2026-04-25 22:58:53 -07:00
---
name: python
2026-04-27 00:21:54 -07:00
description: Run Python through exec_command in the SDK sandbox. Use the image-baked caido_api module for Caido proxy automation from Python scripts.
2026-04-25 22:58:53 -07:00
---
2026-04-27 00:21:54 -07:00
# Python In The Sandbox
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
Use `exec_command` for Python. There is no separate Strix Python executor.
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
Prefer writing reusable scripts to `/workspace/scratch/<name>.py` and
running them with `python3 /workspace/scratch/<name>.py` . For short
one-off transformations, `python3 -c` or a small here-document is fine.
2026-04-25 22:58:53 -07:00
2026-05-25 14:05:42 -07:00
The `shell` parameter on `exec_command` is for swapping POSIX shells
(`bash` /`zsh` /`sh` ), not for picking interpreters. Put the interpreter
invocation in `cmd` instead: `cmd="python3 -c '...'"` , not
`shell=python3, cmd="..."` . The `shell=<interpreter>` shortcut breaks
in subtle ways — `python3` works only with `login=False` (because the
SDK adds `-l` /`-i` ), and other interpreters (`node` , `ruby` , `perl` )
take `-e` not `-c` so they fail even with `login=False` .
2026-04-27 00:21:54 -07:00
## Proxy Automation From Python
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
The sandbox image includes an installed `caido_api` module. Import it
explicitly when Python code needs Caido traffic or replay access:
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
```python
from caido_api import (
list_requests ,
2026-05-25 00:23:46 -07:00
list_sitemap ,
2026-04-27 00:21:54 -07:00
repeat_request ,
scope_rules ,
view_request ,
2026-05-25 00:23:46 -07:00
view_sitemap_entry ,
2026-04-27 00:21:54 -07:00
)
```
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
All helpers are async. Use them inside `asyncio.run(...)` or an async
function:
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
```python
import asyncio
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
from caido_api import list_requests , view_request
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
async def main ():
posts = await list_requests (
httpql_filter = 'req.method.eq:"POST" AND req.path.cont:"/api/"' ,
first = 50 ,
)
candidates = []
for edge in posts . edges :
request_id = edge . node . request . id
body = await view_request ( request_id , part = "request" )
raw = body . request . raw . decode ( "utf-8" , errors = "replace" )
if "id=" in raw or "user=" in raw :
candidates . append ( request_id )
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
print ( f " { len ( candidates ) } candidates" )
print ( candidates [: 10 ])
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
asyncio . run ( main ())
2026-04-25 22:58:53 -07:00
```
2026-04-27 00:21:54 -07:00
Available helpers:
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
- `list_requests(httpql_filter=, first=50, after=, sort_by=, sort_order=, scope_id=)` returns a cursor-paginated Caido SDK `Connection` .
- `view_request(request_id, part="request")` returns a Caido SDK request object with raw request/response bytes.
- `repeat_request(request_id, modifications={...})` replays a captured request after modifying `url` , `params` , `headers` , `body` , or `cookies` .
2026-05-25 00:23:46 -07:00
- `list_sitemap(scope_id=, parent_id=, depth="DIRECT", page=1)` walks Caido's request-tree view of the discovered surface. Omit `parent_id` for root domains; pass an entry id with `depth="DIRECT"` or `"ALL"` to drill in.
- `view_sitemap_entry(entry_id)` returns one entry plus its 30 most recent related requests.
2026-04-27 00:21:54 -07:00
- `scope_rules(action, allowlist=, denylist=, scope_id=, scope_name=)` manages Caido scopes.
2026-04-25 22:58:53 -07:00
2026-05-24 19:16:06 -07:00
For one-off arbitrary requests (e.g. probing a fresh endpoint, hitting an
external API), use `exec_command` with `curl` / `httpx` / `requests` . The
sandbox's `HTTP_PROXY` env routes all such traffic through Caido
automatically, so it shows up in `list_requests` and you can use
`repeat_request` to replay-and-modify any of it.
2026-04-27 00:21:54 -07:00
## Workflow
2026-04-25 22:58:53 -07:00
2026-04-27 00:21:54 -07:00
For iterative exploit work, put code in a file:
2026-04-25 22:58:53 -07:00
```text
2026-04-27 00:21:54 -07:00
1. Create or edit `/workspace/scratch/exploit.py` with `apply_patch`.
2. Run it with `exec_command`: `python3 /workspace/scratch/exploit.py`.
3. Edit and rerun until the proof-of-concept is reliable.
2026-04-25 22:58:53 -07:00
```
2026-05-25 22:02:15 -07:00
## Installing extra packages
The sandbox's Python lives in `/app/.venv` . To add a one-off dependency
for an exploit script, use `uv` (already in the image and much faster
than pip):
```bash
uv pip install --python /app/.venv/bin/python <package>
```