Commit 19de22b
authored
Don't set upgrade-insecure-requests directive for HTTP requests (#570)
## Plan to fix upgrade_insecure_requests for HTTP requests
- [x] Understand the current implementation and test structure
- [x] Modify `header_hash_for` method in `lib/secure_headers.rb` to
remove `upgrade_insecure_requests` from CSP when request is HTTP
- [x] Add tests to verify `upgrade_insecure_requests` is removed for
HTTP requests
- [x] Add tests to verify `upgrade_insecure_requests` is preserved for
HTTPS requests
- [x] Run existing tests to ensure no regressions (251 tests pass)
- [x] Fix linting issues (rubocop clean)
- [x] Refactor to extract helper method and reduce code duplication
- [x] Request code review (no issues found)
- [x] Run security scanner (no alerts)
- [x] Revert .gitignore changes per review feedback
## Summary
This PR fixes issue where `upgrade_insecure_requests` was set even for
HTTP requests, breaking local development. The fix follows the same
pattern as HSTS - the directive is now only included when serving over
HTTPS.
### Security Summary
No security vulnerabilities detected by CodeQL scanner.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Don't upgrade insecure requests when the page is served
over HTTP</issue_title>
> <issue_description>I want to set `upgrade_insecure_requests` only if
the page is requested over HTTPS, because I don't use HTTPS when
developing on localhost (i.e. when developing, I browse
http://localhost, not https://localhost).
>
> Right now if I set `upgrade_insecure_requests`, I can't develop
locally since all internal resource requests are upgraded, and since my
local server doesn't support HTTPS, they fail.
>
> I think this should be a fairly typical scenario. Would this be
considered a bug, or is there a work-around for it?
>
> ### Relevant software versions
>
> * rack 1.6
> * secure_headers 3.6.7
>
> ### Expected outcome
>
> 1. I configure CSP to `upgrade_insecure_requests`.
> 1. I browse http://localhost while developing.
> 1. `upgrade_insecure_requests` header shouldn't be set, since it's
pointless as the webpage itself is being insecurely served.
>
> ### Actual outcome
>
> 1. `upgrade_insecure_requests` header is set and all internal
resources are broken.
>
> ### Config
>
> ```
> SecureHeaders::Configuration.default do |config|
> config.cookies = {
> secure: true,
> httponly: true,
> samesite: {
> lax: true
> }
> }
> # Add "; preload" and submit the site to hstspreload.org for best
protection.
> config.hsts = "max-age=#{20.years.to_i}; includeSubdomains"
> config.x_frame_options = "DENY"
> config.x_content_type_options = "nosniff"
> config.x_xss_protection = "1; mode=block"
> config.x_download_options = "noopen"
> config.x_permitted_cross_domain_policies = "none"
> config.referrer_policy = "same-origin"
> config.clear_site_data = [
> "cache",
> "cookies",
> "storage",
> "executionContexts"
> ]
> config.csp = {
> # "meta" values. these will shaped the header, but the values are not
included in the header.
> # report_only: true, # default: false [DEPRECATED from 3.5.0: instead,
configure csp_report_only]
> preserve_schemes: true, # default: false. Schemes are removed from
host sources to save bytes and discourage mixed content.
>
> # directive values: these values will directly translate into source
directives
> default_src: %w('self'),
> base_uri: %w('self'),
> #block_all_mixed_content: true, # see
http://www.w3.org/TR/mixed-content/
> child_src: %w('self'), # if child-src isn't supported, the value for
frame-src will be set.
> connect_src: %w(),
> font_src: %w('self'),
> form_action: %w('self'),
> frame_ancestors: %w('none'),
> img_src: %w('self' *),
> manifest_src: %w('self'),
> media_src: %w('self'),
> object_src: %w('self'),
> plugin_types: %w(),
> script_src: %w('self' 'unsafe-inline' maps.googleapis.com),
> style_src: %w('self' 'unsafe-inline'),
> upgrade_insecure_requests: true, # see
https://www.w3.org/TR/upgrade-insecure-requests/
> }
> end
> ```
>
> ### Generated headers
>
> ```
> [...]
> Content-Security-Policy:default-src 'self'; base-uri 'self'; child-src
'self'; font-src 'self'; form-action 'self'; frame-ancestors 'none';
img-src *; manifest-src 'self'; media-src 'self'; object-src 'self';
script-src 'self' 'unsafe-inline' maps.googleapis.com; style-src 'self'
'unsafe-inline'; upgrade-insecure-requests
> [...]
> ```
> </issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #348
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/github/secure_headers/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.2 files changed
+85
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
| 136 | + | |
136 | 137 | | |
137 | 138 | | |
138 | 139 | | |
| |||
146 | 147 | | |
147 | 148 | | |
148 | 149 | | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
149 | 155 | | |
150 | 156 | | |
151 | 157 | | |
| |||
242 | 248 | | |
243 | 249 | | |
244 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
245 | 268 | | |
246 | 269 | | |
247 | 270 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
436 | 436 | | |
437 | 437 | | |
438 | 438 | | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
439 | 501 | | |
440 | 502 | | |
441 | 503 | | |
| |||
0 commit comments