Skip to content

Commit 695943e

Browse files
authored
urllib3: Fix fuzz_requests (#14742)
urllib3's `fuzz_requests` has been broken for over a year because it uses HTTPretty which does not support modern urllib3 gabrielfalcao/HTTPretty#485. In this PR, I'm replacing HTTPretty with a simple server in a separate thread, the approach is borrowed from [a httpx fuzzer](https://github.com/google/oss-fuzz/blob/5b14ead1ed0b85d5a21ce30c993a22d71b415b35/projects/httpx/fuzz_api.py). Also, I'm adding myself as the primary contact for urllib3 because I'm its current lead maintainer.
1 parent 38c53bf commit 695943e

3 files changed

Lines changed: 38 additions & 16 deletions

File tree

projects/urllib3/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
################################################################################
1616

1717
FROM gcr.io/oss-fuzz-base/base-builder-python
18-
RUN pip3 install httpretty
1918

2019
RUN git clone --depth 1 https://github.com/urllib3/urllib3
2120

projects/urllib3/fuzz_requests.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,51 @@
1515
# limitations under the License.
1616

1717
import atheris
18-
import httpretty
18+
import socket
1919
import sys
20+
import threading
21+
import time
2022

2123
import urllib3
2224

2325
# Setup http mocking
24-
GLOBAL_RESPONSE_BODY = ""
26+
GLOBAL_RESPONSE_BODY = b""
2527
GLOBAL_RESPONSE_CODE = 0
26-
GLOBAL_CONTENT_TYPE = ""
27-
28-
def request_callback(request, uri, headers):
29-
headers['Content-Type'] = GLOBAL_CONTENT_TYPE
30-
return [GLOBAL_RESPONSE_CODE, headers, GLOBAL_RESPONSE_BODY]
28+
GLOBAL_CONTENT_TYPE = b""
29+
30+
31+
class ServerThread(threading.Thread):
32+
def __init__(self) -> None:
33+
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
34+
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
35+
self.s.bind(("127.0.0.1", 8001))
36+
self.s.listen(1)
37+
super().__init__()
38+
39+
def run(self) -> None:
40+
global GLOBAL_RESPONSE_CODE, GLOBAL_CONTENT_TYPE, GLOBAL_RESPONSE_BODY
41+
conn, addr = self.s.accept()
42+
conn.recv(1024)
43+
conn.send(
44+
b"HTTP/1.1 %d FOO\r\nContent-Type: %b\r\n\r\n%b"
45+
% (GLOBAL_RESPONSE_CODE, GLOBAL_CONTENT_TYPE, GLOBAL_RESPONSE_BODY)
46+
)
47+
time.sleep(0.005)
48+
conn.close()
49+
self.s.shutdown(1)
50+
self.s.close()
51+
time.sleep(0.01)
3152

32-
httpretty.enable(verbose=True, allow_net_connect=False)
33-
httpretty.register_uri(httpretty.GET, "http://www.test.com", body=request_callback)
34-
httpretty.register_uri(httpretty.POST, "http://www.test.com", body=request_callback)
35-
httpretty.register_uri(httpretty.HEAD, "http://www.test.com", body=request_callback)
36-
httpretty.register_uri(httpretty.PUT, "http://www.test.com", body=request_callback)
3753

3854
REQUEST_METHODS = ["POST", "GET", "HEAD", "PUT"]
3955

4056
def TestOneInput(data):
4157
fdp = atheris.FuzzedDataProvider(data)
4258

4359
global GLOBAL_RESPONSE_BODY, GLOBAL_RESPONSE_CODE, GLOBAL_CONTENT_TYPE
44-
GLOBAL_RESPONSE_BODY = fdp.ConsumeUnicodeNoSurrogates(sys.maxsize)
60+
GLOBAL_RESPONSE_BODY = fdp.ConsumeBytes(sys.maxsize)
4561
GLOBAL_RESPONSE_CODE = fdp.ConsumeIntInRange(200, 599)
46-
GLOBAL_CONTENT_TYPE = fdp.ConsumeString(sys.maxsize)
62+
GLOBAL_CONTENT_TYPE = fdp.ConsumeBytes(sys.maxsize)
4763

4864
requestType = fdp.PickValueInList(REQUEST_METHODS)
4965

@@ -64,9 +80,12 @@ def TestOneInput(data):
6480
timeout = urllib3.util.Timeout(connect=0.1, read=0.1)
6581
urllib_pool = urllib3.poolmanager.PoolManager(timeout=timeout)
6682

83+
t1 = ServerThread()
84+
t1.start()
85+
6786
response = urllib_pool.request(
6887
requestType,
69-
"http://www.test.com",
88+
"http://localhost:8001/",
7089
headers=requestHeaders,
7190
fields=formData
7291
)
@@ -75,6 +94,9 @@ def TestOneInput(data):
7594
response.data
7695
response.headers
7796

97+
t1.join()
98+
99+
78100
def main():
79101
atheris.instrument_all()
80102
atheris.Setup(sys.argv, TestOneInput)

projects/urllib3/project.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ main_repo: https://github.com/urllib3/urllib3
66
sanitizers:
77
- address
88
- undefined
9+
primary_contact: "illia.volochii@gmail.com"
910
vendor_ccs:
1011
- david@adalogics.com
1112
- sean@compactcloud.co.uk

0 commit comments

Comments
 (0)