How Strix HTTP Proxy Enables Request Interception and Manipulation: A Technical Deep Dive

Strix routes all sandbox traffic through Caido, exposing a Python API via ProxyManager and @register_tool decorators that let you query, modify, and replay HTTP requests programmatically.

The Strix HTTP proxy tool, integrated into the usestrix/strix repository, provides automated request interception and manipulation capabilities for security testing workflows. By embedding Caido as a forward proxy within the sandbox container, Strix captures every HTTP/HTTPS request and exposes them through a GraphQL-backed Python interface. This architecture enables both real-time traffic inspection and programmatic request modification without requiring manual proxy configuration.

Architecture Overview: Caido Integration

Strix leverages Caido as its underlying proxy engine, running it as an HTTP/HTTPS forward proxy on 127.0.0.1:48080 inside the sandbox container. All traffic generated by the agent—whether from browser automation or direct API calls—is automatically routed through this proxy endpoint.

The proxy stores every request/response pair in Caido's internal database, making them queryable via a GraphQL API at http://127.0.0.1:48080/graphql. Authentication uses the CAIDO_API_TOKEN environment variable, ensuring secure access to the captured traffic data.

Core Components of the Proxy System

ProxyManager: The GraphQL Interface

The ProxyManager class in strax/tools/proxy/proxy_manager.py serves as the primary interface to Caido's GraphQL endpoint. It handles authentication, constructs proxy configurations, and provides high-level methods for traffic manipulation.

Key capabilities include:

  • Traffic querying: list_requests() uses GraphQL queries like GetRequests to retrieve captured traffic with HTTPQL filtering
  • Raw data retrieval: view_request() fetches base-64 encoded request/response data and decodes it for inspection
  • Request replay: repeat_request() parses raw HTTP, applies modifications, and forwards through the proxy
  • Direct forwarding: send_request() routes arbitrary HTTP calls through Caido without database storage

Tool Registration via proxy_actions.py

The proxy_actions.py module in strax/tools/proxy/proxy_actions.py registers proxy functions as Strix tools using the @register_tool decorator. This exposes list_requests, view_request, repeat_request, send_request, scope_rules, list_sitemap, and view_sitemap_entry to the Strix runtime.

These registered tools become callable from the Terminal User Interface (TUI), from other Strix tools, and from user-provided Python code executing within the sandbox.

Python REPL Integration

Every new Python REPL started by Strix automatically injects proxy functions into the user namespace through the _setup_proxy_functions method in strax/tools/python/python_instance.py. This method imports proxy_actions and updates the session globals, making interception capabilities available immediately without explicit imports.

Request Interception and Manipulation Workflow

The Strix HTTP proxy operates through a seven-stage pipeline:

  1. Traffic Capture: Caido receives all outbound requests via the proxy configuration self.proxies = {"http": f"http://{host}:{CAIDO_PORT}", "https": f"http://{host}:{CAIDO_PORT}"} defined in proxy_manager.py (lines 27-29).

  2. Storage: Caido persists request/response pairs in its internal database, enabling historical queries through GraphQL.

  3. Retrieval: list_requests() calls ProxyManager.list_requests(), executing GraphQL queries like query GetRequests (lines 62-71 in proxy_manager.py) and returning normalized dictionaries of request metadata.

  4. Inspection: view_request() retrieves raw payloads, performs base-64 decoding (lines 59-70), and supports regex searching or pagination for large responses.

  5. Modification and Replay: repeat_request() (lines 78-106) implements the core manipulation logic:

    • Calls view_request to retrieve the original raw HTTP request
    • Parses the request using _parse_http_request
    • Reconstructs the full URL via _build_full_url
    • Applies user-supplied modifications through _apply_modifications (headers, parameters, body, cookies)
    • Forwards the modified request through Caido's proxy using requests.request(..., proxies=self.proxies)
  6. Direct Injection: send_request() bypasses the database and forwards arbitrary HTTP calls through the same proxy infrastructure, returning status codes, headers, bodies, and diagnostic messages.

  7. Scope Management: scope_rules() (starting at line 540) creates allow/deny lists that filter captured traffic, while list_sitemap and view_sitemap_entry expose the discovered attack surface.

Programmatic Request Manipulation

The repeat_request() method provides the primary mechanism for request interception and manipulation. According to the usestrix/strix source code, this function reuses the same parsing and re-assembly logic that powers Caido's UI, enabling programmatic editing of method, URL, headers, body, and cookies.

When Caido's UI pauses a request mid-flight, the same underlying data structures are exposed. The Python API provides equivalent capabilities: you can modify any request component before forwarding, effectively creating a scriptable man-in-the-middle proxy.

Practical Code Examples

The following example demonstrates the complete interception and manipulation workflow using Strix's automatically injected proxy functions:


# List recent POST requests using HTTPQL syntax

post_requests = list_requests(
    httpql_filter='req.method.eq:"POST"',
    page_size=10
)

# Inspect the raw HTTP request data

req_id = post_requests["requests"][0]["id"]
details = view_request(req_id, part="request")
print(details["raw"])  # Full HTTP request as string

# Replay with modified JSON body and custom header

modified = repeat_request(req_id, {
    "body": '{"user_id":"admin","action":"escalate"}',
    "headers": {"X-Testing": "true"}
})
print(f"Replay status: {modified['status_code']}")

# Send a new request through the Caido proxy

new_resp = send_request(
    method="GET",
    url="https://api.example.com/health",
    headers={"Accept": "application/json"}
)
print(new_resp["status_code"], new_resp["body"][:200])

All functions execute through the ProxyManager instance, automatically handling authentication via CAIDO_API_TOKEN and routing through 127.0.0.1:48080.

Summary

  • Strix integrates Caido as a forward proxy at 127.0.0.1:48080, capturing all sandbox HTTP/HTTPS traffic automatically.
  • ProxyManager in strax/tools/proxy/proxy_manager.py provides the GraphQL interface for querying, viewing, and modifying captured requests.
  • proxy_actions.py registers functions like list_requests, view_request, and repeat_request as Strix tools via @register_tool decorators.
  • Python REPL integration via python_instance.py makes proxy functions available in every new session without explicit imports.
  • repeat_request() enables programmatic request manipulation by parsing raw HTTP, applying modifications, and forwarding through the proxy.
  • Scope rules and sitemap functions provide attack surface discovery and traffic filtering capabilities.

Frequently Asked Questions

How does Strix authenticate with the Caido proxy?

Strix authenticates with Caido's GraphQL API using the CAIDO_API_TOKEN environment variable. The ProxyManager class automatically includes this token in requests to http://127.0.0.1:48080/graphql, ensuring secure access to the captured traffic database without manual credential management.

Can I modify request headers and body when replaying traffic?

Yes. The repeat_request() function accepts a modifications dictionary that supports changing headers, parameters, body content, and cookies. The function parses the original raw HTTP request, applies your changes via _apply_modifications, and forwards the updated request through the Caido proxy, returning the new response data.

Are proxy functions available automatically in Python scripts?

Yes. Strix automatically injects all proxy functions into every Python REPL session through the _setup_proxy_functions method in strax/tools/python/python_instance.py. This imports proxy_actions and updates the global namespace, making list_requests, send_request, and other tools immediately accessible without import statements.

What is the difference between repeat_request() and send_request()?

repeat_request() retrieves an existing request from Caido's database by ID, allows you to modify it, and replays it through the proxy. send_request() bypasses the database entirely and forwards a brand-new HTTP request constructed from parameters you provide. Both route traffic through 127.0.0.1:48080 and return status codes, headers, and response bodies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →