Skip to content

Commit 6c02a63

Browse files
committed
Merge pull request #193 from twitter/calling-name-on-nil-value
Fix issue with opting out of headers when using header_hash method
2 parents 170271f + 64908d5 commit 6c02a63

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

lib/secure_headers.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,23 @@ def append_features(base)
5252

5353
def header_hash(options = nil)
5454
ALL_HEADER_CLASSES.inject({}) do |memo, klass|
55-
config = if options.is_a?(Hash) && options[klass::Constants::CONFIG_KEY]
55+
# must use !options[key].nil? because 'false' represents opting out, nil
56+
# represents use global default.
57+
config = if options.is_a?(Hash) && !options[klass::Constants::CONFIG_KEY].nil?
5658
options[klass::Constants::CONFIG_KEY]
5759
else
5860
::SecureHeaders::Configuration.send(klass::Constants::CONFIG_KEY)
5961
end
6062

6163
unless klass == SecureHeaders::PublicKeyPins && !config.is_a?(Hash)
62-
header = get_a_header(klass::Constants::CONFIG_KEY, klass, config)
63-
memo[header.name] = header.value
64+
header = get_a_header(klass, config)
65+
memo[header.name] = header.value if header
6466
end
6567
memo
6668
end
6769
end
6870

69-
def get_a_header(name, klass, options)
71+
def get_a_header(klass, options)
7072
return if options == false
7173
klass.new(options)
7274
end
@@ -210,7 +212,7 @@ def secure_header_options_for(type, options)
210212
def set_a_header(name, klass, options=nil)
211213
options = secure_header_options_for(name, options)
212214
return if options == false
213-
set_header(SecureHeaders::get_a_header(name, klass, options))
215+
set_header(SecureHeaders::get_a_header(klass, options))
214216
end
215217

216218
def set_header(name_or_header, value=nil)

spec/lib/secure_headers_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
let(:request) {double(:ssl? => true, :url => 'https://example.com')}
99

1010
before(:each) do
11+
reset_config
1112
stub_user_agent(nil)
1213
allow(headers).to receive(:[])
1314
allow(subject).to receive(:response).and_return(response)
@@ -171,6 +172,23 @@ def expect_default_values(hash)
171172
expect_default_values(hash)
172173
end
173174

175+
it "allows opting out" do
176+
hash = SecureHeaders::header_hash(:csp => false, :hpkp => false)
177+
expect(hash['Content-Security-Policy-Report-Only']).to be_nil
178+
expect(hash['Content-Security-Policy']).to be_nil
179+
end
180+
181+
it "allows opting out with config" do
182+
::SecureHeaders::Configuration.configure do |config|
183+
config.hsts = false
184+
config.csp = false
185+
end
186+
187+
hash = SecureHeaders::header_hash
188+
expect(hash['Content-Security-Policy-Report-Only']).to be_nil
189+
expect(hash['Content-Security-Policy']).to be_nil
190+
end
191+
174192
it "produces a hash with a mix of config values, override values, and default values" do
175193
::SecureHeaders::Configuration.configure do |config|
176194
config.hsts = { :max_age => '123456'}

0 commit comments

Comments
 (0)