secure_headers 1.1.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +15 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +2 -0
  5. data/Gemfile +0 -4
  6. data/Guardfile +1 -5
  7. data/HISTORY.md +17 -0
  8. data/README.md +55 -26
  9. data/fixtures/rails_3_2_12/Gemfile +0 -2
  10. data/fixtures/rails_3_2_12/config/initializers/secure_headers.rb +1 -0
  11. data/fixtures/rails_3_2_12/spec/controllers/other_things_controller_spec.rb +10 -14
  12. data/fixtures/rails_3_2_12/spec/controllers/things_controller_spec.rb +7 -12
  13. data/fixtures/rails_3_2_12/spec/spec_helper.rb +1 -5
  14. data/fixtures/rails_3_2_12_no_init/Gemfile +0 -2
  15. data/fixtures/rails_3_2_12_no_init/spec/controllers/other_things_controller_spec.rb +7 -12
  16. data/fixtures/rails_3_2_12_no_init/spec/controllers/things_controller_spec.rb +7 -12
  17. data/fixtures/rails_3_2_12_no_init/spec/spec_helper.rb +3 -18
  18. data/lib/secure_headers/headers/content_security_policy.rb +46 -36
  19. data/lib/secure_headers/padrino.rb +14 -0
  20. data/lib/secure_headers/version.rb +1 -1
  21. data/spec/controllers/content_security_policy_controller_spec.rb +19 -19
  22. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +105 -85
  23. data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +20 -20
  24. data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +12 -12
  25. data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +12 -12
  26. data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +18 -18
  27. data/spec/lib/secure_headers_spec.rb +11 -11
  28. data/spec/spec_helper.rb +9 -24
  29. metadata +8 -12
  30. data/.rvmrc +0 -1
  31. data/fixtures/rails_3_2_12/Guardfile +0 -14
  32. data/fixtures/rails_3_2_12_no_init/Guardfile +0 -14
@@ -30,38 +30,38 @@ module SecureHeaders
30
30
 
31
31
  describe "#name" do
32
32
  context "when supplying options to override request" do
33
- specify { ContentSecurityPolicy.new(default_opts, :ua => IE).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
34
- specify { ContentSecurityPolicy.new(default_opts, :ua => FIREFOX).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
35
- specify { ContentSecurityPolicy.new(default_opts, :ua => FIREFOX_23).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
36
- specify { ContentSecurityPolicy.new(default_opts, :ua => CHROME).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
37
- specify { ContentSecurityPolicy.new(default_opts, :ua => CHROME_25).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
33
+ specify { expect(ContentSecurityPolicy.new(default_opts, :ua => IE).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
34
+ specify { expect(ContentSecurityPolicy.new(default_opts, :ua => FIREFOX).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
35
+ specify { expect(ContentSecurityPolicy.new(default_opts, :ua => FIREFOX_23).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
36
+ specify { expect(ContentSecurityPolicy.new(default_opts, :ua => CHROME).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
37
+ specify { expect(ContentSecurityPolicy.new(default_opts, :ua => CHROME_25).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
38
38
  end
39
39
 
40
40
  context "when in report-only mode" do
41
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(IE)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
42
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
43
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX_23)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
44
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
45
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME_25)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
41
+ specify { expect(ContentSecurityPolicy.new(default_opts, :request => request_for(IE)).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
42
+ specify { expect(ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX)).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
43
+ specify { expect(ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX_23)).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
44
+ specify { expect(ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME)).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
45
+ specify { expect(ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME_25)).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
46
46
  end
47
47
 
48
48
  context "when in enforce mode" do
49
49
  let(:opts) { default_opts.merge(:enforce => true)}
50
50
 
51
- specify { ContentSecurityPolicy.new(opts, :request => request_for(IE)).name.should == STANDARD_HEADER_NAME}
52
- specify { ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX)).name.should == STANDARD_HEADER_NAME}
53
- specify { ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX_23)).name.should == STANDARD_HEADER_NAME}
54
- specify { ContentSecurityPolicy.new(opts, :request => request_for(CHROME)).name.should == STANDARD_HEADER_NAME}
55
- specify { ContentSecurityPolicy.new(opts, :request => request_for(CHROME_25)).name.should == STANDARD_HEADER_NAME}
51
+ specify { expect(ContentSecurityPolicy.new(opts, :request => request_for(IE)).name).to eq(STANDARD_HEADER_NAME)}
52
+ specify { expect(ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX)).name).to eq(STANDARD_HEADER_NAME)}
53
+ specify { expect(ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX_23)).name).to eq(STANDARD_HEADER_NAME)}
54
+ specify { expect(ContentSecurityPolicy.new(opts, :request => request_for(CHROME)).name).to eq(STANDARD_HEADER_NAME)}
55
+ specify { expect(ContentSecurityPolicy.new(opts, :request => request_for(CHROME_25)).name).to eq(STANDARD_HEADER_NAME)}
56
56
  end
57
57
 
58
58
  context "when in experimental mode" do
59
59
  let(:opts) { default_opts.merge(:enforce => true).merge(:experimental => {})}
60
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(IE)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
61
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
62
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX_23)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
63
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
64
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME_25)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
60
+ specify { expect(ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(IE)}).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
61
+ specify { expect(ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX)}).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
62
+ specify { expect(ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX_23)}).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
63
+ specify { expect(ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME)}).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
64
+ specify { expect(ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME_25)}).name).to eq(STANDARD_HEADER_NAME + "-Report-Only")}
65
65
  end
66
66
  end
67
67
 
@@ -76,7 +76,29 @@ module SecureHeaders
76
76
  context "Content-Security-Policy" do
77
77
  it "converts the script values to their equivilents" do
78
78
  csp = ContentSecurityPolicy.new(@opts, :request => request_for(CHROME))
79
- csp.value.should include("script-src 'unsafe-inline' 'unsafe-eval' https://* data: 'self' 'none'")
79
+ expect(csp.value).to include("script-src 'unsafe-inline' 'unsafe-eval' https://* data: 'self' 'none'")
80
+ end
81
+
82
+ it "accepts procs for report-uris" do
83
+ opts = {
84
+ :default_src => 'self',
85
+ :report_uri => lambda { "http://lambda/result" }
86
+ }
87
+
88
+ csp = ContentSecurityPolicy.new(opts)
89
+ expect(csp.report_uri).to eq("http://lambda/result")
90
+ end
91
+
92
+ it "accepts procs for other fields" do
93
+ opts = {
94
+ :default_src => lambda { "http://lambda/result" },
95
+ :enforce => lambda { true },
96
+ :disable_fill_missing => lambda { true }
97
+ }
98
+
99
+ csp = ContentSecurityPolicy.new(opts)
100
+ expect(csp.value).to eq("default-src http://lambda/result; img-src http://lambda/result data:;")
101
+ expect(csp.name).to match("Content-Security-Policy")
80
102
  end
81
103
  end
82
104
  end
@@ -86,47 +108,47 @@ module SecureHeaders
86
108
 
87
109
  it "matches when host, scheme, and port match" do
88
110
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com'}, :request => request_for(FIREFOX, "https://example.com"))
89
- csp.send(:same_origin?).should be_true
111
+ expect(csp.send(:same_origin?)).to be true
90
112
 
91
113
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com'}, :request => request_for(FIREFOX, "https://example.com:443"))
92
- csp.send(:same_origin?).should be_true
114
+ expect(csp.send(:same_origin?)).to be true
93
115
 
94
116
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com:123'}, :request => request_for(FIREFOX, "https://example.com:123"))
95
- csp.send(:same_origin?).should be_true
117
+ expect(csp.send(:same_origin?)).to be true
96
118
 
97
119
  csp = ContentSecurityPolicy.new({:report_uri => 'http://example.com'}, :request => request_for(FIREFOX, "http://example.com"))
98
- csp.send(:same_origin?).should be_true
120
+ expect(csp.send(:same_origin?)).to be true
99
121
 
100
122
  csp = ContentSecurityPolicy.new({:report_uri => 'http://example.com:80'}, :request => request_for(FIREFOX, "http://example.com"))
101
- csp.send(:same_origin?).should be_true
123
+ expect(csp.send(:same_origin?)).to be true
102
124
 
103
125
  csp = ContentSecurityPolicy.new({:report_uri => 'http://example.com'}, :request => request_for(FIREFOX, "http://example.com:80"))
104
- csp.send(:same_origin?).should be_true
126
+ expect(csp.send(:same_origin?)).to be true
105
127
  end
106
128
 
107
129
  it "does not match port mismatches" do
108
130
  csp = ContentSecurityPolicy.new({:report_uri => 'http://example.com'}, :request => request_for(FIREFOX, "http://example.com:81"))
109
- csp.send(:same_origin?).should be_false
131
+ expect(csp.send(:same_origin?)).to be false
110
132
  end
111
133
 
112
134
  it "does not match host mismatches" do
113
135
  csp = ContentSecurityPolicy.new({:report_uri => 'http://twitter.com'}, :request => request_for(FIREFOX, "http://example.com"))
114
- csp.send(:same_origin?).should be_false
136
+ expect(csp.send(:same_origin?)).to be false
115
137
  end
116
138
 
117
139
  it "does not match host mismatches because of subdomains" do
118
140
  csp = ContentSecurityPolicy.new({:report_uri => 'http://example.com'}, :request => request_for(FIREFOX, "http://sub.example.com"))
119
- csp.send(:same_origin?).should be_false
141
+ expect(csp.send(:same_origin?)).to be false
120
142
  end
121
143
 
122
144
  it "does not match scheme mismatches" do
123
145
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com'}, :request => request_for(FIREFOX, "ftp://example.com"))
124
- csp.send(:same_origin?).should be_false
146
+ expect(csp.send(:same_origin?)).to be false
125
147
  end
126
148
 
127
149
  it "does not match on substring collisions" do
128
150
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com'}, :request => request_for(FIREFOX, "https://anotherexample.com"))
129
- csp.send(:same_origin?).should be_false
151
+ expect(csp.send(:same_origin?)).to be false
130
152
  end
131
153
  end
132
154
 
@@ -136,29 +158,29 @@ module SecureHeaders
136
158
  context "when using firefox" do
137
159
  it "updates the report-uri when posting to a different host" do
138
160
  csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX, "https://anexample.com"))
139
- csp.report_uri.should == FF_CSP_ENDPOINT
161
+ expect(csp.report_uri).to eq(FF_CSP_ENDPOINT)
140
162
  end
141
163
 
142
164
  it "doesn't change report-uri if a path supplied" do
143
165
  csp = ContentSecurityPolicy.new({:report_uri => "/csp_reports"}, :request => request_for(FIREFOX, "https://anexample.com"))
144
- csp.report_uri.should == "/csp_reports"
166
+ expect(csp.report_uri).to eq("/csp_reports")
145
167
  end
146
168
 
147
169
  it "forwards if the request_uri is set to a non-matching value" do
148
170
  csp = ContentSecurityPolicy.new({:report_uri => "https://another.example.com", :forward_endpoint => '/somewhere'}, :ua => "Firefox", :request_uri => "https://anexample.com")
149
- csp.report_uri.should == FF_CSP_ENDPOINT
171
+ expect(csp.report_uri).to eq(FF_CSP_ENDPOINT)
150
172
  end
151
173
  end
152
174
 
153
175
  it "does not update the URI is the report_uri is on the same origin" do
154
176
  opts = {:report_uri => 'https://example.com/csp', :forward_endpoint => 'https://anotherexample.com'}
155
177
  csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX, "https://example.com/somewhere"))
156
- csp.report_uri.should == 'https://example.com/csp'
178
+ expect(csp.report_uri).to eq('https://example.com/csp')
157
179
  end
158
180
 
159
181
  it "does not update the report-uri when using a non-firefox browser" do
160
182
  csp = ContentSecurityPolicy.new(opts, :request => request_for(CHROME))
161
- csp.report_uri.should == 'https://example.com/csp'
183
+ expect(csp.report_uri).to eq('https://example.com/csp')
162
184
  end
163
185
 
164
186
  context "when using a protocol-relative value for report-uri" do
@@ -171,20 +193,20 @@ module SecureHeaders
171
193
 
172
194
  it "uses the current protocol" do
173
195
  csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX, '/', :ssl => true))
174
- csp.value.should =~ %r{report-uri https://example.com/csp;}
196
+ expect(csp.value).to match(%r{report-uri https://example.com/csp;})
175
197
 
176
198
  csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX))
177
- csp.value.should =~ %r{report-uri http://example.com/csp;}
199
+ expect(csp.value).to match(%r{report-uri http://example.com/csp;})
178
200
  end
179
201
 
180
202
  it "uses the pre-configured https protocol" do
181
203
  csp = ContentSecurityPolicy.new(opts, :ua => "Firefox", :ssl => true)
182
- csp.value.should =~ %r{report-uri https://example.com/csp;}
204
+ expect(csp.value).to match(%r{report-uri https://example.com/csp;})
183
205
  end
184
206
 
185
207
  it "uses the pre-configured http protocol" do
186
208
  csp = ContentSecurityPolicy.new(opts, :ua => "Firefox", :ssl => false)
187
- csp.value.should =~ %r{report-uri http://example.com/csp;}
209
+ expect(csp.value).to match(%r{report-uri http://example.com/csp;})
188
210
  end
189
211
  end
190
212
  end
@@ -192,20 +214,20 @@ module SecureHeaders
192
214
  describe "#value" do
193
215
  it "raises an exception when default-src is missing" do
194
216
  csp = ContentSecurityPolicy.new({:script_src => 'anything'}, :request => request_for(CHROME))
195
- lambda {
217
+ expect {
196
218
  csp.value
197
- }.should raise_error(ContentSecurityPolicyBuildError, "Couldn't build CSP header :( Expected to find default_src directive value")
219
+ }.to raise_error(ContentSecurityPolicyBuildError, "Couldn't build CSP header :( Expected to find default_src directive value")
198
220
  end
199
221
 
200
222
  context "auto-whitelists data: uris for img-src" do
201
223
  it "sets the value if no img-src specified" do
202
224
  csp = ContentSecurityPolicy.new({:default_src => 'self', :disable_fill_missing => true, :disable_chrome_extension => true}, :request => request_for(CHROME))
203
- csp.value.should == "default-src 'self'; img-src data:;"
225
+ expect(csp.value).to eq("default-src 'self'; img-src 'self' data:;")
204
226
  end
205
227
 
206
228
  it "appends the value if img-src is specified" do
207
229
  csp = ContentSecurityPolicy.new({:default_src => 'self', :img_src => 'self', :disable_fill_missing => true, :disable_chrome_extension => true}, :request => request_for(CHROME))
208
- csp.value.should == "default-src 'self'; img-src 'self' data:;"
230
+ expect(csp.value).to eq("default-src 'self'; img-src 'self' data:;")
209
231
  end
210
232
  end
211
233
 
@@ -213,30 +235,55 @@ module SecureHeaders
213
235
  options = default_opts.merge(:disable_fill_missing => false)
214
236
  csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
215
237
  value = "default-src https://*; connect-src https://*; font-src https://*; frame-src https://*; img-src https://* data:; media-src https://*; object-src https://*; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
216
- csp.value.should == value
238
+ expect(csp.value).to eq(value)
217
239
  end
218
240
 
219
241
  it "sends the standard csp header if an unknown browser is supplied" do
220
242
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(IE))
221
- csp.value.should match "default-src"
243
+ expect(csp.value).to match "default-src"
222
244
  end
223
245
 
224
246
  context "Firefox" do
225
247
  it "builds a csp header for firefox" do
226
248
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX))
227
- csp.value.should == "default-src https://*; img-src data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
249
+ expect(csp.value).to eq("default-src https://*; img-src https://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;")
228
250
  end
229
251
  end
230
252
 
231
253
  context "Chrome" do
232
254
  it "builds a csp header for chrome" do
233
255
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME))
234
- csp.value.should == "default-src https://*; img-src data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
256
+ expect(csp.value).to eq("default-src https://*; img-src https://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;")
235
257
  end
236
258
 
237
259
  it "ignores :forward_endpoint settings" do
238
260
  csp = ContentSecurityPolicy.new(@options_with_forwarding, :request => request_for(CHROME))
239
- csp.value.should =~ /report-uri #{@options_with_forwarding[:report_uri]};/
261
+ expect(csp.value).to match(/report-uri #{@options_with_forwarding[:report_uri]};/)
262
+ end
263
+ end
264
+
265
+ context "when using a nonce" do
266
+ it "adds a nonce and unsafe-inline to the script-src value" do
267
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(CHROME))
268
+ expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
269
+ end
270
+
271
+ it "adds a nonce and unsafe-inline to the style-src value" do
272
+ header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "self nonce"), :request => request_for(CHROME))
273
+ expect(header.value).to include("style-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
274
+ end
275
+
276
+ it "adds an identical nonce to the style and script-src directives" do
277
+ header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "self nonce", :script_src => "self nonce"), :request => request_for(CHROME))
278
+ nonce = header.nonce
279
+ value = header.value
280
+ expect(value).to include("style-src 'self' 'nonce-#{nonce}' 'unsafe-inline'")
281
+ expect(value).to include("script-src 'self' 'nonce-#{nonce}' 'unsafe-inline'")
282
+ end
283
+
284
+ it "does not add 'unsafe-inline' twice" do
285
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce inline"), :request => request_for(CHROME))
286
+ expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline';")
240
287
  end
241
288
  end
242
289
 
@@ -253,12 +300,12 @@ module SecureHeaders
253
300
 
254
301
  it "returns the original value" do
255
302
  header = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
256
- header.value.should == "default-src 'self'; img-src data:; script-src https://*;"
303
+ expect(header.value).to eq("default-src 'self'; img-src 'self' data:; script-src https://*;")
257
304
  end
258
305
 
259
306
  it "it returns the experimental value if requested" do
260
307
  header = ContentSecurityPolicy.new(options, {:request => request_for(CHROME), :experimental => true})
261
- header.value.should_not =~ /https/
308
+ expect(header.value).not_to match(/https/)
262
309
  end
263
310
  end
264
311
 
@@ -274,17 +321,17 @@ module SecureHeaders
274
321
 
275
322
  it "adds directive values for headers on http" do
276
323
  csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
277
- csp.value.should == "default-src https://*; frame-src http://*; img-src http://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
324
+ expect(csp.value).to eq("default-src https://*; frame-src http://*; img-src http://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;")
278
325
  end
279
326
 
280
327
  it "does not add the directive values if requesting https" do
281
328
  csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME, '/', :ssl => true))
282
- csp.value.should_not =~ /http:/
329
+ expect(csp.value).not_to match(/http:/)
283
330
  end
284
331
 
285
332
  it "does not add the directive values if requesting https" do
286
333
  csp = ContentSecurityPolicy.new(options, :ua => "Chrome", :ssl => true)
287
- csp.value.should_not =~ /http:/
334
+ expect(csp.value).not_to match(/http:/)
288
335
  end
289
336
 
290
337
  context "when supplying an experimental block" do
@@ -314,47 +361,20 @@ module SecureHeaders
314
361
 
315
362
  it "uses the value in the experimental block over SSL" do
316
363
  csp = ContentSecurityPolicy.new(options, :experimental => true, :request => request_for(FIREFOX, '/', :ssl => true))
317
- csp.value.should == "default-src 'self'; img-src data:; script-src 'self';"
364
+ expect(csp.value).to eq("default-src 'self'; img-src 'self' data:; script-src 'self';")
318
365
  end
319
366
 
320
367
  it "detects the :ssl => true option" do
321
368
  csp = ContentSecurityPolicy.new(options, :experimental => true, :ua => FIREFOX, :ssl => true)
322
- csp.value.should == "default-src 'self'; img-src data:; script-src 'self';"
369
+ expect(csp.value).to eq("default-src 'self'; img-src 'self' data:; script-src 'self';")
323
370
  end
324
371
 
325
372
  it "merges the values from experimental/http_additions when not over SSL" do
326
373
  csp = ContentSecurityPolicy.new(options, :experimental => true, :request => request_for(FIREFOX))
327
- csp.value.should == "default-src 'self'; img-src data:; script-src 'self' https://mycdn.example.com;"
374
+ expect(csp.value).to eq("default-src 'self'; img-src 'self' data:; script-src 'self' https://mycdn.example.com;")
328
375
  end
329
376
  end
330
377
  end
331
-
332
- context "when supplying a script nonce callback" do
333
- let(:options) {
334
- default_opts.merge({
335
- :script_nonce => "random",
336
- })
337
- }
338
-
339
- it "uses the value in the X-Webkit-CSP" do
340
- csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
341
- csp.value.should match "script-nonce random;"
342
- end
343
-
344
- it "runs a dynamic nonce generator" do
345
- options[:script_nonce] = lambda { 'something' }
346
- csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
347
- csp.value.should match "script-nonce something;"
348
- end
349
-
350
- it "runs against the given controller context" do
351
- fake_params = {}
352
- options[:script_nonce] = lambda { params[:script_nonce] = 'something' }
353
- csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME), :controller => double(:params => fake_params))
354
- csp.value.should match "script-nonce something;"
355
- fake_params.should == {:script_nonce => 'something'}
356
- end
357
- end
358
378
  end
359
379
  end
360
380
  end
@@ -2,59 +2,59 @@ require 'spec_helper'
2
2
 
3
3
  module SecureHeaders
4
4
  describe StrictTransportSecurity do
5
- specify{ StrictTransportSecurity.new.name.should == "Strict-Transport-Security" }
5
+ specify{ expect(StrictTransportSecurity.new.name).to eq("Strict-Transport-Security") }
6
6
 
7
7
  describe "#value" do
8
- specify { StrictTransportSecurity.new.value.should == StrictTransportSecurity::Constants::DEFAULT_VALUE}
9
- specify { StrictTransportSecurity.new("max-age=1234").value.should == "max-age=1234"}
10
- specify { StrictTransportSecurity.new(:max_age => '1234').value.should == "max-age=1234"}
11
- specify { StrictTransportSecurity.new(:max_age => 1234).value.should == "max-age=1234"}
12
- specify { StrictTransportSecurity.new(:max_age => HSTS_MAX_AGE, :include_subdomains => true).value.should == "max-age=#{HSTS_MAX_AGE}; includeSubdomains"}
8
+ specify { expect(StrictTransportSecurity.new.value).to eq(StrictTransportSecurity::Constants::DEFAULT_VALUE)}
9
+ specify { expect(StrictTransportSecurity.new("max-age=1234").value).to eq("max-age=1234")}
10
+ specify { expect(StrictTransportSecurity.new(:max_age => '1234').value).to eq("max-age=1234")}
11
+ specify { expect(StrictTransportSecurity.new(:max_age => 1234).value).to eq("max-age=1234")}
12
+ specify { expect(StrictTransportSecurity.new(:max_age => HSTS_MAX_AGE, :include_subdomains => true).value).to eq("max-age=#{HSTS_MAX_AGE}; includeSubdomains")}
13
13
 
14
14
  context "with an invalid configuration" do
15
15
  context "with a hash argument" do
16
16
  it "should allow string values for max-age" do
17
- lambda {
17
+ expect {
18
18
  StrictTransportSecurity.new(:max_age => '1234')
19
- }.should_not raise_error
19
+ }.not_to raise_error
20
20
  end
21
21
 
22
22
  it "should allow integer values for max-age" do
23
- lambda {
23
+ expect {
24
24
  StrictTransportSecurity.new(:max_age => 1234)
25
- }.should_not raise_error
25
+ }.not_to raise_error
26
26
  end
27
27
 
28
28
  it "raises an exception with an invalid max-age" do
29
- lambda {
29
+ expect {
30
30
  StrictTransportSecurity.new(:max_age => 'abc123')
31
- }.should raise_error(STSBuildError)
31
+ }.to raise_error(STSBuildError)
32
32
  end
33
33
 
34
34
  it "raises an exception if max-age is not supplied" do
35
- lambda {
35
+ expect {
36
36
  StrictTransportSecurity.new(:includeSubdomains => true)
37
- }.should raise_error(STSBuildError)
37
+ }.to raise_error(STSBuildError)
38
38
  end
39
39
  end
40
40
 
41
41
  context "with a string argument" do
42
42
  it "raises an exception with an invalid max-age" do
43
- lambda {
43
+ expect {
44
44
  StrictTransportSecurity.new('max-age=abc123')
45
- }.should raise_error(STSBuildError)
45
+ }.to raise_error(STSBuildError)
46
46
  end
47
47
 
48
48
  it "raises an exception if max-age is not supplied" do
49
- lambda {
49
+ expect {
50
50
  StrictTransportSecurity.new('includeSubdomains')
51
- }.should raise_error(STSBuildError)
51
+ }.to raise_error(STSBuildError)
52
52
  end
53
53
 
54
54
  it "raises an exception with an invalid format" do
55
- lambda {
55
+ expect {
56
56
  StrictTransportSecurity.new('max-age=123includeSubdomains')
57
- }.should raise_error(STSBuildError)
57
+ }.to raise_error(STSBuildError)
58
58
  end
59
59
  end
60
60
  end
@@ -1,33 +1,33 @@
1
1
  module SecureHeaders
2
2
  describe XContentTypeOptions do
3
- specify{ XContentTypeOptions.new.name.should == "X-Content-Type-Options" }
3
+ specify{ expect(XContentTypeOptions.new.name).to eq("X-Content-Type-Options") }
4
4
 
5
5
  describe "#value" do
6
- specify { XContentTypeOptions.new.value.should == XContentTypeOptions::Constants::DEFAULT_VALUE}
7
- specify { XContentTypeOptions.new("nosniff").value.should == "nosniff"}
8
- specify { XContentTypeOptions.new(:value => 'nosniff').value.should == "nosniff"}
6
+ specify { expect(XContentTypeOptions.new.value).to eq(XContentTypeOptions::Constants::DEFAULT_VALUE)}
7
+ specify { expect(XContentTypeOptions.new("nosniff").value).to eq("nosniff")}
8
+ specify { expect(XContentTypeOptions.new(:value => 'nosniff').value).to eq("nosniff")}
9
9
 
10
10
  context "invalid configuration values" do
11
11
  it "accepts nosniff" do
12
- lambda {
12
+ expect {
13
13
  XContentTypeOptions.new("nosniff")
14
- }.should_not raise_error
14
+ }.not_to raise_error
15
15
 
16
- lambda {
16
+ expect {
17
17
  XContentTypeOptions.new(:value => "nosniff")
18
- }.should_not raise_error
18
+ }.not_to raise_error
19
19
  end
20
20
 
21
21
  it "accepts nil" do
22
- lambda {
22
+ expect {
23
23
  XContentTypeOptions.new
24
- }.should_not raise_error
24
+ }.not_to raise_error
25
25
  end
26
26
 
27
27
  it "doesn't accept anything besides no-sniff" do
28
- lambda {
28
+ expect {
29
29
  XContentTypeOptions.new("donkey")
30
- }.should raise_error
30
+ }.to raise_error
31
31
  end
32
32
  end
33
33
  end
@@ -2,34 +2,34 @@ require 'spec_helper'
2
2
 
3
3
  module SecureHeaders
4
4
  describe XFrameOptions do
5
- specify{ XFrameOptions.new.name.should == "X-Frame-Options" }
5
+ specify{ expect(XFrameOptions.new.name).to eq("X-Frame-Options") }
6
6
 
7
7
  describe "#value" do
8
- specify { XFrameOptions.new.value.should == XFrameOptions::Constants::DEFAULT_VALUE}
9
- specify { XFrameOptions.new("SAMEORIGIN").value.should == "SAMEORIGIN"}
10
- specify { XFrameOptions.new(:value => 'DENY').value.should == "DENY"}
8
+ specify { expect(XFrameOptions.new.value).to eq(XFrameOptions::Constants::DEFAULT_VALUE)}
9
+ specify { expect(XFrameOptions.new("SAMEORIGIN").value).to eq("SAMEORIGIN")}
10
+ specify { expect(XFrameOptions.new(:value => 'DENY').value).to eq("DENY")}
11
11
 
12
12
  context "with invalid configuration" do
13
13
  it "allows SAMEORIGIN" do
14
- lambda {
14
+ expect {
15
15
  XFrameOptions.new("SAMEORIGIN").value
16
- }.should_not raise_error
16
+ }.not_to raise_error
17
17
  end
18
18
 
19
19
  it "allows DENY" do
20
- lambda {
20
+ expect {
21
21
  XFrameOptions.new("DENY").value
22
- }.should_not raise_error end
22
+ }.not_to raise_error end
23
23
 
24
24
  it "allows ALLOW-FROM*" do
25
- lambda {
25
+ expect {
26
26
  XFrameOptions.new("ALLOW-FROM: example.com").value
27
- }.should_not raise_error
27
+ }.not_to raise_error
28
28
  end
29
29
  it "does not allow garbage" do
30
- lambda {
30
+ expect {
31
31
  XFrameOptions.new("I like turtles").value
32
- }.should raise_error(XFOBuildError)
32
+ }.to raise_error(XFOBuildError)
33
33
  end
34
34
  end
35
35
  end
@@ -1,50 +1,50 @@
1
1
  module SecureHeaders
2
2
  describe XXssProtection do
3
- specify { XXssProtection.new.name.should == X_XSS_PROTECTION_HEADER_NAME}
4
- specify { XXssProtection.new.value.should == "1"}
5
- specify { XXssProtection.new("0").value.should == "0"}
6
- specify { XXssProtection.new(:value => 1, :mode => 'block').value.should == '1; mode=block' }
3
+ specify { expect(XXssProtection.new.name).to eq(X_XSS_PROTECTION_HEADER_NAME)}
4
+ specify { expect(XXssProtection.new.value).to eq("1")}
5
+ specify { expect(XXssProtection.new("0").value).to eq("0")}
6
+ specify { expect(XXssProtection.new(:value => 1, :mode => 'block').value).to eq('1; mode=block') }
7
7
 
8
8
  context "with invalid configuration" do
9
9
  it "should raise an error when providing a string that is not valid" do
10
- lambda {
10
+ expect {
11
11
  XXssProtection.new("asdf")
12
- }.should raise_error(XXssProtectionBuildError)
12
+ }.to raise_error(XXssProtectionBuildError)
13
13
 
14
- lambda {
14
+ expect {
15
15
  XXssProtection.new("asdf; mode=donkey")
16
- }.should raise_error(XXssProtectionBuildError)
16
+ }.to raise_error(XXssProtectionBuildError)
17
17
  end
18
18
 
19
19
  context "when using a hash value" do
20
20
  it "should allow string values ('1' or '0' are the only valid strings)" do
21
- lambda {
21
+ expect {
22
22
  XXssProtection.new(:value => '1')
23
- }.should_not raise_error
23
+ }.not_to raise_error
24
24
  end
25
25
 
26
26
  it "should allow integer values (1 or 0 are the only valid integers)" do
27
- lambda {
27
+ expect {
28
28
  XXssProtection.new(:value => 1)
29
- }.should_not raise_error
29
+ }.not_to raise_error
30
30
  end
31
31
 
32
32
  it "should raise an error if no value key is supplied" do
33
- lambda {
33
+ expect {
34
34
  XXssProtection.new(:mode => 'block')
35
- }.should raise_error(XXssProtectionBuildError)
35
+ }.to raise_error(XXssProtectionBuildError)
36
36
  end
37
37
 
38
38
  it "should raise an error if an invalid key is supplied" do
39
- lambda {
39
+ expect {
40
40
  XXssProtection.new(:value => 123)
41
- }.should raise_error(XXssProtectionBuildError)
41
+ }.to raise_error(XXssProtectionBuildError)
42
42
  end
43
43
 
44
44
  it "should raise an error if mode != block" do
45
- lambda {
45
+ expect {
46
46
  XXssProtection.new(:value => 1, :mode => "donkey")
47
- }.should raise_error(XXssProtectionBuildError)
47
+ }.to raise_error(XXssProtectionBuildError)
48
48
  end
49
49
  end
50
50