Comments (7)
Hi @birthdaycorp 👋
Sorry the late reply 🙏 I see some comments in #61 (comment) and I'd like to say thanks @jmstfv for supporting this!
To be honest I'm not using CSP in my apps with invisible-captcha
, so I have a vague idea about how this should work (or whether this is a bug). I'd really appreciate @jmstfv helping with this issue.
from invisible_captcha.
I might be missing something here, but how does one add a nonce explicitly, when it's randomly generated by the
content_security_policy_nonce_generator
?
You are correct in that the nonce is generated randomly, but you have to explicitly add a nonce
attribute (not the value) to the script element:
<%= javascript_tag nonce: true do -%>
alert('42');
<% end -%>
or like this:
<script nonce="<%= content_security_policy_nonce %>">
alert('42');
</script>
I'm using Rails v 5.2.1, and the problematic code snippet is just the helper
<%= invisible_captcha nonce: true %>
which injects this into the view:<style media="screen" nonce="5Cq/QyoJ5Co+LdarO1uvrg==">
.
That's the expected behavior.
Comparing this with the header shows that the nonce is being added, it just goes to the wrong directive...
Content-Security-Policy-Report-Only script-src 'self' https: 'nonce-5Cq/QyoJ5Co+LdarO1uvrg=='; style-src 'self' https:;
Weird. In your case, a nonce should appear in both script-src
and style-src
directives (in the generated CSP header).
I found the following issue and a pull request that might explain this behaviour.
Can you please upgrade Rails to 6.x
(or at least to 5.2.4.3
) to check if the problem persists?
FWIW, here's the page from my app (Rails 6.0.3.2
) that uses invisible captcha with a nonce. You can poke around the source and HTTP headers to see how it works. Here's the CSP config I use:
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
Rails.application.config.content_security_policy do |policy|
policy.default_src :none
policy.block_all_mixed_content true
policy.base_uri :self
policy.connect_src :self, 'https://api.stripe.com'
policy.form_action :self
policy.frame_ancestors :none
policy.frame_src 'https://js.stripe.com', 'https://hooks.stripe.com'
policy.img_src :self, 'https://hexadecimal-status-pages.s3.amazonaws.com', 'https://platform.slack-edge.com', ENV.fetch('CDN_HOST', '')
policy.script_src :self, 'https://js.stripe.com', ENV.fetch('CDN_HOST', '')
policy.style_src :self, ENV.fetch('CDN_HOST', '')
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
end
# If you are using UJS then enable automatic nonce generation
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Set the nonce only to specific directives
Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true
And the CSP header that is generated by Rails (nonces change on each request):
default-src 'none'; block-all-mixed-content; base-uri 'self'; connect-src 'self' https://api.stripe.com; form-action 'self'; frame-ancestors 'none'; frame-src https://js.stripe.com https://hooks.stripe.com; img-src 'self' https://hexadecimal-status-pages.s3.amazonaws.com https://platform.slack-edge.com d3npmfcpkcxq06.cloudfront.net; script-src 'self' https://js.stripe.com d3npmfcpkcxq06.cloudfront.net; style-src 'self' d3npmfcpkcxq06.cloudfront.net 'nonce-mwip/U/aTL8mSlPpUPj7Yw=='
from invisible_captcha.
@birthdaycorp the nonce attribute has to be added explicitly. Can you share the problematic snippet, your Rails version, and your full CSP config?
You can grep through the codebase to check if you use nonces (replace your_app_folder
with the actual folder name):
grep -iR "nonce" your_app_folder --exclude-dir=tmp --exclude-dir=log --exclude-dir=node_modules
As I mentioned before, if you don't want nonces to be valid for scripts:
Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
Don't forget to restart your server after making each change.
from invisible_captcha.
Thanks so much for your time, everyone. To be clear: I do want nonces to be valid for scripts. I have a few code blocks that use nonces and they play along with the CSP. But the <style>
element added by the invisible captcha helper needs to be whitelisted.
@jmstfv I might be missing something here, but how does one add a nonce explicitly, when it's randomly generated by the content_security_policy_nonce_generator
?
I'm using Rails v 5.2.1, and the problematic code snippet is just the helper <%= invisible_captcha nonce: true %>
which injects this into the view: <style media="screen" nonce="5Cq/QyoJ5Co+LdarO1uvrg==">
.
Comparing this with the header shows that the nonce is being added, it just goes to the wrong directive... Content-Security-Policy-Report-Only script-src 'self' https: 'nonce-5Cq/QyoJ5Co+LdarO1uvrg=='; style-src 'self' https:;
Full content_security_policy.rb:
Rails.application.config.content_security_policy do |config|
config.font_src :self, :data, :https, 'fonts.googleapis.com'
config.img_src :self, :data, :https, 'site.amazonaws.com'
config.script_src :self, :https, 'stripe.com', '*.stripe.com', "'sha256-whatever'", "'sha256-whatever2'"
config.style_src :self, :https
config.object_src :none
config.frame_src :self, :https, '*.stripe.com'
config.media_src :none
if Rails.env.production?
config.connect_src 'wss://site.com/cable'
end
config.frame_ancestors :none
# config.report_uri "https://reportingurl.com"
end
Rails.application.config.content_security_policy_report_only = false
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
Rails.application.config.content_security_policy_nonce_directives = %w(style-src script-src)
from invisible_captcha.
Thanks for all your help, @jmstfv. After upgrading to 5.2.4.3, I can confirm that the style nonce is still being added to script-src😓😢
from invisible_captcha.
Hi @birthdaycorp did you finally manage to make it work with CSP as @jmstfv explained above?
from invisible_captcha.
I'm going to close this one for now (doing some issues housekeeping). In order to move forwards with this issue we'll need an example app that reproduces the behavior (https://www.codetriage.com/example_app).
Best,
Marc
from invisible_captcha.
Related Issues (20)
- Adding recaptcha to handle the chrome auto fill bug HOT 5
- Undefined method remote_ip HOT 1
- Tips when used together with Sorcery gem. HOT 1
- By using I18n.with_locale(..) in app_controller action is not called HOT 3
- IP spinner validation when forms are added with JS HOT 1
- Timestamp validation when forms are submitted with JS HOT 1
- Option with dynamic honeypot (collection of default honeypots) does not use scope HOT 1
- Submit form on multi tabs HOT 3
- Potential spam detected for IP 127.0.0.1. Invisible Captcha spinner value mismatch HOT 2
- Markup not valid when run through HTML validator HOT 6
- Each spinner should have a unique HTML ID
- `#honeypot_spam?` does not use `:scope` option if `:honeypot` option is not also set. HOT 1
- InvisibleCaptcha::ControllerExt honeypot attribute ActiveSupport::Notifications dispatches an `invisible_captcha.spam_detected` event test is failing now HOT 10
- Edge case with scope changes in 2.1.0
- It's difficult to write tests HOT 3
- [Invisible Captcha] Potential spam detected for IP 127.0.0.1. Timestamp not found in session. HOT 13
- Captcha field visible in Rails 7.1 HOT 5
- Logic bug regarding spinner-based protection HOT 4
- What is the "IP based 🔍 spinner validation"? HOT 1
- New feature: Spam-Filtering on Post requests only HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from invisible_captcha.