ChainJockey is a Burp Suite extension I built to deal with something that kept slowing me down during API pentests. Modern APIs are stateful and async. A lot of what you want to test requires a create, wait, then act sequence before you can even reach the interesting part of the attack surface. Burp built-in Macros and tools like ATOR (Authentication Token Obtain and Replace) just do not handle this well.
ChainJockey solves it by letting you build multi-step request chains where the output of one call feeds into the next, with full support for polling, sleep steps, and trigger conditions tied to live traffic.
The Problem With Macros
Burp Macros are fine for simple session token refresh. They fall apart the moment your API is async. If you fire a POST to create a resource and that resource needs to reach a ready state before you can interact with it, Macros have no answer. You either hardcode a sleep and hope, or you manually babysit the flow every time. Neither works for systematic fuzzing across hundreds of endpoints.
ATOR has the same problem. It is focused on token replacement, not stateful API orchestration.
What ChainJockey Does Differently
You capture real traffic, highlight values in the request or response to auto-build regex extractors, then assemble those into a chain. Steps can be send-request with variable substitution using extracted values, sleep for timing-sensitive APIs, or polling that loops until an extracted value matches a target state.
The trigger engine watches live traffic and fires your chain when incoming requests match your conditions: method, URL regex, status code, body content. You can allow or deny triggering per Burp tool, so you can scope it to Repeater only, Intruder only, or both.
ON REQUEST Mode
The feature I use most is ON REQUEST mode. This lets you run pre-steps before the trigger request is ever forwarded. The practical use case: you want to fuzz a DELETE endpoint, but the resource has to exist first. You set up a pre-step that creates the resource, polls until it is ready, injects the resource ID into the trigger request, then runs cleanup post-steps after regardless of whether the fuzz payload caused a failure. No orphaned resources, no manual reset between iterations.
A real example of that flow:
Pre-step 1: POST /api/orders -> Extract {{orderId}}
Pre-step 2: GET /api/orders/{{orderId}} -> Poll until status == "ready"
Trigger: DELETE /api/orders/{{orderId}}/cancel (fuzzed by Intruder)
Post-step: DELETE /api/orders/{{orderId}} (cleanup, always runs)
Extractors are built by highlighting text in a sample request or response and clicking Add extractor from response highlight. The placeholder is immediately available in all downstream steps. You can also export full chain definitions to YAML and import them back, which is useful for sharing test configs across engagements.
Use Cases
- OAuth flows with state and token refresh
- Multi-step provisioning workflows
- Eventual consistency and polling loops
- Async cloud API flows requiring sleeps and retries
- Fuzzing DELETE and state-mutating endpoints with automatic resource setup and cleanup
- Dynamic request rewriting using extracted variables
If just replaying a request is not enough, ChainJockey is the answer. This one is feature complete at this point.