http-terminator is a research pipeline from PortSwigger that points a large language model at HTTP specifications and asks it to find request-smuggling attacks. It was published alongside the research it produced, as a reference companion rather than a product.

I read the current repository rather than the write-ups about it. What’s there is a four-stage pipeline: two stages are self-contained, and two need Burp, the last of them also a simulator the repository doesn’t ship.
Advertisement
At a check on 27 September, the public main branch contained one commit, 874682c, dated 22 July 2026.
The ground this sits on
A 2017 post here on Microsoft’s Azure web application firewall mentions request smuggling among the attacks a WAF blocks, but doesn’t explain it, so it’s worth a sentence. Request smuggling – also called desync – exploits a disagreement between two servers about where one HTTP request ends and the next begins.
Put a front-end proxy in front of a back-end server and send a request the two parse differently, and the back-end can treat part of your input as the start of another request. In one variant, response poisoning, the next user’s request on that reused back-end connection completes your smuggled prefix, and that user receives the response to your request instead of their own. PortSwigger researcher James Kettle has published techniques and research on it.
From specifications to test cases
PortSwigger’s own HTTP Request Smuggler tests targets from Burp Suite and includes a research mode for exploring new desync techniques. http-terminator takes a document-driven approach: Claude extracts candidate vectors from specifications, which feed generation, validation and investigation stages.
The four stages
The pipeline runs in four stages:
- seeker (Python) reads documents and RFCs and, through Claude, extracts candidate desync vectors.
- flamer (Java) turns those vectors into malformed HTTP test-cases.
- validator, a Burp extension, fires the generated requests at a target and reports confirmed desync findings and unconfirmed anomalies.
- investigator (Python, driven by Claude Code) replicates the hits, confirms them, chases follow-on impact and writes them up.
Reproducing it is where the documentation gets tangled. seeker and flamer are self-contained – Python or Java, plus an Anthropic API key. The other two are not.
Advertisement
The validator’s documentation needs careful reading. The root README lists commercial Burp Suite for running it, while the validator’s own README says its test suite runs under Burp Community or Professional, with the Professional-only tests skipped on Community. Those cover different things, running the stage and testing it. Where the repository does contradict itself is the build: the validator’s README says the build depends on bulkScan-all.jar and that the jar is not vendored in the repository – yet it is committed at validator/bulkScan-all.jar, and the build file points at it. investigator, in turn, needs an external MCP simulator and Burp Organizer alongside Claude Code and a live target.
Following the data through the stages
Start in seeker/, with Python 3.11 or later, an Anthropic API key and network access. The README installs the package from that directory:
That installs seeker’s command-line tool. Its next command reads a URL list you create, a text file of the document URLs to process, fetches those documents and stores the extracted sections in seeker.db. The repository ships a sample list at seeker/fixtures/urls.txt you can point at instead to try it:
seeker process --input urls.txt --db seeker.db --manifest run.manifest.json --verbose |
The manifest records that run, while the SQLite database holds the sections you can inspect with seeker’s query command:
seeker query --db seeker.db --type http_desync_vector |
That selects the extracted desync-vector sections; once flamer has generated requests, seeker can trace a request ID back to its source:
python3 -m seeker.cli trace 1002368 --db seeker.db --flamer-db ../flamer/production.db |
Replace 1002368, the README’s example, with a request ID from your own flamer database; the trace links a generated request to the seeker section it came from.
Next, from flamer/, with Java 21, Gradle and an Anthropic API key, the default run reads unprocessed sections from ../seeker/seeker.db and writes generated requests to its own production.db:
export ANTHROPIC_API_KEY=your_key ./gradlew run |
The key is required for Claude; flamer’s README also offers a run that does not save generated requests:
./gradlew run --args="--dry-run" |
Use the documented dump option to view requests already held in flamer’s database:
./gradlew run --args="--dump" |
Flamer’s Gradle task copies its generated database into the validator directory:
./gradlew copyDbToValidator |
From validator/, the README builds the Burp extension jar with:
The documented output is build/libs/validator.jar; load it in Burp via Extensions > Installed > Add and select that file.
That manual extension-loading step is separate from the validator’s livetesting suite, which can use Burp Community or Professional: Community skips the Professional-only tests, while Professional runs them. The root README’s commercial-Burp requirement describes running the validation stage, not this test suite.
There is no investigator command to copy from its README. It calls for Claude Code with an Anthropic API key, an external simulator exposing turbo-simulator MCP tools, Burp Suite and a Burp Organizer-style findings source, plus a target you are authorised to test; those external pieces are not supplied with the repository.
seeker fetches the documents you list and calls Claude; flamer calls Claude and keeps its database local unless you opt into its upload flag. The generated requests are not sent to a target by those two stages. Validation is the point where Burp and target authorisation become necessary.
What it’s worth if you can’t run all of it
What the repository exposes is the design. The tree holds the prompts seeker uses to pull candidate vectors from a specification and the code flamer uses to turn those vectors into test cases. PentestGPT now runs a testing pipeline itself, driven by Claude Code or Codex; http-terminator instead points a model at one class of bug, starting from specifications.
Read that way, the repository is a worked, inspectable design for pointing a language model at a specification to generate desync test cases. Reading it is not the same as confirming it works. That would need running the pipeline against authorised targets, which this article did not do, so nothing here measures how well the approach performs.
I read the repository and its READMEs on 16 September 2026, at main commit 874682c, dated 22 July 2026. Everything above is read from the repository and its GitHub page; I did not run the pipeline.
You can find http-terminator here: https://github.com/PortSwigger/http-terminator
Advertisement