How to preserve referrer (Referer HTTP header) across subdomains? - cross-domain

I have a website running on www.example.com that makes GET requests to api.example.com to process a form. When I examine web server logs for api.example.com I see that requests from Safari get the full referer (e.g., www.example.com/page-where-request-originated). But requests from Chrome only get a partial referer (www.example.com).
I need the ability to track the full referring page when the request hits api.example.com. Reviewing the documentation for Referrer-Policy it seems my only option is to set it to unsafe-url. But that seems overkill because I only want the referrer to be sent for subdomains of example.com. Is that possible?

The only option I can find is strict-origin : Send the origin as referrer, but only when the request is no downgrade from https to http.
see: https://wiki.crashtest-security.com/enable-security-headers
Everything else will either omit the referrer completely or send the origin URL without any URL parameters.

Related

Why does RFC 6797 forbid sending of the Strict-Transport-Security header over plain HTTP responses?

When reading the spec for HSTS (Strict-Transport-Security), I see an injunction in section 7.2 against sending the header when accessed over http instead of https:
An HSTS Host MUST NOT include the STS header field in HTTP responses
conveyed over non-secure transport.
Why is this? What are the risks if this is violated?
The danger is to the availability of the website itself. If the website is able to respond (either now or in the future) over HTTP but not over HTTPS, it will semi-permanently prevent browsers from accessing the site:
Browser: "I want http://example.com"
ExampleCom: "You should go to the https:// URL now and for the next 3 months!"
Browser: "I want https://example.com"
ExampleCom: [nothing]
By only serving the STS header over HTTPS connections, the site guarantees that at least right now it is not pointing browsers to an inaccessible site. Of course, if the max-age is set to 3 months and the HTTPS site breaks tomorrow, the effect is the same. This is merely an incremental protection.
If your server cannot positively tell from request characteristics whether it is being accessed over HTTP vs. HTTPS, but you believe you have set up your website to only be accessible over HTTPS anyhow (e.g. due to SSL/TLS termination in an nginx proxy), it should be safe to serve the header all the time. But if you want to serve both, e.g. if you wish to serve HTTP->HTTPS redirects from your server, find out how your proxy tells you about the connection and start gating the STS header response on that.
(Thanks to Deirdre Connolly for this explanation!)
Not sure if you have a specific issue you are trying to solve, or are only asking for curiosity sake but this might be better asked on http://security.stackexchange.com
Like you I can't see the threat from the server sending this over HTTP. It doesn't really make sense, but I'm not sure if there is a risk to be honest. Except to say if you can't set up the header properly then perhaps you're not ready to implement HSTS as it can be dangerous if misconfigured!
The far bigger danger is if a browser was to process a HSTS header received over HTTP, which section 8.1 explicitly states it MUST ignore:
If an HTTP response is received over insecure transport, the UA MUST
ignore any present STS header field(s).
The risk here is that a malicious attacker (or an accidentally misconfigured header) could take a HTTP-only website offline (or the HTTP-only parts of a mixed site) if a browser incorrectly processed it. This would effectively cause a DoS for that user(s) until either the header expiries or the site implements HTTPS.
Additionally if a browser did accept this header over HTTP rather than HTTPS, it could be possible for a MITM attacker to expire the header by setting it to a max-age of 0. For example if you have a long HSTS header set on https://www.example.com but attacker was able to publish a max-age=0 header with includeSubDomain over http://example.com, and the browser incorrectly processed that, then it could effectively remove the protection HTTPS gives to your www site.
For these reasons it's very important that clients (i.e. webbrowsers) implement this correctly and ignore the HSTS header if served over HTTP and only process it over HTTPS. This could be another reason the RFC states servers must not send this over HTTP - just in case a browser implements this wrong but, to be honest, if that happens then that browser is putting all HTTP only websites at risk as a MITM attacker could add it as per above.

How to prevent HSTS?

I have a sdk and want to support both http and https, but browsers always force to https. I know that is good feature of browser but many websites using http could not use my sdk.
Does anyone know how I can prevent HSTS or a solution for this?
HSTS is activated only when the concerned website ask for it (or when the user add the website manually to his browser). So if HSTS is enable, it's because the website support https (HSTS header is only valid when set on a secure https response).
If the website doesn't provide http you can't force it. (and when using HSTS, all http request bypassing HSTS will probably get a redirect to https as an answer)
Note that if the HSTS header have the 'includeSubdomains' options, it will force https for all subdomains, even if they don't support https.
Last point : HSTS (and HTTPS) is a security feature, it's probably a bad idea to try disable it.

Disable Serving from Default Cloudfront Hostname (ourdistid.cloudfront.net)

I've setup an alternate domain name for our Cloudfront distribution so we can serve from oursite.com. We'd like to disable ourdistid.cloudfront.net so our site is only accessible from one hostname. Is this possible?
Yes, you can do this, though perhaps not in the place where you might expect to.
By default, CloudFront sets the Host: header in the request sent to the origin server to have the value of the origin server hostname.
However, you can configure CloudFront to forward the original request's host header to the origin server, instead. It doesn't change how the request is routed, only the header that gets forwarded.
After that, it is a simple matter to configure your web server to return the response you want, when the request's Host: header matches the *.cloudfront.net host, which can include a generic error page with whatever code you seem most appropriate, such as 503 Service Unavailable, 404 Not Found, 403 Forbidden, or 410 Gone. You could even use 301 Moved Permanently. Whatever makes the most sense to you.
You can't literally disable the assigned endpoint, but you can prevent it from returning any of your content.
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html

Enabling HSTS without forcibly redirecting to HTTPS?

This seems like a silly question but I am wondering:
How is HSTS deployed without forcibly redirecting users to HTTPS?
How is HTTP content still served from the same domain as one using HSTS? (Either an entire site or mixed content)
Why would anyone do this?
I'm reading from the EFF site and it appears that that was done:
We recently enabled HSTS for eff.org. It took less than an hour to set up, and we found a way to do it without forcibly redirecting users to HTTPS, so we can state an unequivocal preference for HTTPS access while still making the site available in HTTP. It worked like a charm and a significant fraction of our users are now automatically accessing our site in HTTPS, perhaps without even knowing it.
As I'm aware, HSTS works by sending an HTTP header:
Strict-Transport-Security: max-age=31536000
So if I access a page on https://example.net/ that sends that header, all future requests to the domain example.net for the next 31536000 seconds will use HTTPS, and if the (response?) is HTTP then the browser will show giant red warnings.
Can someone please clarify this for me? Is my understanding of HSTS accurate or am I missing something?
HSTS headers should only be issued over HTTPS and only enforced by a User Agent if they are received over HTTPS. A User Agent should disregard the HSTS header sent over HTTP as an attacker could have maliciously injected it.
This means the site can continue to serve over HTTP and the user can continue browsing over HTTP at their choice. However, if they manually insert https:// into the address bar, they will receive the HSTS header and the User Agent will then treat it as a HSTS host.
This is a good way of progressively introducing enforced HTTPS traffic without forcing it all there on day one. As users become aware of the secure option the HTTPS traffic will increase and remain thanks to HSTS. Perhaps the EFF is introducing it gradually and may just flick the big 'HTTPS Switch' one day once they are satisfied they can accommodate it.

Is HTTP header Referer sent when going to a http page from a https page?

After a few tests, I'm starting to reach the conclusion that a browser does not send a Referer HTTP header when one clicks to a http page from a https one.
What security reason is that for? Is is defined somewhere in the standard?
The HTTP RFC states, in section 15.1.3 Encoding Sensitive Information in URI's :
Clients SHOULD NOT include a Referer
header field in a (non-secure) HTTP
request if the referring page was
transferred with a secure protocol.
So, this is expected / standard behaviour.
Actually it's not that straight forward anymore (2014 onwards), according to this w3c document on referrer policy.
The default behaviour is that browsers will not send referrer information when going from HTTPS to HTTP. However, browsers will send referrer when going from HTTPS to HTTPS.
Also, in HTML5, there is a new meta tag named referrer, that looks like this:
<meta name="referrer" content="origin">
New browsers have already implemented this. So whether or not browsers will send referrer, will depend on this meta tag in the near future. If this meta tag is not included in page's HTML, then browsers will use the default behaviour.
Following are the possible values of content attribute of referrer meta tag:
no-referrer: Referrer will not be sent, regardless of HTTP or HTTPS
origin: Only the origin (main) domain will be sent as referrer
origin-when-crossorigin: Same origin will send full referrer URL and cross origin will send only origin URL as referrer
no-referrer-when-downgrade: This is the default behaviour when no referrer meta tag is provided on the page.
unsafe-url: This will always send referrer, regardless of HTTP or HTTPS
Also, there are some legacy attribute values for referrer meta tag. These are no longer recommended, but used in many sites at the moment:
never: same as no-referrer
default: same as no-referrer-when-downgrade
always: same as unsafe-url
I hope this information will be helpful to someone who just found this post after 2014.
Yes, defined in the standard:
Clients SHOULD NOT include a Referer
header field in a (non-secure) HTTP
request if the referring page was
transferred with a secure protocol
Reason: Sometimes SessionIDs are URL encoded. HTTP Pages can have cross site scripting which steals the session from the HTTPS communication. To prevent this, the referrer is not transmitted on the HTTPS to HTTP transition so that the URL encoded sessin ID can't be stolen.

Resources