You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
urllib.request.getproxies() misparses Windows registry proxy settings #86793
If HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer contains the string http=host:123;https=host:456;ftp=host:789, then getproxies_registry() should return
This bug has existed for a very long time (since Python 2.0.1 if not earlier), but it was exposed recently when urllib3 added support for HTTPS-in-HTTPS proxies in version 1.26. Before that, an https prefix on the HTTPS proxy url was silently treated as http, accidentally resulting in the correct behavior.
There are additional bugs in the treatment of single-proxy strings (the case when the string contains no = character).
Below is my attempt at modifying the code from getproxies_registry to approximately match Chromium's behavior. I could turn this into a patch, but I'd like feedback on the corner cases first.
if'='notinproxyServerand';'notinproxyServer:
# Use one setting for all protocols.# Chromium treats this as a separate category, and some software# uses the ALL_PROXY environment variable for a similar purpose,# so arguably this should be 'all={}'.format(proxyServer),# but this is more backward compatible.proxyServer='http={0};https={0};ftp={0}'.format(proxyServer)
forpinproxyServer.split(';'):
# Chromium and WinInet are inconsistent in their treatment of# invalid strings with the wrong number of = characters. It# probably doesn't matter.protocol, addresses=p.split('=', 1)
protocol=protocol.strip()
# Chromium supports more than one proxy per protocol. I don't# know how many clients support the same, but handling it is at# least no worse than leaving the commas uninterpreted.foraddressinaddresses.split(','):
ifprotocolin {'http', 'https', 'ftp', 'socks'}:
# See if address has a type:// prefixifnotre.match('(?:[^/:]+)://', address):
ifprotocol=='socks':
# Chromium notes that the correct protocol here# is SOCKS4, but "socks://" is interpreted# as SOCKS5 elsewhere. I don't know whether# prepending socks4:// here would break code.address='socks://'+addresselse:
address='http://'+address# A string like 'http=foo;http=bar' will produce a# comma-separated list, while previously 'bar' would# override 'foo'. That could potentially break something.ifprotocolnotinproxies:
proxies[protocol] =addresselse:
proxies[protocol] +=','+address
I came across this issue as well.
I checked Microsoft documentations and it seems InternetGetProxyInfo in WinInet is deprecated, while WinHttpGetIEProxyConfigForCurrentUser in WinHTTP will return the exact same string as what it stored registery.
We know Windows reslove: http=host:port;https=host:port;ftp=host:port;socks=host:port
as: http=http://host:port;https=http://host:port;ftp=http://host:port;socks=socks://host:port
means:
Using HTTP type proxy for HTTP, HTTPS and FTP requests, but Socks4/4a type proxy for the other TCP requests.
We notice that socks are different from the others.
Now I want to know what if Windows slove this: http=socks://host:port;ftp=https://host:port;socks=https://host:port
Does it mean using Socks4/4a type proxy for HTTP requests, HTTPS type proxy for FTP requests, and HTTP type proxy for the other TCP requests?
Or just invalid settings?
CrazyBoyFeng commented on Mar 5, 2021
CrazyBoyFengmannequin
Mannequin
More actions
I make some black box tests with the HTTPS proxy.
Set system proxy http=https://host:port and start a HTTPS proxy, then IE, Edge (Chromium) and benrg's code (using urllib3) work fine while fetching http://website. Then I shutdown the HTTPS proxy and start a HTTP proxy on the same port, I get SSLError. That's it.
benrg should add your patch as soon as possible.
Too few people actually use HTTPS proxy. Even if there is a bug with HTTPS proxy, it will not be too late to fix it when it is discovered.
@TTimo From a quick glance, I think it'll deal with part of the second half of that question. It should be able to pick up manually customised proxies, but I don't think it'll get automatically configured ones. And anything that's bypassing urllib here won't get any benefit, naturally.
Activity
benrg commentedon Dec 12, 2020
If
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServercontains the stringhttp=host:123;https=host:456;ftp=host:789, then getproxies_registry() should returnfor consistency with WinInet and Chromium, but it actually returns
This bug has existed for a very long time (since Python 2.0.1 if not earlier), but it was exposed recently when urllib3 added support for HTTPS-in-HTTPS proxies in version 1.26. Before that, an
httpsprefix on the HTTPS proxy url was silently treated ashttp, accidentally resulting in the correct behavior.There are additional bugs in the treatment of single-proxy strings (the case when the string contains no
=character).The Chromium code for parsing the ProxyServer string can be found here: https://source.chromium.org/chromium/chromium/src/+/refs/tags/89.0.4353.1:net/proxy_resolution/proxy_config.cc;l=86
Below is my attempt at modifying the code from
getproxies_registryto approximately match Chromium's behavior. I could turn this into a patch, but I'd like feedback on the corner cases first.kotori commentedon Feb 21, 2021
I came across this issue as well.
I checked Microsoft documentations and it seems
InternetGetProxyInfoin WinInet is deprecated, whileWinHttpGetIEProxyConfigForCurrentUserin WinHTTP will return the exact same string as what it stored registery.https://docs.microsoft.com/en-US/troubleshoot/windows-client/networking/configure-client-proxy-server-settings-by-registry-file
Also from this documentation, a proxy server could have "http://" prefix, so I guess it could also support "https://" prefix if a user set a https proxy.
CrazyBoyFeng commentedon Mar 5, 2021
We know Windows reslove:
http=host:port;https=host:port;ftp=host:port;socks=host:portas:
http=http://host:port;https=http://host:port;ftp=http://host:port;socks=socks://host:portmeans:
Using HTTP type proxy for HTTP, HTTPS and FTP requests, but Socks4/4a type proxy for the other TCP requests.
We notice that socks are different from the others.
Now I want to know what if Windows slove this:
http=socks://host:port;ftp=https://host:port;socks=https://host:portDoes it mean using Socks4/4a type proxy for HTTP requests, HTTPS type proxy for FTP requests, and HTTP type proxy for the other TCP requests?
Or just invalid settings?
CrazyBoyFeng commentedon Mar 5, 2021
I make some black box tests with the HTTPS proxy.
Set system proxy
http=https://host:portand start a HTTPS proxy, then IE, Edge (Chromium) and benrg's code (usingurllib3) work fine while fetchinghttp://website. Then I shutdown the HTTPS proxy and start a HTTP proxy on the same port, I get SSLError. That's it.benrg should add your patch as soon as possible.
Too few people actually use HTTPS proxy. Even if there is a bug with HTTPS proxy, it will not be too late to fix it when it is discovered.
4 remaining items
zooba commentedon Sep 16, 2021
I think the PR is basically ready, unfortunately it's stuck behind a CI issue we only just fixed, and needs to merge from main before it'll clear.
Posting here once CI is green will get attention faster than on GitHub.
CrazyBoyFeng commentedon Nov 20, 2021
Sorry I didn't see this comment before.
Can it be merged now?
SekiBetu commentedon Apr 28, 2022
any updates?
zooba commentedon Apr 28, 2022
I retriggered the CI to see if it passes now.
TTimo commentedon May 10, 2022
Hello,
I am curious if this will also address https://stackoverflow.com/questions/65931275/python-requests-module-does-it-use-system-level-on-windows-proxy-settings or if it's yet another problem?
zooba commentedon May 12, 2022
@TTimo From a quick glance, I think it'll deal with part of the second half of that question. It should be able to pick up manually customised proxies, but I don't think it'll get automatically configured ones. And anything that's bypassing urllib here won't get any benefit, naturally.
Implement workaround for python/cpython#86793
[core] Workaround erroneous urllib Windows proxy parsing (#7092)
[core] Workaround erroneous urllib Windows proxy parsing (yt-dlp#7092)