badtests
A malicious HTTP response server for testing how different clients handle broken, malformed, and abusive HTTP responses. The goal is to compare how curl, Python HTTP libraries (urllib, http.client, requests, aiohttp), and web browsers react to protocol violations, edge cases, and deliberately hostile payloads.
What it does
badtests.py is a single-file HTTP server with 81 test endpoints. Each one returns a deliberately broken or abusive response targeting a specific aspect of HTTP handling. Categories include:
- Content-Length violations (words, negatives, floats, NaN, mismatches)
- Content-Type abuse (garbage, null bytes, emoji MIME types, CRLF injection)
- Invalid status codes (negative, zero, five-digit, non-numeric)
- Header abuse (64KB names, 1MB values, 1000 headers, duplicate Content-Length, null bytes)
- Body abuse (infinite streams, missing bodies, binary as text/html)
- Transfer-Encoding smuggling (CL+TE conflicts, invalid chunk sizes)
- Protocol violations (raw garbage, empty responses, unknown HTTP versions)
- Encoding mismatches (UTF-16 body with UTF-8 header, fake gzip)
- Redirect abuse (self-loops, garbage URLs, infinite unique chains)
- Timing attacks (slowloris headers, slow-drip bodies)
- HTML edge cases (UTF-16LE pages, 1000-char titles, meta refresh loops)
- Terminal abuse (ANSI escape code injection)
- JavaScript browser attacks (alert loops, fork bombs, GPU killers, audio hell, tab bombs, clipboard hijack, cookie bombs, download spam, popup storms, ServiceWorker hijack)
- Image/file abuse (bait-and-switch, SVG XSS, GIF/JS polyglots)
- Network abuse (gzip bombs, SSE floods, MIME sniffing, cache poisoning, HSTS bombs)
The server also includes a /logs page that records every request with full headers, and a /fingerprint page for browser fingerprinting.
Running it
Start the server:
python3 badtests.py
It listens on port 60666. Open http://localhost:60666/ in a browser to see the full index of tests, or hit endpoints directly with curl.
Testing
test.sh runs every endpoint through curl and captures the output:
./test.sh localhost:60666
test.py runs every endpoint through urllib, http.client, requests, and aiohttp:
python3 test.py
Both scripts have timeouts and output caps to prevent hanging on infinite streams.
Results
- RESULTS.md - Full writeup comparing how each client handled every test
- results_curl.txt - Raw curl test output
- results_python.txt - Raw Python library test output
Files
| File | Description |
|---|---|
badtests.py |
The server. Single file, no dependencies beyond Python 3 stdlib. |
test.sh |
Bash script to test all endpoints with curl. |
test.py |
Python script to test all endpoints with urllib, http.client, requests, aiohttp. |
RESULTS.md |
Detailed results and analysis of client behavior differences. |
results_curl.txt |
Raw curl output from test.sh. |
results_python.txt |
Raw output from test.py. |