Skip to content

Commit 10b3074

Browse files
committed
Warn if HPKP report host is the same as the current host
1 parent e1321c5 commit 10b3074

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,7 @@ config.hpkp = {
330330
{sha256: '73a2c64f9545172c1195efb6616ca5f7afd1df6f245407cafb90de3998a1c97f'}
331331
],
332332
report_only: true, # defaults to false (report-only mode)
333-
report_uri: 'https://report-uri.io/example-hpkp',
334-
app_name: 'example',
335-
tag_report_uri: true
333+
report_uri: 'https://report-uri.io/example-hpkp'
336334
}
337335
```
338336

lib/secure_headers/configuration.rb

Lines changed: 26 additions & 3 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,12 @@ 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,
106-
:x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies,
107-
:hpkp, :dynamic_csp, :cookies
109+
:x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies
108110

109-
attr_reader :cached_headers, :csp, :dynamic_csp, :cookies
111+
attr_reader :cached_headers, :csp, :cookies, :hpkp, :hpkp_report_host
110112

111113
HASH_CONFIG_FILE = ENV["secure_headers_generated_hashes_file"] || "config/secure_headers_generated_hashes.yml"
112114
if File.exists?(HASH_CONFIG_FILE)
@@ -137,6 +139,7 @@ def dup
137139
copy.x_download_options = @x_download_options
138140
copy.x_permitted_cross_domain_policies = @x_permitted_cross_domain_policies
139141
copy.hpkp = @hpkp
142+
copy.hpkp_report_host = @hpkp_report_host
140143
copy
141144
end
142145

@@ -199,12 +202,32 @@ def csp=(new_csp)
199202
@csp = new_csp
200203
end
201204

205+
def cookies=(cookies)
206+
@cookies = cookies
207+
end
208+
202209
def cached_headers=(headers)
203210
@cached_headers = headers
204211
end
205212

213+
def hpkp=(hpkp)
214+
@hpkp = hpkp
215+
end
216+
217+
def hpkp_report_host=(hpkp_report_host)
218+
@hpkp_report_host = hpkp_report_host
219+
end
220+
206221
private
207222

223+
def cache_hpkp_report_host
224+
has_report_uri = @hpkp && @hpkp != OPT_OUT && @hpkp[:report_uri]
225+
self.hpkp_report_host = if has_report_uri
226+
parsed_report_uri = URI.parse(@hpkp[:report_uri])
227+
parsed_report_uri.host
228+
end
229+
end
230+
208231
# Public: Precompute the header names and values for this configuraiton.
209232
# Ensures that headers generated at configure time, not on demand.
210233
#

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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@ 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+
Configuration.default do |config|
18+
config.hpkp = {
19+
max_age: 10000000,
20+
pins: [
21+
{sha256: 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'},
22+
{sha256: '73a2c64f9545172c1195efb6616ca5f7afd1df6f245407cafb90de3998a1c97f'}
23+
],
24+
report_uri: 'https://report-uri.io/example-hpkp'
25+
}
26+
end
27+
28+
expect(Kernel).to receive(:warn).with(Middleware::HPKP_SAME_HOST_WARNING)
29+
30+
middleware.call(Rack::MockRequest.env_for("https://report-uri.io", {}))
31+
end
32+
1633
it "sets the headers" do
1734
_, env = middleware.call(Rack::MockRequest.env_for("https://looocalhost", {}))
1835
expect_default_values(env)

0 commit comments

Comments
 (0)