secure_headers 3.3.2 → 3.4.0

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.

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"