secure_headers 3.3.2 → 3.4.0

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9f6cd36ab6ff2100c1c0bdd0fe493aaf6030ab7
4
- data.tar.gz: dd8e633b00f13f2afe165a7cebb5d9b2a13fc5d0
3
+ metadata.gz: 88233251c7a26e1269f77957d56823619e3d9d11
4
+ data.tar.gz: 8e9c0e69fcca0298ee52223d587134f5a8df062f
5
5
  SHA512:
6
- metadata.gz: ed6420d1b5a1817b09557501834ac7d9c48b8dfa4cd4affdff49208038b3b277d3debc37baca7d31c5a800b4cfcb27b31311581d1302311d4a639498652b119c
7
- data.tar.gz: 6bf1ef8d330ee00ccee7a5950e73aeae24fe5c10d78a6fa96bc34b0724cc4f772f577a0b11dc3daf9f3270ad41fefce2505dfcae709f2ebb1b79ae9e6b352ae4
6
+ metadata.gz: f421d0d58eb9b5a7b22fd13932644c2c3868e0294886cbf5250127e8807fa20dec95717219e0a82ce59f49f376b32e17b97b77c7e011d2e2d1633162c1297bbc
7
+ data.tar.gz: ae63cbdd588bf6c31e531bfec5480e022a5df96c8ee2cc4c824d1e869f64df2a44073d795cc6d5e7ffeca6d6369f0d2e33f202ce8ceda04d274849e95789ff43
@@ -0,0 +1,41 @@
1
+ # Feature Requests
2
+
3
+ ## Adding a new header
4
+
5
+ Generally, adding a new header is always OK.
6
+
7
+ * Is the header supported by any user agent? If so, which?
8
+ * What does it do?
9
+ * What are the valid values for the header?
10
+ * Where does the specification live?
11
+
12
+ ## Adding a new CSP directive
13
+
14
+ * Is the directive supported by any user agent? If so, which?
15
+ * What does it do?
16
+ * What are the valid values for the directive?
17
+
18
+ ---
19
+
20
+ # Bugs
21
+
22
+ Console errors and deprecation warnings are considered bugs that should be addressed with more precise UA sniffing. Bugs caused by incorrect or invalid UA sniffing are also bugs.
23
+
24
+ ### Expected outcome
25
+
26
+ Describe what you expected to happen
27
+
28
+ 1. I configure CSP to do X
29
+ 1. When I inspect the response headers, the CSP should have included X
30
+
31
+ ### Actual outcome
32
+
33
+ 1. The generated policy did not include X
34
+
35
+ ### Config
36
+
37
+ Please provide the configuration (`SecureHeaders::Configuration.default`) you are using including any overrides (`SecureHeaders::Configuration.override`).
38
+
39
+ ### Generated headers
40
+
41
+ Provide a sample response containing the headers
@@ -0,0 +1,20 @@
1
+ ## All PRs:
2
+
3
+ * [ ] Has tests
4
+ * [ ] Documentation updated
5
+
6
+ ## Adding a new header
7
+
8
+ Generally, adding a new header is always OK.
9
+
10
+ * Is the header supported by any user agent? If so, which?
11
+ * What does it do?
12
+ * What are the valid values for the header?
13
+ * Where does the specification live?
14
+
15
+ ## Adding a new CSP directive
16
+
17
+ * Is the directive supported by any user agent? If so, which?
18
+ * What does it do?
19
+ * What are the valid values for the directive?
20
+
@@ -1,3 +1,17 @@
1
+ ## 3.4.0 the frame-src/child-src transition for Firefox.
2
+
3
+ Handle the `child-src`/`frame-src` transition semi-intelligently across versions. I think the code best descibes the behavior here:
4
+
5
+ ```ruby
6
+ if supported_directives.include?(:child_src)
7
+ @config[:child_src] = @config[:child_src] || @config[:frame_src]
8
+ else
9
+ @config[:frame_src] = @config[:frame_src] || @config[:child_src]
10
+ end
11
+ ```
12
+
13
+ Also, @koenpunt noticed that we were [loading view helpers](https://github.com/twitter/secureheaders/pull/272) in a way that Rails 5 did not like.
14
+
1
15
  ## 3.3.2 minor fix to silence warnings when using rake
2
16
 
3
17
  [@dankohn](https://github.com/twitter/secureheaders/issues/257) was seeing "already initialized" errors in his output. This change conditionally defines the constants.
data/Gemfile CHANGED
@@ -5,7 +5,8 @@ gemspec
5
5
  group :test do
6
6
  gem "tins", "~> 1.6.0" # 1.7 requires ruby 2.0
7
7
  gem "pry-nav"
8
- gem "rack"
8
+ gem "json", "~> 1"
9
+ gem "rack", "~> 1"
9
10
  gem "rspec"
10
11
  gem "coveralls"
11
12
  end
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  The gem will automatically apply several headers that are related to security. This includes:
9
9
  - Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack. [CSP 2 Specification](http://www.w3.org/TR/CSP2/)
10
10
  - HTTP Strict Transport Security (HSTS) - Ensures the browser never visits the http version of a website. Protects from SSLStrip/Firesheep attacks. [HSTS Specification](https://tools.ietf.org/html/rfc6797)
11
- - X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options draft](https://tools.ietf.org/html/draft-ietf-websec-x-frame-options-02)
11
+ - X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options Specification](https://tools.ietf.org/html/rfc7034)
12
12
  - X-XSS-Protection - [Cross site scripting heuristic filter for IE/Chrome](https://msdn.microsoft.com/en-us/library/dd565647\(v=vs.85\).aspx)
13
13
  - X-Content-Type-Options - [Prevent content type sniffing](https://msdn.microsoft.com/library/gg622941\(v=vs.85\).aspx)
14
14
  - X-Download-Options - [Prevent file downloads opening](https://msdn.microsoft.com/library/jj542450(v=vs.85).aspx)
@@ -53,20 +53,19 @@ SecureHeaders::Configuration.default do |config|
53
53
 
54
54
  # directive values: these values will directly translate into source directives
55
55
  default_src: %w(https: 'self'),
56
- frame_src: %w('self' *.twimg.com itunes.apple.com),
57
- connect_src: %w(wws:),
56
+ base_uri: %w('self'),
57
+ block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
58
+ child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
59
+ connect_src: %w(wss:),
58
60
  font_src: %w('self' data:),
61
+ form_action: %w('self' github.com),
62
+ frame_ancestors: %w('none'),
59
63
  img_src: %w(mycdn.com data:),
60
64
  media_src: %w(utoob.com),
61
65
  object_src: %w('self'),
66
+ plugin_types: %w(application/x-shockwave-flash),
62
67
  script_src: %w('self'),
63
68
  style_src: %w('unsafe-inline'),
64
- base_uri: %w('self'),
65
- child_src: %w('self'),
66
- form_action: %w('self' github.com),
67
- frame_ancestors: %w('none'),
68
- plugin_types: %w(application/x-shockwave-flash),
69
- block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
70
69
  upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
71
70
  report_uri: %w(https://report-uri.io/example-csp)
72
71
  }
@@ -203,7 +203,7 @@ module SecureHeaders
203
203
  raise IllegalPolicyModificationError, "You are attempting to modify CSP settings directly. Use dynamic_csp= instead."
204
204
  end
205
205
 
206
- @csp = new_csp
206
+ @csp = self.class.send(:deep_copy_if_hash, new_csp)
207
207
  end
208
208
 
209
209
  def cookies=(cookies)
@@ -215,7 +215,7 @@ module SecureHeaders
215
215
  end
216
216
 
217
217
  def hpkp=(hpkp)
218
- @hpkp = hpkp
218
+ @hpkp = self.class.send(:deep_copy_if_hash, hpkp)
219
219
  end
220
220
 
221
221
  def hpkp_report_host=(hpkp_report_host)
@@ -1,18 +1,22 @@
1
1
  require_relative 'policy_management'
2
+ require 'useragent'
2
3
 
3
4
  module SecureHeaders
4
5
  class ContentSecurityPolicyConfigError < StandardError; end
5
6
  class ContentSecurityPolicy
6
7
  include PolicyManagement
7
8
 
9
+ # constants to be used for version-specific UA sniffing
10
+ VERSION_46 = ::UserAgent::Version.new("46")
11
+
8
12
  def initialize(config = nil, user_agent = OTHER)
9
- config = Configuration.deep_copy(DEFAULT_CONFIG) unless config
10
- @config = config
13
+ @config = Configuration.send(:deep_copy, config || DEFAULT_CONFIG)
11
14
  @parsed_ua = if user_agent.is_a?(UserAgent::Browsers::Base)
12
15
  user_agent
13
16
  else
14
17
  UserAgent.parse(user_agent)
15
18
  end
19
+ normalize_child_frame_src
16
20
  @report_only = @config[:report_only]
17
21
  @preserve_schemes = @config[:preserve_schemes]
18
22
  @script_nonce = @config[:script_nonce]
@@ -42,6 +46,22 @@ module SecureHeaders
42
46
 
43
47
  private
44
48
 
49
+ # frame-src is deprecated, child-src is being implemented. They are
50
+ # very similar and in most cases, the same value can be used for both.
51
+ def normalize_child_frame_src
52
+ if @config[:frame_src] && @config[:child_src] && @config[:frame_src] != @config[:child_src]
53
+ Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers.")
54
+ elsif @config[:frame_src]
55
+ Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] :frame_src is deprecated, use :child_src instead. Provided: #{@config[:frame_src]}.")
56
+ end
57
+
58
+ if supported_directives.include?(:child_src)
59
+ @config[:child_src] = @config[:child_src] || @config[:frame_src]
60
+ else
61
+ @config[:frame_src] = @config[:frame_src] || @config[:child_src]
62
+ end
63
+ end
64
+
45
65
  # Private: converts the config object into a string representing a policy.
46
66
  # Places default-src at the first directive and report-uri as the last. All
47
67
  # others are presented in alphabetical order.
@@ -162,9 +182,19 @@ module SecureHeaders
162
182
 
163
183
  # Private: determine which directives are supported for the given user agent.
164
184
  #
185
+ # Add UA-sniffing special casing here.
186
+ #
165
187
  # Returns an array of symbols representing the directives.
166
188
  def supported_directives
167
- @supported_directives ||= VARIATIONS[@parsed_ua.browser] || VARIATIONS[OTHER]
189
+ @supported_directives ||= if VARIATIONS[@parsed_ua.browser]
190
+ if @parsed_ua.browser == "Firefox" && @parsed_ua.version >= VERSION_46
191
+ VARIATIONS["FirefoxTransitional"]
192
+ else
193
+ VARIATIONS[@parsed_ua.browser]
194
+ end
195
+ else
196
+ VARIATIONS[OTHER]
197
+ end
168
198
  end
169
199
 
170
200
  def nonces_supported?
@@ -100,10 +100,23 @@ module SecureHeaders
100
100
  PLUGIN_TYPES
101
101
  ].freeze
102
102
 
103
+ FIREFOX_46_DEPRECATED_DIRECTIVES = [
104
+ FRAME_SRC
105
+ ].freeze
106
+
107
+ FIREFOX_46_UNSUPPORTED_DIRECTIVES = [
108
+ BLOCK_ALL_MIXED_CONTENT,
109
+ PLUGIN_TYPES
110
+ ].freeze
111
+
103
112
  FIREFOX_DIRECTIVES = (
104
113
  DIRECTIVES_2_0 + DIRECTIVES_DRAFT - FIREFOX_UNSUPPORTED_DIRECTIVES
105
114
  ).freeze
106
115
 
116
+ FIREFOX_46_DIRECTIVES = (
117
+ DIRECTIVES_2_0 + DIRECTIVES_DRAFT - FIREFOX_46_UNSUPPORTED_DIRECTIVES - FIREFOX_46_DEPRECATED_DIRECTIVES
118
+ ).freeze
119
+
107
120
  CHROME_DIRECTIVES = (
108
121
  DIRECTIVES_2_0 + DIRECTIVES_DRAFT
109
122
  ).freeze
@@ -118,6 +131,7 @@ module SecureHeaders
118
131
  "Chrome" => CHROME_DIRECTIVES,
119
132
  "Opera" => CHROME_DIRECTIVES,
120
133
  "Firefox" => FIREFOX_DIRECTIVES,
134
+ "FirefoxTransitional" => FIREFOX_46_DIRECTIVES,
121
135
  "Safari" => SAFARI_DIRECTIVES,
122
136
  "Edge" => EDGE_DIRECTIVES,
123
137
  "Other" => CHROME_DIRECTIVES
@@ -108,8 +108,6 @@ module SecureHeaders
108
108
  end
109
109
  end
110
110
 
111
- module ActionView #:nodoc:
112
- class Base #:nodoc:
113
- include SecureHeaders::ViewHelpers
114
- end
115
- end
111
+ ActiveSupport.on_load :action_view do
112
+ include SecureHeaders::ViewHelpers
113
+ end if defined?(ActiveSupport)
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = "secure_headers"
4
- gem.version = "3.3.2"
4
+ gem.version = "3.4.0"
5
5
  gem.authors = ["Neil Matatall"]
6
6
  gem.email = ["neil.matatall@gmail.com"]
7
7
  gem.description = 'Security related headers all in one gem.'
@@ -24,7 +24,7 @@ module SecureHeaders
24
24
 
25
25
  describe "#value" do
26
26
  it "discards 'none' values if any other source expressions are present" do
27
- csp = ContentSecurityPolicy.new(default_opts.merge(frame_src: %w('self' 'none')))
27
+ csp = ContentSecurityPolicy.new(default_opts.merge(child_src: %w('self' 'none')))
28
28
  expect(csp.value).not_to include("'none'")
29
29
  end
30
30
 
@@ -86,42 +86,68 @@ module SecureHeaders
86
86
  expect(csp.value).to eq("default-src example.org")
87
87
  end
88
88
 
89
+ it "emits a warning when using frame-src" do
90
+ expect(Kernel).to receive(:warn).with(/:frame_src is deprecated, use :child_src instead./)
91
+ ContentSecurityPolicy.new(default_src: %w('self'), frame_src: %w('self')).value
92
+ end
93
+
94
+ it "emits a warning when child-src and frame-src are supplied but are not equal" do
95
+ expect(Kernel).to receive(:warn).with(/both :child_src and :frame_src supplied and do not match./)
96
+ ContentSecurityPolicy.new(default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)).value
97
+ end
98
+
99
+ it "will still set inconsistent child/frame-src values to be less surprising" do
100
+ expect(Kernel).to receive(:warn).at_least(:once)
101
+ firefox = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox]).value
102
+ firefox_transitional = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox46]).value
103
+ expect(firefox).not_to eq(firefox_transitional)
104
+ expect(firefox).to match(/frame-src/)
105
+ expect(firefox).not_to match(/child-src/)
106
+ expect(firefox_transitional).to match(/child-src/)
107
+ expect(firefox_transitional).not_to match(/frame-src/)
108
+ end
109
+
89
110
  context "browser sniffing" do
90
111
  let (:complex_opts) do
91
- ContentSecurityPolicy::ALL_DIRECTIVES.each_with_object({}) do |directive, hash|
92
- hash[directive] = %w('self')
112
+ (ContentSecurityPolicy::ALL_DIRECTIVES - [:frame_src]).each_with_object({}) do |directive, hash|
113
+ hash[directive] = ["#{directive.to_s.gsub("_", "-")}.com"]
93
114
  end.merge({
94
115
  block_all_mixed_content: true,
95
116
  upgrade_insecure_requests: true,
96
117
  reflected_xss: "block",
97
- script_src: %w('self'),
118
+ script_src: %w(script-src.com),
98
119
  script_nonce: 123456
99
120
  })
100
121
  end
101
122
 
102
123
  it "does not filter any directives for Chrome" do
103
124
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:chrome])
104
- expect(policy.value).to eq("default-src 'self'; base-uri 'self'; block-all-mixed-content; child-src 'self'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'self'; plugin-types 'self'; sandbox 'self'; script-src 'self' 'nonce-123456'; style-src 'self'; upgrade-insecure-requests; report-uri 'self'")
125
+ expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
105
126
  end
106
127
 
107
128
  it "does not filter any directives for Opera" do
108
129
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:opera])
109
- expect(policy.value).to eq("default-src 'self'; base-uri 'self'; block-all-mixed-content; child-src 'self'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'self'; plugin-types 'self'; sandbox 'self'; script-src 'self' 'nonce-123456'; style-src 'self'; upgrade-insecure-requests; report-uri 'self'")
130
+ expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
110
131
  end
111
132
 
112
133
  it "filters blocked-all-mixed-content, child-src, and plugin-types for firefox" do
113
134
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox])
114
- expect(policy.value).to eq("default-src 'self'; base-uri 'self'; connect-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'self'; sandbox 'self'; script-src 'self' 'nonce-123456'; style-src 'self'; upgrade-insecure-requests; report-uri 'self'")
135
+ expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
136
+ end
137
+
138
+ it "filters blocked-all-mixed-content, frame-src, and plugin-types for firefox 46 and higher" do
139
+ policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox46])
140
+ expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
115
141
  end
116
142
 
117
- it "adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for Edge" do
143
+ it "child-src value is copied to frame-src, adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for Edge" do
118
144
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:edge])
119
- expect(policy.value).to eq("default-src 'self'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'self'; sandbox 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'; report-uri 'self'")
145
+ expect(policy.value).to eq("default-src default-src.com; connect-src connect-src.com; font-src font-src.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'unsafe-inline'; style-src style-src.com; report-uri report-uri.com")
120
146
  end
121
147
 
122
- it "adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for safari" do
148
+ it "child-src value is copied to frame-src, adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for safari" do
123
149
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:safari6])
124
- expect(policy.value).to eq("default-src 'self'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'self'; sandbox 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'; report-uri 'self'")
150
+ expect(policy.value).to eq("default-src default-src.com; connect-src connect-src.com; font-src font-src.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'unsafe-inline'; style-src style-src.com; report-uri report-uri.com")
125
151
  end
126
152
  end
127
153
  end
@@ -23,7 +23,8 @@ module SecureHeaders
23
23
  # directive values: these values will directly translate into source directives
24
24
  default_src: %w(https: 'self'),
25
25
  frame_src: %w('self' *.twimg.com itunes.apple.com),
26
- connect_src: %w(wws:),
26
+ child_src: %w('self' *.twimg.com itunes.apple.com),
27
+ connect_src: %w(wss:),
27
28
  font_src: %w('self' data:),
28
29
  img_src: %w(mycdn.com data:),
29
30
  media_src: %w(utoob.com),
@@ -31,7 +32,6 @@ module SecureHeaders
31
32
  script_src: %w('self'),
32
33
  style_src: %w('unsafe-inline'),
33
34
  base_uri: %w('self'),
34
- child_src: %w('self'),
35
35
  form_action: %w('self' github.com),
36
36
  frame_ancestors: %w('none'),
37
37
  plugin_types: %w(application/x-shockwave-flash),
@@ -90,8 +90,7 @@ module SecureHeaders
90
90
  config = Configuration.default do |config|
91
91
  config.csp = {
92
92
  default_src: %w('self'),
93
- child_src: %w('self'), #unsupported by firefox
94
- frame_src: %w('self')
93
+ child_src: %w('self')
95
94
  }
96
95
  end
97
96
  firefox_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:firefox]))
@@ -102,6 +101,8 @@ module SecureHeaders
102
101
  SecureHeaders.override_content_security_policy_directives(firefox_request, script_src: %w('self'))
103
102
 
104
103
  hash = SecureHeaders.header_hash_for(firefox_request)
104
+
105
+ # child-src is translated to frame-src
105
106
  expect(hash[CSP::HEADER_NAME]).to eq("default-src 'self'; frame-src 'self'; script-src 'self'")
106
107
  end
107
108
 
@@ -12,7 +12,8 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'secure_headers')
12
12
 
13
13
  USER_AGENTS = {
14
14
  edge: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
15
- firefox: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1',
15
+ firefox: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1",
16
+ firefox46: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0",
16
17
  chrome: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5',
17
18
  ie: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)',
18
19
  opera: 'Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00',
@@ -8,7 +8,7 @@ Changes
8
8
  | Global configuration | `SecureHeaders::Configuration.configure` block | `SecureHeaders::Configuration.default` block |
9
9
  | All headers besides HPKP and CSP | Accept hashes as config values | Must be strings (validated during configuration) |
10
10
  | CSP directive values | Accepted space delimited strings OR arrays of strings | Must be arrays of strings |
11
- | CSP Nonce values in views | `@content_security_policy_nonce` | `content_security_policy_script_nonce` or `content_security_policy_style_nonce` |
11
+ | CSP Nonce values in views | `@content_security_policy_nonce` | `content_security_policy_nonce(:script)` or `content_security_policy_nonce(:style)` |
12
12
  | nonce is no longer a source expression | `config.csp = "'self' 'nonce'"` | Remove `'nonce'` from source expression and use [nonce helpers](https://github.com/twitter/secureheaders#nonce). |
13
13
  | `self`/`none` source expressions | Could be `self` / `none` / `'self'` / `'none'` | Must be `'self'` or `'none'` |
14
14
  | `inline` / `eval` source expressions | Could be `inline`, `eval`, `'unsafe-inline'`, or `'unsafe-eval'` | Must be `'unsafe-eval'` or `'unsafe-inline'` |
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secure_headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.2
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Matatall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-23 00:00:00.000000000 Z
11
+ date: 2016-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -45,6 +45,8 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/ISSUE_TEMPLATE.md"
49
+ - ".github/PULL_REQUEST_TEMPLATE.md"
48
50
  - ".gitignore"
49
51
  - ".rspec"
50
52
  - ".ruby-gemset"