Skip to content

Commit 71c2736

Browse files
authored
Remove skipping CSP nonce on unsafe-inline (#1010)
The current implementation for Rails's CSP nonce functionality intentionally skips adding a nonce to the script tag if the script-src directive includes `unsafe-inline`. However, using both a nonce and unsafe-inline at the same time is perfectly valid (and indeed sensible) behaviour. It allows the app to maintain some level of backwards compatibility with browsers that support CSP1 but not CSP2, c.f.: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src - Remove special handling of nonces when `unsafe-inline` is specified in the `script-src` directive
1 parent 310a9d1 commit 71c2736

File tree

3 files changed

+2
-44
lines changed

3 files changed

+2
-44
lines changed

lib/rollbar/middleware/js.rb

+1-6
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ def rails5_nonce(env)
183183
req.respond_to?(:content_security_policy) &&
184184
req.content_security_policy &&
185185
req.content_security_policy.directives['script-src'] &&
186-
!req.content_security_policy.directives['script-src'].include?("'unsafe-inline'") &&
187186
req.content_security_policy_nonce
188187
end
189188

@@ -224,16 +223,12 @@ def find_csp
224223
end
225224

226225
def csp_needs_nonce?(csp)
227-
!opt_out?(csp) && !unsafe_inline?(csp)
226+
!opt_out?(csp)
228227
end
229228

230229
def opt_out?(_csp)
231230
raise NotImplementedError
232231
end
233-
234-
def unsafe_inline?(csp)
235-
csp[:script_src].to_a.include?("'unsafe-inline'")
236-
end
237232
end
238233

239234
class SecureHeadersFalse < SecureHeadersResolver

spec/rollbar/middleware/js_spec.rb

-14
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,6 @@
1717
expect(new_body).to include(snippet)
1818
end
1919

20-
it 'renders the snippet in the response without nonce if SecureHeaders script_src includes \'unsafe-inline\'' do
21-
SecureHeadersMocks::CSP.config = {
22-
:opt_out? => false,
23-
:script_src => %w['unsafe-inline'] # rubocop:disable Lint/PercentStringArray
24-
}
25-
26-
_, _, response = subject.call(env)
27-
new_body = response.body.join
28-
29-
expect(new_body).to include('<script type="text/javascript">')
30-
expect(new_body).to include("var _rollbarConfig = #{json_options};")
31-
expect(new_body).to include(snippet)
32-
end
33-
3420
it 'renders the snippet in the response without nonce if SecureHeaders CSP is OptOut' do
3521
SecureHeadersMocks::CSP.config = {
3622
:opt_out? => true

spec/rollbar/plugins/rails_js_spec.rb

+1-24
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ def configure_csp(mode)
3131
nonce_present
3232
elsif mode == :script_src_not_present
3333
script_src_not_present
34-
elsif mode == :unsafe_inline
35-
unsafe_inline
3634
else
3735
raise 'Unknown CSP mode'
3836
end
@@ -53,14 +51,6 @@ def script_src_not_present
5351
end
5452
end
5553

56-
def unsafe_inline
57-
# Browser behavior is undefined when unsafe_inline and the nonce are both present.
58-
# The app should never set both, but if they do, our best behavior is to not use the nonce.
59-
Rails.application.config.content_security_policy do |policy|
60-
policy.script_src :self, :unsafe_inline
61-
end
62-
end
63-
6454
def nonce(response)
6555
response.request.content_security_policy_nonce
6656
end
@@ -107,20 +97,7 @@ def reset_rails_config
10797
include_examples 'adds the snippet'
10898
end
10999

110-
context 'when unsafe_inline is present' do
111-
let(:nonce_mode) { :unsafe_inline }
112-
113-
it 'renders the snippet and config in the response with nonce in script tag' do
114-
get '/test_rollbar_js'
115-
116-
expect(response.body).to_not include %[<script type="text/javascript" nonce="#{nonce(response)}">]
117-
expect(response.body).to include '<script type="text/javascript">'
118-
end
119-
120-
include_examples 'adds the snippet'
121-
end
122-
123-
context 'when scp nonce is present' do
100+
context 'when CSP nonce is present' do
124101
let(:nonce_mode) { :nonce_present }
125102

126103
it 'renders the snippet and config in the response with nonce in script tag' do

0 commit comments

Comments
 (0)