Skip to content

Commit c09b6de

Browse files
committed
Merge pull request #246 from twitter/hpkp-warn
Warn if HPKP report host is the same as the current host
2 parents d3aac03 + 681c8af commit c09b6de

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,7 @@ config.hpkp = {
332332
{sha256: '73a2c64f9545172c1195efb6616ca5f7afd1df6f245407cafb90de3998a1c97f'}
333333
],
334334
report_only: true, # defaults to false (report-only mode)
335-
report_uri: 'https://report-uri.io/example-hpkp',
336-
app_name: 'example',
337-
tag_report_uri: true
335+
report_uri: 'https://report-uri.io/example-hpkp'
338336
}
339337
```
340338

lib/secure_headers/configuration.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def add_configuration(name, config)
6161
config.validate_config!
6262
@configurations ||= {}
6363
config.send(:cache_headers!)
64+
config.send(:cache_hpkp_report_host)
6465
config.freeze
6566
@configurations[name] = config
6667
end
@@ -102,11 +103,13 @@ def deep_copy_if_hash(value)
102103
end
103104
end
104105

106+
attr_accessor :dynamic_csp
107+
105108
attr_writer :hsts, :x_frame_options, :x_content_type_options,
106109
:x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies,
107-
:hpkp, :dynamic_csp, :cookies, :referrer_policy
110+
:referrer_policy
108111

109-
attr_reader :cached_headers, :csp, :dynamic_csp, :cookies
112+
attr_reader :cached_headers, :csp, :cookies, :hpkp, :hpkp_report_host
110113

111114
HASH_CONFIG_FILE = ENV["secure_headers_generated_hashes_file"] || "config/secure_headers_generated_hashes.yml"
112115
if File.exists?(HASH_CONFIG_FILE)
@@ -139,6 +142,7 @@ def dup
139142
copy.x_permitted_cross_domain_policies = @x_permitted_cross_domain_policies
140143
copy.referrer_policy = @referrer_policy
141144
copy.hpkp = @hpkp
145+
copy.hpkp_report_host = @hpkp_report_host
142146
copy
143147
end
144148

@@ -202,12 +206,32 @@ def csp=(new_csp)
202206
@csp = new_csp
203207
end
204208

209+
def cookies=(cookies)
210+
@cookies = cookies
211+
end
212+
205213
def cached_headers=(headers)
206214
@cached_headers = headers
207215
end
208216

217+
def hpkp=(hpkp)
218+
@hpkp = hpkp
219+
end
220+
221+
def hpkp_report_host=(hpkp_report_host)
222+
@hpkp_report_host = hpkp_report_host
223+
end
224+
209225
private
210226

227+
def cache_hpkp_report_host
228+
has_report_uri = @hpkp && @hpkp != OPT_OUT && @hpkp[:report_uri]
229+
self.hpkp_report_host = if has_report_uri
230+
parsed_report_uri = URI.parse(@hpkp[:report_uri])
231+
parsed_report_uri.host
232+
end
233+
end
234+
211235
# Public: Precompute the header names and values for this configuraiton.
212236
# Ensures that headers generated at configure time, not on demand.
213237
#

lib/secure_headers/middleware.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module SecureHeaders
22
class Middleware
3+
HPKP_SAME_HOST_WARNING = "[WARNING] HPKP report host should not be the same as the request host. See https://github.com/twitter/secureheaders/issues/166"
4+
35
def initialize(app)
46
@app = app
57
end
@@ -10,6 +12,10 @@ def call(env)
1012
status, headers, response = @app.call(env)
1113

1214
config = SecureHeaders.config_for(req)
15+
if config.hpkp_report_host == req.host
16+
Kernel.warn(HPKP_SAME_HOST_WARNING)
17+
end
18+
1319
flag_cookies!(headers, override_secure(env, config.cookies)) if config.cookies
1420
headers.merge!(SecureHeaders.header_hash_for(req))
1521
[status, headers, response]

spec/lib/secure_headers/middleware_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ module SecureHeaders
1313
Configuration.default
1414
end
1515

16+
it "warns if the hpkp report-uri host is the same as the current host" do
17+
report_host = "report-uri.io"
18+
Configuration.default do |config|
19+
config.hpkp = {
20+
max_age: 10000000,
21+
pins: [
22+
{sha256: 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'},
23+
{sha256: '73a2c64f9545172c1195efb6616ca5f7afd1df6f245407cafb90de3998a1c97f'}
24+
],
25+
report_uri: "https://#{report_host}/example-hpkp"
26+
}
27+
end
28+
29+
expect(Kernel).to receive(:warn).with(Middleware::HPKP_SAME_HOST_WARNING)
30+
31+
middleware.call(Rack::MockRequest.env_for("https://#{report_host}", {}))
32+
end
33+
1634
it "sets the headers" do
1735
_, env = middleware.call(Rack::MockRequest.env_for("https://looocalhost", {}))
1836
expect_default_values(env)

0 commit comments

Comments
 (0)