-
-
Notifications
You must be signed in to change notification settings - Fork 862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Skip HSTS preloading for single-label domains #1025
Comments
Yup, small standalone script to reproduce: import asyncio
import httpx
async def app(scope, receive, send):
await send({"type": "http.response.start", "status": 200})
await send({"type": "http.response.body", "body": b"Hello, world!"})
async def main():
async with httpx.AsyncClient(app=app) as client:
r = await client.get("http://app")
assert r.request.url == "https://app"
asyncio.run(main()) The meat of it being that: >>> import hstspreload
>>> hstspreload.in_hsts_preload("app")
True Note that as per #896 |
Removing the Maybe |
@florimondmanca It looks like a bug to me because that rewrite was totally unexpected. As name |
Not saying this is not buggy, but I'm not sure it'd be us that should do something, or whether Should we perhaps reach out over https://github.com/sethmlarson/hstspreload about this? …Actually I might directly cc @sethmlarson if he's got a quick insight about whether this is expected. :-) |
HSTS preloading rules don't require an additional label when You can tell that browsers (in my case Firefox) have something going on with single-label domain names triggering HSTS as well. If you type this in your URL bar:
But you're right there's definitely a "usability" issue here when it comes to things like Docker networks. Excluding single-label domain names from HSTS preload checking almost certainly isn't a security issue as under all normal circumstances they wouldn't resolve to anything on their own. I don't think this is an issue with the |
Thanks for the clarifications @sethmlarson :) So I think we can proceed with flagging this as a bug, and the fix is most likely to be to skip HSTS preloading for single-label hostnames (making sure we skip the case of an IP):
|
Is there someone tackling this? If not, I would be happy to work on it 🙂 I was thinking of checking if there was at least one dot in the hostname, but it sounds a bit naive to me. I'm open for better suggestions 🙂 |
I think this kind of issue should make us reconsider whether enforcing HSTS from a server-side client is a sensible thing to do at all. @tomchristie and I chatted privately about this today. From a UX perspective it can lead to ambiguous behaviors (#896) and cases when you really don't want HSTS preload to kick in (like in this case). Some options are: make HSTS preload opt-in, make it opt-out, drop it entirely (?). But in the meantime, while this discussion is being held, I guess it's still valuable to have a fix in master for this? The way I'd have gone about it is to check how many parts the hostname contains, yes. There might be a util in urllib to do this, otherwise let's just |
Ok, it sounds also to me that HSTS is quite heavy for a server-side client (from my experience, I always make sure to use the HTTPS URL if available). Anyway, I'll make this simple fix with a dedicated unit test that'll be easy to remove if needed. |
Closed via #1074 |
Checklist
master
.Describe the bug
I run two services in docker-compose. One of them named "app" which is Django application.
During startup, another service makes HTTP call to "app" service:
GET http://app:8000
The request then fails with
ConnectionReset
error because it was rewritten to HTTPS.I dug into the issue and found that
httpx._client.BaseClient.merge_url
checks againsthstspreload.in_hsts_preload
and, if succeeds, replaces http with https.Inside of
hstspreload.in_hsts_preload
I found_GTLD_INCLUDE_SUBDOMAINS
constant that includesapp
value and the check I have mentioned before is always True.This means, that any request to any host that is listed in
_GTLD_INCLUDE_SUBDOMAINS
will be rewritten to HTTPS.To reproduce
Dockerfile, docker-compose.yml:
https://gist.github.com/alex-oleshkevich/6695124d41208c5dc692a30ea817ea82
Expected behavior
The scheme should not be rewritten.
Actual behavior
URL
http://app:8000
was changed tohttps://app:8000
by httpx.Debugging material
Environment
Additional context
The text was updated successfully, but these errors were encountered: