5921fec16c
send_request was a thin wrapper over the Caido Replay API that the model
could replicate with a one-liner `curl` via exec_command. The sandbox's
HTTP_PROXY env captures all such traffic for free, so the tool was
adding bugs (duplicate dispatch, dropped responses) without adding
capability. Removed across factory, tools module, sandbox-importable
caido_api helper, TUI renderer, prompt template, skill doc, and public
docs. repeat_request stays — it operates on captured request IDs with
structured modifications, which curl can't replicate cleanly.
Three caido-sdk-client workarounds that were hitting us through both
send_request and repeat_request:
- replay_send_raw used to pass CreateReplaySessionFromRaw to
sessions.create(), which seeds a stored entry server-side, then
called send() — producing two history rows per call. Empty-create +
send produces one dispatched request.
- The same helper read result.entry.response_raw, an attribute that
doesn't exist on ReplayEntry, so response bytes were silently
dropped. Fixed to walk result.entry.response.raw with proper None
guards.
- get_request_with_client passed include_request_raw / include_response_raw
based on the requested part, but the SDK's generated pydantic models
declare raw as required even though the GraphQL fragment makes it
conditional via @include. Passing False crashed view_request with a
pydantic validation error. Always request both raw bodies; the caller
picks which to surface.
Also wrapped replay.send() in asyncio.wait_for(30s) so a stalled Caido
dispatch (notably loopback targets that don't route cleanly through the
sandbox proxy) fails fast with a model-readable error instead of
hanging the agent until the function_tool 120s budget expires.
Finally, list_requests now omits the roundtrip_ms field when Caido
reports 0 — proxy-captured unscoped traffic consistently reports 0
while scoped/replay traffic carries real measurements, so the absence
of the field is now informative ("Caido didn't measure this") rather
than misleading ("this request took 0ms").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
134 lines
4.6 KiB
Plaintext
134 lines
4.6 KiB
Plaintext
---
|
|
title: "HTTP Proxy"
|
|
description: "Caido-powered proxy for request interception and replay"
|
|
---
|
|
|
|
Strix includes [Caido](https://caido.io), a modern HTTP proxy built for security testing. All browser traffic flows through Caido, giving the agent full control over requests and responses.
|
|
|
|
## Capabilities
|
|
|
|
| Feature | Description |
|
|
| ---------------- | -------------------------------------------- |
|
|
| Request Capture | Log all HTTP/HTTPS traffic automatically |
|
|
| Request Replay | Repeat any request with modifications |
|
|
| HTTPQL | Query captured traffic with powerful filters |
|
|
| Scope Management | Focus on specific domains or paths |
|
|
| Sitemap | Visualize the discovered attack surface |
|
|
|
|
## HTTPQL Filtering
|
|
|
|
Query captured requests using Caido's HTTPQL syntax
|
|
|
|
## Request Replay
|
|
|
|
The agent can take any captured request and replay it with modifications:
|
|
|
|
- Change path parameters (test for IDOR)
|
|
- Modify request body (test for injection)
|
|
- Add/remove headers (test for auth bypass)
|
|
- Alter cookies (test for session issues)
|
|
|
|
## Python Integration
|
|
|
|
Proxy helpers are available to sandbox Python scripts through the image-baked `caido_api` module. This enables powerful scripted security testing:
|
|
|
|
```python
|
|
import asyncio
|
|
|
|
from caido_api import list_requests, repeat_request, view_request
|
|
|
|
|
|
async def main():
|
|
# List recent POST requests
|
|
post_requests = await list_requests(
|
|
httpql_filter='req.method.eq:"POST"',
|
|
first=20,
|
|
)
|
|
|
|
# View a specific request
|
|
request_details = await view_request("req_123", part="request")
|
|
|
|
# Replay with modified payload
|
|
response = await repeat_request(
|
|
"req_123",
|
|
modifications={"body": '{"user_id": "admin"}'},
|
|
)
|
|
print(response["status"], request_details is not None, len(post_requests.edges))
|
|
|
|
|
|
asyncio.run(main())
|
|
```
|
|
|
|
### Available Functions
|
|
|
|
| Function | Description |
|
|
| ---------------------- | ------------------------------------------ |
|
|
| `list_requests()` | Query captured traffic with HTTPQL filters |
|
|
| `view_request()` | Get full request/response details |
|
|
| `repeat_request()` | Replay a request with modifications |
|
|
| `scope_rules()` | Manage proxy scope (allowlist/denylist) |
|
|
|
|
For one-off arbitrary requests, use shell tooling like `curl` — the
|
|
sandbox's `HTTP_PROXY` env routes the traffic through Caido
|
|
automatically, so it lands in `list_requests` and can be replayed via
|
|
`repeat_request`.
|
|
|
|
### Example: Automated IDOR Testing
|
|
|
|
```python
|
|
import asyncio
|
|
|
|
# Get all requests to user endpoints
|
|
from caido_api import list_requests, repeat_request
|
|
|
|
|
|
async def main():
|
|
user_requests = await list_requests(httpql_filter='req.path.cont:"/users/"')
|
|
|
|
for edge in user_requests.edges:
|
|
req = edge.node.request
|
|
scheme = "https" if req.is_tls else "http"
|
|
for test_id in ["1", "2", "admin", "../admin"]:
|
|
url = f"{scheme}://{req.host}{req.path.replace('/users/1', f'/users/{test_id}')}"
|
|
response = await repeat_request(
|
|
req.id,
|
|
modifications={"url": url},
|
|
)
|
|
print(req.id, test_id, response["status"])
|
|
if response["status"] == "DONE":
|
|
print(f"Replay completed for candidate {test_id}")
|
|
|
|
|
|
asyncio.run(main())
|
|
```
|
|
|
|
## Human-in-the-Loop
|
|
|
|
Strix exposes the Caido proxy to your host machine, so you can interact with it alongside the automated scan. When the sandbox starts, the Caido URL is displayed in the TUI sidebar — click it to copy, then open it in Caido Desktop.
|
|
|
|
### Accessing Caido
|
|
|
|
1. Start a scan as usual
|
|
2. Look for the **Caido** URL in the sidebar stats panel (e.g. `localhost:52341`)
|
|
3. Open the URL in Caido Desktop
|
|
4. Click **Continue as guest** to access the instance
|
|
|
|
### What You Can Do
|
|
|
|
- **Inspect traffic** — Browse all HTTP/HTTPS requests the agent is making in real time
|
|
- **Replay requests** — Take any captured request and resend it with your own modifications
|
|
- **Intercept and modify** — Pause requests mid-flight, edit them, then forward
|
|
- **Explore the sitemap** — See the full attack surface the agent has discovered
|
|
- **Manual testing** — Use Caido's tools to test findings the agent reports, or explore areas it hasn't reached
|
|
|
|
This turns Strix from a fully automated scanner into a collaborative tool — the agent handles the heavy lifting while you focus on the interesting parts.
|
|
|
|
## Scope
|
|
|
|
Create scopes to filter traffic to relevant domains:
|
|
|
|
```
|
|
Allowlist: ["api.example.com", "*.example.com"]
|
|
Denylist: ["*.gif", "*.jpg", "*.png", "*.css", "*.js"]
|
|
```
|