Skip to content

Don't upgrade insecure requests when the page is served over HTTP #348

Description

@guiprav

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.
  2. I browse http://localhost while developing.
  3. 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
[...]

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions