Skip to content

Commit c293283

Browse files
committed
Merge pull request #212 from twitter/optionally-strip-protocols
Add CSP config flag to preserve host source schemes
2 parents 44c8c3e + 977c5d6 commit c293283

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The gem will automatically apply several headers that are related to security.
2525

2626
If you do not supply a `default` configuration, exceptions will be raised. If you would like to use a default configuration (which is fairly locked down), just call `SecureHeaders::Configuration.default` without any arguments or block.
2727

28-
All `nil` values will fallback to their default value. `SecureHeaders::OPT_OUT` will disable the header entirely.
28+
All `nil` values will fallback to their default values. `SecureHeaders::OPT_OUT` will disable the header entirely.
2929

3030
```ruby
3131
SecureHeaders::Configuration.default do |config|
@@ -36,8 +36,12 @@ SecureHeaders::Configuration.default do |config|
3636
config.x_download_options = "noopen"
3737
config.x_permitted_cross_domain_policies = "none"
3838
config.csp = {
39+
# "meta" values. these will shaped the header, but the values are not included in the header.
40+
report_only: true, # default: false
41+
preserve_schemes: true # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
42+
43+
# directive values: these values will directly translate into source directives
3944
default_src: %w(https: 'self'),
40-
report_only: false,
4145
frame_src: %w('self' *.twimg.com itunes.apple.com),
4246
connect_src: %w(wws:),
4347
font_src: %w('self' data:),

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ def initialize(config = nil, user_agent = OTHER)
280280
else
281281
UserAgent.parse(user_agent)
282282
end
283-
@report_only = !!@config[:report_only]
283+
@report_only = @config[:report_only]
284+
@preserve_schemes = @config[:preserve_schemes]
284285
@script_nonce = @config[:script_nonce]
285286
@style_nonce = @config[:style_nonce]
286287
end
@@ -350,9 +351,12 @@ def build_directive(directive_name)
350351
source_list.reject! { |value| value == NONE } if source_list.length > 1
351352

352353
# remove schemes and dedup source expressions
353-
source_list = strip_source_schemes(source_list) unless directive_name == REPORT_URI
354+
unless directive_name == REPORT_URI || @preserve_schemes
355+
source_list = strip_source_schemes(source_list)
356+
end
354357
dedup_source_list(source_list).join(" ")
355358
end
359+
356360
[symbol_to_hyphen_case(directive_name), value].join(" ")
357361
end
358362

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ module SecureHeaders
151151
expect(csp.value).to eq("default-src https:; report-uri https://example.org")
152152
end
153153

154+
it "does not remove schemes when :preserve_schemes is true" do
155+
csp = ContentSecurityPolicy.new(default_src: %w(https://example.org), :preserve_schemes => true)
156+
expect(csp.value).to eq("default-src https://example.org")
157+
end
158+
154159
it "removes nil from source lists" do
155160
csp = ContentSecurityPolicy.new(default_src: ["https://example.org", nil])
156161
expect(csp.value).to eq("default-src example.org")

0 commit comments

Comments
 (0)