i am trying to setup a CSP policy (collected from: Evil Martian Blog):
Rails.application.config.content_security_policy do |policy|
policy.font_src :self, :https, :data
policy.img_src :self, :https, :data
policy.object_src :none
policy.style_src :self, :https, :unsafe_inline
# If you are using webpack-dev-server then specify webpack-dev-server host
if Rails.env.development?
policy.script_src :self, :http, :unsafe_inline
## policy.script_src :self, :http, :unsafe_eval
policy.default_src :self, :http, :unsafe_eval
policy.connect_src :self, :http, 'http://localhost:3035', 'ws://localhost:3035', 'http://localhost:3000', 'ws://localhost:3000'
else
policy.script_src :self, :https, :unsafe_inline
policy.default_src :self, :https
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
end
end
EDIT = > I ended up using the secure_headers gem and followed advise contained in https://bauland42.com/ruby-on-rails-content-security-policy-csp/
There are two issues that seems to prevent the implementation in development mode :
1/ it seems to prevent toaster notification (installed from webpacker)
How can I allow toaster notifications ?
Solved by adding :unsafe_inline. to the dev environment also
2/ an inline script in application.html.erb
this is solved as well but I will be happy to move the script below if I can reference injectSvgSprite('<%= asset_url("icons/icons.svg") %>'). to work from the javascript folder.
How can I allow the inline script ? I am happy to move this to javascript folder but could not link the sprite folder.
the head contains : <%= csrf_meta_tags %>. and <%= csp_meta_tag %>
then comes:
<body>
<%= custom_bootstrap_flash %>
<%= yield %>
<script>
// ------------------------------------------------------- //
// Inject SVG Sprite -
// see more here
// https://css-tricks.com/ajaxing-svg-sprite/
// ------------------------------------------------------ //
function injectSvgSprite(path) {
var ajax = new XMLHttpRequest();
ajax.open("GET", path, true);
ajax.send();
ajax.onload = function(e) {
var div = document.createElement("div");
div.className = 'd-none';
div.innerHTML = ajax.responseText;
document.body.insertBefore(div, document.body.childNodes[0]);
}
}
injectSvgSprite('<%= asset_url("icons/icons.svg") %>')
</script>
<!-- Swiper Carousel -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.1/js/swiper.min.js"></script>
EDIT => I have setup svg inline using the svgeez gem enter link description here
3/ as subsidiary here : Sipper needs the above CDN to work
I have yarn installed swiper, and required it in application.js, include it in the pack_tag but I still need to reference the can for the javascript (css worked without it). What have I missed ?
Related
The browser console is hitting some errors due to content security policy on a Rails 7.0.3 application when running connections to localhost:3000.
Rails.application.config.content_security_policy do |policy|
# policy.default_src :self, :https
policy.font_src :self, :https, :data
policy.img_src :self, :https, :data
policy.object_src :none
policy.style_src :self, :https, :unsafe_inline
policy.connect_src :self, :https, 'https://api.stripe.com'
policy.frame_src :self, 'https://js.stripe.com', 'https://hooks.stripe.com'
# policy.script_src :self, :https #, :unsafe_inline
end
Under the above settings the application does not encounter any errors.
The moment one of the two disabled policies is enabled, page settings block elements Content Security Policy: The page's settings blocked the loading of a resource at inline ("script-src"). The peculiar part is that it occurs even with default settings
policy.script_src :self, :https
Also, it is weird that default_src would also lead to blocking of said resource...
[side note] no idea how to get this suggestion to function, the path being a rails-compliant route definition
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
The first line points to the place where the first object is blocked, essentially the application importmap thus disabling hotwire.
wonderful!
The question is a bit fuzzy (knowledge of csp combined with the mechanics of Rails and importmaps in this instance being limited). The full set of policies are running on a Rails 6 application; Rails 7 has the obvious change of importmaps to do things the Hotwire way.
The lack of a CSP, especially regarding scripts, is logically frowned upon.
So how does Hotwire get to run with proper settings?
I am using an external API to display images from source https://i.ibb.co
The img src URL looks like this: https://i.ibb.co/R0VHJbd/ds.png
In production, I'm having an issue displaying the images. In the console, the error:
Refused to load the image 'https://i.ibb.co/R0VHJbd/ds.png' because it violates the following Content Security Policy directive: "img-src 'self' data:".
However, even after setting my Content Security Policy in the index.html to:
<meta http-equiv="Content-Security-Policy" content="img-src 'self' https://i.ibb.co; connect-src 'self' https://api.imgbb.com; child-src *; object-src *">
I am still getting the error
I am also getting the same error when attempting to upload through the API, even though the connect-src is defined in my meta tag
Refused to connect to 'https://api.imgbb.com/1/upload?expiration=600&key=<key>' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
I have rack-cors enabled to allow all requests
application.rb
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: :any
end
end
config/initializers/rack_cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: %w(Authorization),
expose: %w(Authorization),
methods: :any
end
end
config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
policy.font_src :self, :https, :data
policy.img_src :self, :https, "i.ibb.co", :data
policy.object_src :none
policy.script_src :self, :https
policy.style_src :self, :https
# If you are using webpack-dev-server then specify webpack-dev-server host
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
end
How can I resolve this?
Note: This is an Angular project running on the Rails server, so the Angular index.html that is served on the homepage is compiled first, followed by Rails
For reference: my project on Heroku
Hey I have an Ror App and I've set the CSP in my app globaly
this is CSP file in my config/initilaizers/content_security_policy
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
policy.font_src :self, :https, :data
policy.img_src :self, :https, :data
policy.object_src :none
policy.script_src :self, :https
policy.style_src :self, :https
end
but I have a problem with ckeditor and google font
1st google font wont loaded the font
2nd ckeditor have an error on the style like this
ckeditor.js:94 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' https:". Either the 'unsafe-inline' keyword, a hash ('sha256-ZVjd2zfSTfAVh1y7eCcNk0SPGUQOP/H8vzrFJIVgg90='), or a nonce ('nonce-...') is required to enable inline execution.
the question is, can I add specific unsafe_inline only for ckeditor CSP ?
this is because I only use this CKEditor only in rails_admin
and why the google font wont loaded after I generated integrity hash?
thanks
I just configured rails to use a CSP as per the docs
My exact configuration looks like this
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
policy.font_src :self, :https, :data
policy.img_src :self, :https, :data
policy.object_src :none
policy.script_src :self, :https
policy.style_src :self, :https
end
# TODO: Remove this when ready to use CSP
Rails.application.config.content_security_policy_report_only = true
I then added csp_meta_tag in to <head> in the layout
Now when I start my application I can see that there are lots of reports about CSP violations. In my slim templates there are a few javascript: tags which I would like to all be allowed automatically by the CSP. This seems to be possible but I'm not quite sure how to configure it to work this way.
I would like to keep the inline script protection enabled but use the methods available to allow the inline scripts in my app even if that means adding a tag or something to each instance of an inline script.
To allow inline scripts, you can do the following.
Rails.application.config.content_security_policy do |policy|
# other policies
policy.script_src :self, :https, :unsafe_inline
end
Sources:
https://bauland42.com/ruby-on-rails-content-security-policy-csp/
https://rorsecurity.info/portfolio/content-security-policy-csp-strategy
In Rails 4.0.2, I am using s3_direct_upload and aws-sdk gems for file uploads for s3 bucket directly. In development environment it is working fine but in production environment it is throwing an error like below,
ActionView::Template::Error (no implicit conversion of nil into String)
In views,
<%= s3_uploader_form :callback_url=>create_cv_url, :id=> "s3_uploader", :key=> "cv_uploads/{unique_id}/${filename}",
:key_starts_with=> "cv_uploads/", :callback_param=> "cv[direct_upload_url]", :max_file_size=> 1.megabytes,
:expiration=> 24.hours.from_now.utc.iso8601 do %>
<%= file_field_tag :file, multiple: true, :max_file_size => 1.megabytes, accept: 'application/pdf application/msword application/rtf application/doc application/docx' %>
<% end %>
<script id="template-upload" type="text/x-tmpl">
<div id="upload_{%=o.unique_id%}" class="upload">
<h5 class="mt1">Please Wait. <span style="color: #5f6fa0;"> {%=o.name%} </span>is processing...</h5>
<div class="progress"><div class="progress-bar progress-bar-striped active" style="width: 0%;"></div></div>
</div>
Here, the issue is mainly pointing to s3_uploader_form line(in views).
This feature is fully referred from http://blog.littleblimp.com/post/53942611764/direct-uploads-to-s3-with-rails-paperclip-and
In paperclip.rb
Paperclip::Attachment.default_options.merge!(
url: :s3_domain_url,
path: ':class/:attachment/:id/:style/:filename',
storage: :s3,
s3_credentials: Rails.configuration.aws,
s3_permissions: :private,
s3_protocol: 'http'
)
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
In aws.rb
require 'aws-sdk'
# Rails.configuration.aws is used by AWS, Paperclip, and S3DirectUpload
Rails.configuration.aws = YAML.load(ERB.new(File.read("# {Rails.root}/config/aws.yml")).result)[Rails.env].symbolize_keys!
AWS.config(:logger=> Rails.logger)
AWS.config(Rails.configuration.aws)
In s3_direct_upload.rb
S3DirectUpload.config do |c|
c.access_key_id = Rails.configuration.aws[:access_key_id]
c.secret_access_key = Rails.configuration.aws[:secret_access_key]
c.bucket = Rails.configuration.aws[:bucket]
c.region = "s3"
end
Is it because of configuration issue in production environment? Please help me to solve this issue.
I had the same problem and I solve it adding the file config.yml with my S3 credentials:
RailsApp/config.yml
# Fill in your AWS Access Key ID and Secret Access Key
# http://aws.amazon.com/security-credentials
access_key_id: xxxxxx
secret_access_key: xxxxxxx
More info: https://docs.aws.amazon.com/AWSSdkDocsRuby/latest/DeveloperGuide/ruby-dg-setup.html
The code seems ok. As skozz mentioned, one of the issue may be with your configuration keys that may be not assigned properly. Please check aws production keys in "/config/aws.yml".
I was suffering the same, by following this link. The thing is that I've added the initializers, but I needed to restart rails (it was running but not refreshed).
Executing this command worked for me. figaro heroku:set -e production