secure_headers 3.0.0 → 3.0.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.

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: ed9f86aeaa22e01fb8d842a43ff1607cb8083b6a
4
- data.tar.gz: b71a52f6790c7a0f78053695038cb925e2c4895a
3
+ metadata.gz: 208059fe9a87ae245d5e89de656e6e5065a7b146
4
+ data.tar.gz: 61befbceb8d4fd119abf6a3913829f15a328054c
5
5
  SHA512:
6
- metadata.gz: 699085b909d21178a40e9f109687b3d9dd6dd21bb7250d81a33aca7b682627ad79f0c59941647b82f0492f2d25aae513ad825826d38760c579518b7c2d8ee508
7
- data.tar.gz: 89d8d3c867306921bff9a7f5a09f2708a54eecdce5a57a83cd8c505253afbd46ae67d489beef5cb8f5eba678235110ae50e69f9e82c1391dd53c125ede53cb73
6
+ metadata.gz: 828c2b59608e98e470e8a1b1bf11f272897d7db47443c79057f37775d7fa866679bc2d77da4a8b8a88d3135732fa01bc2b1d2f0a8b29afb07dc6c450cc0fd436
7
+ data.tar.gz: 2caac270328075254de8940840dce7b2573302c534f3533ec6566765a66a4a3546f9d52be972945cf28c8dad3ca6d7fb7d2044af4bc28f0b646041841017627f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 3.0.1
2
+
3
+ Adds `upgrade-insecure-requests` support for requests from Firefox and Chrome (and Opera). See [the spec](https://www.w3.org/TR/upgrade-insecure-requests/) for details.
4
+
1
5
  ## 3.0.0
2
6
 
3
7
  secure_headers 3.0.0 is a near-complete, not-entirely-backward-compatible rewrite. Please see the [upgrade guide](https://github.com/twitter/secureheaders/blob/master/upgrading-to-3-0.md) for an in-depth explanation of the changes and the suggested upgrade path.
data/README.md CHANGED
@@ -56,6 +56,7 @@ SecureHeaders::Configuration.default do |config|
56
56
  frame_ancestors: %w('none'),
57
57
  plugin_types: %w(application/x-shockwave-flash),
58
58
  block_all_mixed_content: true, # see [http://www.w3.org/TR/mixed-content/](http://www.w3.org/TR/mixed-content/)
59
+ upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
59
60
  report_uri: %w(https://example.com/uri-directive)
60
61
  }
61
62
  config.hpkp = {
@@ -130,7 +131,7 @@ By default, a noop configuration is provided. No headers will be set when this d
130
131
  ```ruby
131
132
  class MyController < ApplicationController
132
133
  def index
133
- SecureHeaders::opt_out_of_all_protection(request)
134
+ SecureHeaders.opt_out_of_all_protection(request)
134
135
  end
135
136
  end
136
137
  ```
@@ -191,7 +192,7 @@ Code | Result
191
192
 
192
193
  #### Nonce
193
194
 
194
- script/style-nonce can be used to whitelist inline content. To do this, call the SecureHeaders::content_security_policy_nonce then set the nonce attributes on the various tags.
195
+ script/style-nonce can be used to whitelist inline content. To do this, call the `SecureHeaders.content_security_policy_nonce` then set the nonce attributes on the various tags.
195
196
 
196
197
  Setting a nonce will also set 'unsafe-inline' for browsers that don't support nonces for backwards compatibility. 'unsafe-inline' is ignored if a nonce is present in a directive in compliant browsers.
197
198
 
@@ -280,7 +281,7 @@ class Donkey < Sinatra::Application
280
281
  set :root, APP_ROOT
281
282
 
282
283
  get '/' do
283
- SecureHeaders.override_x_frame_options(SecureHeaders::OPT_OUT)
284
+ SecureHeaders.override_x_frame_options(request, SecureHeaders::OPT_OUT)
284
285
  haml :index
285
286
  end
286
287
  end
@@ -77,8 +77,10 @@ module SecureHeaders
77
77
  # All the directives that are not currently in a formal spec, but have
78
78
  # been implemented somewhere.
79
79
  BLOCK_ALL_MIXED_CONTENT = :block_all_mixed_content
80
+ UPGRADE_INSECURE_REQUESTS = :upgrade_insecure_requests
80
81
  DIRECTIVES_DRAFT = [
81
- BLOCK_ALL_MIXED_CONTENT
82
+ BLOCK_ALL_MIXED_CONTENT,
83
+ UPGRADE_INSECURE_REQUESTS
82
84
  ].freeze
83
85
 
84
86
  SAFARI_DIRECTIVES = DIRECTIVES_1_0
@@ -90,7 +92,7 @@ module SecureHeaders
90
92
  ].freeze
91
93
 
92
94
  FIREFOX_DIRECTIVES = (
93
- DIRECTIVES_2_0 - FIREFOX_UNSUPPORTED_DIRECTIVES
95
+ DIRECTIVES_2_0 + DIRECTIVES_DRAFT - FIREFOX_UNSUPPORTED_DIRECTIVES
94
96
  ).freeze
95
97
 
96
98
  CHROME_DIRECTIVES = (
@@ -114,25 +116,26 @@ module SecureHeaders
114
116
  OTHER = "Other".freeze
115
117
 
116
118
  DIRECTIVE_VALUE_TYPES = {
117
- BASE_URI => :source_list,
118
- BLOCK_ALL_MIXED_CONTENT => :boolean,
119
- CHILD_SRC => :source_list,
120
- CONNECT_SRC => :source_list,
121
- DEFAULT_SRC => :source_list,
122
- FONT_SRC => :source_list,
123
- FORM_ACTION => :source_list,
124
- FRAME_ANCESTORS => :source_list,
125
- FRAME_SRC => :source_list,
126
- IMG_SRC => :source_list,
127
- MANIFEST_SRC => :source_list,
128
- MEDIA_SRC => :source_list,
129
- OBJECT_SRC => :source_list,
130
- PLUGIN_TYPES => :source_list,
131
- REFLECTED_XSS => :string,
132
- REPORT_URI => :source_list,
133
- SANDBOX => :string,
134
- SCRIPT_SRC => :source_list,
135
- STYLE_SRC => :source_list
119
+ BASE_URI => :source_list,
120
+ BLOCK_ALL_MIXED_CONTENT => :boolean,
121
+ CHILD_SRC => :source_list,
122
+ CONNECT_SRC => :source_list,
123
+ DEFAULT_SRC => :source_list,
124
+ FONT_SRC => :source_list,
125
+ FORM_ACTION => :source_list,
126
+ FRAME_ANCESTORS => :source_list,
127
+ FRAME_SRC => :source_list,
128
+ IMG_SRC => :source_list,
129
+ MANIFEST_SRC => :source_list,
130
+ MEDIA_SRC => :source_list,
131
+ OBJECT_SRC => :source_list,
132
+ PLUGIN_TYPES => :source_list,
133
+ REFLECTED_XSS => :string,
134
+ REPORT_URI => :source_list,
135
+ SANDBOX => :string,
136
+ SCRIPT_SRC => :source_list,
137
+ STYLE_SRC => :source_list,
138
+ UPGRADE_INSECURE_REQUESTS => :boolean
136
139
  }.freeze
137
140
 
138
141
  CONFIG_KEY = :csp
@@ -196,7 +199,7 @@ module SecureHeaders
196
199
  #
197
200
  # raises an error if the original config is OPT_OUT
198
201
  #
199
- # 1. for non-source-list values (report_only, block_all_mixed_content),
202
+ # 1. for non-source-list values (report_only, block_all_mixed_content, upgrade_insecure_requests),
200
203
  # additions will overwrite the original value.
201
204
  # 2. if a value in additions does not exist in the original config, the
202
205
  # default-src value is included to match original behavior.
@@ -3,11 +3,11 @@ if defined?(Rails::Railtie)
3
3
  module SecureHeaders
4
4
  class Railtie < Rails::Railtie
5
5
  isolate_namespace SecureHeaders if defined? isolate_namespace # rails 3.0
6
- conflicting_headers = ['X-Frame-Options', 'X-XSS-Protection', 'X-Content-Type-Options',
6
+ conflicting_headers = ['X-Frame-Options', 'X-XSS-Protection',
7
7
  'X-Permitted-Cross-Domain-Policies', 'X-Download-Options',
8
8
  'X-Content-Type-Options', 'Strict-Transport-Security',
9
9
  'Content-Security-Policy', 'Content-Security-Policy-Report-Only',
10
- 'X-Permitted-Cross-Domain-Policies', 'Public-Key-Pins', 'Public-Key-Pins-Report-Only']
10
+ 'Public-Key-Pins', 'Public-Key-Pins-Report-Only']
11
11
 
12
12
  initializer "secure_headers.middleware" do
13
13
  Rails.application.config.middleware.use SecureHeaders::Middleware
@@ -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.0.0"
4
+ gem.version = "3.0.1"
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.'
@@ -46,6 +46,7 @@ module SecureHeaders
46
46
  frame_ancestors: %w('none'),
47
47
  plugin_types: %w(application/x-shockwave-flash),
48
48
  block_all_mixed_content: true, # see [http://www.w3.org/TR/mixed-content/](http://www.w3.org/TR/mixed-content/)
49
+ upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
49
50
  report_uri: %w(https://example.com/uri-directive)
50
51
  }
51
52
 
@@ -76,6 +77,12 @@ module SecureHeaders
76
77
  end.to raise_error(ContentSecurityPolicyConfigError)
77
78
  end
78
79
 
80
+ it "requires :upgrade_insecure_requests to be a boolean value" do
81
+ expect do
82
+ CSP.validate_config!(default_opts.merge(upgrade_insecure_requests: "steve"))
83
+ end.to raise_error(ContentSecurityPolicyConfigError)
84
+ end
85
+
79
86
  it "requires all source lists to be an array of strings" do
80
87
  expect do
81
88
  CSP.validate_config!(default_src: "steve")
@@ -214,27 +221,33 @@ module SecureHeaders
214
221
 
215
222
  context "browser sniffing" do
216
223
  let (:complex_opts) do
217
- ContentSecurityPolicy::ALL_DIRECTIVES.each_with_object({}) { |directive, hash| hash[directive] = %w('self') }
218
- .merge(block_all_mixed_content: true, reflected_xss: "block")
219
- .merge(script_src: %w('self'), script_nonce: 123456)
224
+ ContentSecurityPolicy::ALL_DIRECTIVES.each_with_object({}) do |directive, hash|
225
+ hash[directive] = %w('self')
226
+ end.merge({
227
+ block_all_mixed_content: true,
228
+ upgrade_insecure_requests: true,
229
+ reflected_xss: "block",
230
+ script_src: %w('self'),
231
+ script_nonce: 123456
232
+ })
220
233
  end
221
234
 
222
235
  it "does not filter any directives for Chrome" do
223
236
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:chrome])
224
- 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'; report-uri 'self'")
237
+ 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'")
225
238
  end
226
239
 
227
240
  it "does not filter any directives for Opera" do
228
241
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:opera])
229
- 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'; report-uri 'self'")
242
+ 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'")
230
243
  end
231
244
 
232
245
  it "filters blocked-all-mixed-content, child-src, and plugin-types for firefox" do
233
246
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox])
234
- 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'; report-uri 'self'")
247
+ 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'")
235
248
  end
236
249
 
237
- it "adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for safari" do
250
+ 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
238
251
  policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:safari6])
239
252
  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'")
240
253
  end
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.0.0
4
+ version: 3.0.1
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-02-18 00:00:00.000000000 Z
11
+ date: 2016-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake