secure_headers 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of secure_headers might be problematic. Click here for more details.

data/HISTORY.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.4.3
2
+ ======
3
+
4
+ - Stupid bug where Fixnums couldn't be used for config values
5
+ - Doc updates
6
+
1
7
  0.4.1
2
8
  ======
3
9
 
data/README.md CHANGED
@@ -41,7 +41,7 @@ By default, it will set all of the headers listed in the options section below u
41
41
 
42
42
  Use the standard `skip_before_filter :filter_name, options` mechanism. e.g. `skip_before_filter :set_csp_header, :only => :tinymce_page`
43
43
 
44
- The following methods are going to be called, unles they are provided in a `skip_before_filter` block.
44
+ The following methods are going to be called, unless they are provided in a `skip_before_filter` block.
45
45
 
46
46
  * `:set_csp_header`
47
47
  * `:set_hsts_header`
@@ -53,10 +53,10 @@ The following methods are going to be called, unles they are provided in a `skip
53
53
 
54
54
  This gem makes a few assumptions about how you will use some features. For example:
55
55
 
56
- * It adds 'chrome-extension:' to your CSP directives by default. This helps drastically reduce the amount of reports, but you can also disable this feature by supplying :disable_chrome_extension => true.
57
- * It fills any blank directives with the value in :default_src Getting a default\-src report is pretty useless. This way, you will always know what type of violation occurred. You can disable this feature by supplying :disable_fill_missing => true.
56
+ * It adds 'chrome-extension:' to your CSP directives by default. This helps drastically reduce the amount of reports, but you can also disable this feature by supplying `:disable_chrome_extension => true`.
57
+ * It fills any blank directives with the value in `:default_src` Getting a default\-src report is pretty useless. This way, you will always know what type of violation occurred. You can disable this feature by supplying `:disable_fill_missing => true`.
58
58
  * It copies the connect\-src value to xhr\-src for AJAX requests when using Firefox.
59
- * Firefox does not support cross\-origin CSP reports. If we are using Firefox, AND the value for :report_uri does not satisfy the same\-origin requirements, we will instead forward to an internal endpoint (`FF_CSP_ENDPOINT`). This is also the case if :report_uri only contains a path, which we assume will be cross host. This endpoint will in turn forward the request to the value in :forward_endpoint without restriction. More information can be found in the "Note on Firefox handling of CSP" section.
59
+ * Firefox does not support cross\-origin CSP reports. If we are using Firefox, AND the value for `:report_uri` does not satisfy the same\-origin requirements, we will instead forward to an internal endpoint (`FF_CSP_ENDPOINT`). This is also the case if `:report_uri` only contains a path, which we assume will be cross host. This endpoint will in turn forward the request to the value in `:forward_endpoint` without restriction. More information can be found in the "Note on Firefox handling of CSP" section.
60
60
 
61
61
 
62
62
  ## Configuration
@@ -159,6 +159,16 @@ and [Mozilla CSP specification](https://wiki.mozilla.org/Security/CSP/Specificat
159
159
  :img_src => 'http://mycdn.example.com'
160
160
  }
161
161
  }
162
+
163
+ # script-nonce is an experimental feature of CSP 1.1 available in Chrome. It allows
164
+ # you to whitelist inline script blocks. For more information, see
165
+ # https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-nonce
166
+ :script_nonce => { 'abc123' }
167
+
168
+ # you can also use lambdas to use dynamically generated nonces
169
+ :script_nonce => lambda { @script_nonce] = 'something' }
170
+ # which can be used to whitelist a script block:
171
+ # script_tag :nonce = @script_nonce { inline_script_call() }
162
172
  }
163
173
  ```
164
174
 
@@ -72,10 +72,10 @@ module SecureHeaders
72
72
  options = self.class.options_for :csp, options
73
73
  return if options == false
74
74
 
75
- header = ContentSecurityPolicy.new(options, :request => request)
75
+ header = ContentSecurityPolicy.new(options, :request => request, :controller => self)
76
76
  set_header(header.name, header.value)
77
77
  if options && options[:experimental] && options[:enforce]
78
- header = ContentSecurityPolicy.new(options, :experimental => true, :request => request)
78
+ header = ContentSecurityPolicy.new(options, :experimental => true, :request => request, :controller => self)
79
79
  set_header(header.name, header.value)
80
80
  end
81
81
  end
@@ -36,6 +36,7 @@ module SecureHeaders
36
36
  # :report used to determine what :ssl_request, :ua, and :request_uri are set to
37
37
  def initialize(config=nil, options={})
38
38
  @experimental = !!options.delete(:experimental)
39
+ @controller = options.delete(:controller)
39
40
  if options[:request]
40
41
  parse_request(options[:request])
41
42
  else
@@ -65,6 +66,7 @@ module SecureHeaders
65
66
  end
66
67
 
67
68
  @report_uri = @config.delete(:report_uri)
69
+ @script_nonce = @config.delete(:script_nonce)
68
70
 
69
71
  normalize_csp_options
70
72
  normalize_reporting_endpoint
@@ -103,7 +105,8 @@ module SecureHeaders
103
105
  header_value = [
104
106
  build_impl_specific_directives,
105
107
  generic_directives(@config),
106
- report_uri_directive
108
+ report_uri_directive,
109
+ script_nonce_directive,
107
110
  ].join
108
111
 
109
112
  #store the value for next time
@@ -208,6 +211,18 @@ module SecureHeaders
208
211
  "report-uri #{@report_uri};"
209
212
  end
210
213
 
214
+ def script_nonce_directive
215
+ return '' if @script_nonce.nil?
216
+ nonce_value = if @script_nonce.is_a?(String)
217
+ @script_nonce
218
+ elsif @controller
219
+ @controller.instance_exec(&@script_nonce)
220
+ else
221
+ @script_nonce.call
222
+ end
223
+ "script-nonce #{nonce_value};"
224
+ end
225
+
211
226
  def generic_directives(config)
212
227
  header_value = ''
213
228
  if config[:img_src]
@@ -29,7 +29,7 @@ module SecureHeaders
29
29
  end
30
30
 
31
31
  max_age = @config.fetch(:max_age, HSTS_MAX_AGE)
32
- value = "max-age=" + max_age
32
+ value = "max-age=" + max_age.to_s
33
33
  value += "; includeSubdomains" if @config[:include_subdomains]
34
34
 
35
35
  value
@@ -1,3 +1,3 @@
1
1
  module SecureHeaders
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -397,6 +397,38 @@ module SecureHeaders
397
397
  end
398
398
  end
399
399
  end
400
+
401
+ context "when supplying a script nonce callback" do
402
+ let(:options) {
403
+ default_opts.merge({
404
+ :script_nonce => "random",
405
+ })
406
+ }
407
+
408
+ it "uses the value in the X-Webkit-CSP" do
409
+ csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
410
+ csp.value.should match "script-nonce random;"
411
+ end
412
+
413
+ it "uses the value in the X-Content-Security-Policy" do
414
+ csp = ContentSecurityPolicy.new(options, :request => request_for(FIREFOX))
415
+ csp.value.should match "script-nonce random;"
416
+ end
417
+
418
+ it "runs a dynamic nonce generator" do
419
+ options[:script_nonce] = lambda { 'something' }
420
+ csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
421
+ csp.value.should match "script-nonce something;"
422
+ end
423
+
424
+ it "runs against the given controller context" do
425
+ fake_params = {}
426
+ options[:script_nonce] = lambda { params[:script_nonce] = 'something' }
427
+ csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME), :controller => double(:params => fake_params))
428
+ csp.value.should match "script-nonce something;"
429
+ fake_params.should == {:script_nonce => 'something'}
430
+ end
431
+ end
400
432
  end
401
433
  end
402
434
  end
@@ -26,6 +26,12 @@ module SecureHeaders
26
26
  s.value.should == "max-age=#{age}"
27
27
  end
28
28
 
29
+ it "allows you to specify max-age as a Fixnum" do
30
+ age = 8675309
31
+ s = StrictTransportSecurity.new(:max_age => age)
32
+ s.value.should == "max-age=#{age}"
33
+ end
34
+
29
35
  context "with an invalid configuration" do
30
36
  context "with a hash argument" do
31
37
  it "should allow string values for max-age" do
metadata CHANGED
@@ -1,55 +1,62 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: secure_headers
3
- version: !ruby/object:Gem::Version
4
- version: 0.4.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 2
10
+ version: 0.4.2
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Neil Matatall
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2013-04-10 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2013-05-05 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: brwsr
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: 1.1.1
22
- type: :runtime
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 17
29
+ segments:
30
+ - 1
31
+ - 1
32
+ - 1
29
33
  version: 1.1.1
30
- - !ruby/object:Gem::Dependency
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
31
37
  name: rake
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
39
38
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
39
+ requirement: &id002 !ruby/object:Gem::Requirement
41
40
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id002
46
50
  description: Add easily configured browser headers to responses.
47
- email:
51
+ email:
48
52
  - neil.matatall@gmail.com
49
53
  executables: []
54
+
50
55
  extensions: []
56
+
51
57
  extra_rdoc_files: []
52
- files:
58
+
59
+ files:
53
60
  - .gitignore
54
61
  - .rvmrc
55
62
  - .travis.yml
@@ -170,32 +177,39 @@ files:
170
177
  - spec/spec_helper.rb
171
178
  - travis.sh
172
179
  homepage: https://github.com/twitter/secureheaders
173
- licenses:
180
+ licenses:
174
181
  - Apache Public License 2.0
175
182
  post_install_message:
176
183
  rdoc_options: []
177
- require_paths:
184
+
185
+ require_paths:
178
186
  - lib
179
- required_ruby_version: !ruby/object:Gem::Requirement
187
+ required_ruby_version: !ruby/object:Gem::Requirement
180
188
  none: false
181
- requirements:
182
- - - ! '>='
183
- - !ruby/object:Gem::Version
184
- version: '0'
185
- required_rubygems_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ hash: 3
193
+ segments:
194
+ - 0
195
+ version: "0"
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
197
  none: false
187
- requirements:
188
- - - ! '>='
189
- - !ruby/object:Gem::Version
190
- version: '0'
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ hash: 3
202
+ segments:
203
+ - 0
204
+ version: "0"
191
205
  requirements: []
206
+
192
207
  rubyforge_project:
193
208
  rubygems_version: 1.8.24
194
209
  signing_key:
195
210
  specification_version: 3
196
- summary: Add easily configured browser headers to responses including content security
197
- policy, x-frame-options, strict-transport-security and more.
198
- test_files:
211
+ summary: Add easily configured browser headers to responses including content security policy, x-frame-options, strict-transport-security and more.
212
+ test_files:
199
213
  - spec/controllers/content_security_policy_controller_spec.rb
200
214
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
201
215
  - spec/lib/secure_headers/headers/strict_transport_security_spec.rb