Proxy & History
The proxy sits between your client and the upstream server, records each exchange as a flow, and stores it in the current project. History is where you read those flows back.
Capturing Traffic
Start gori and point your client at 127.0.0.1:8070 (see the Quick Start). Toggle capture at any time with c. Turning it off lets traffic pass through without being recorded, which is handy while you set up.
Each flow records the full request and response: start line, headers, and body (the stored body is capped at 2 MiB; larger bodies still forward byte-exact and report their true size). Bodies compressed with gzip, deflate, Brotli, or Zstd are decoded for display.
Intercept
Press i to enable Intercept. When on, matching requests (and optionally responses) are held so you can forward, drop, or edit them before they continue. A filter bar at the top of the Intercept tab lets you choose the direction to catch and narrow what gets held with a query-language expression, so you only pause on the traffic you care about.
Scope
Scope keeps a large session focused on your target. In the Project tab you define include/exclude rules by host, string, or regular expression. Toggle the scope lens with s to filter the views down to in-scope traffic, and use scope to gate what Intercept and the scanners act on.
Sandbox
The Sandbox is a hard containment gate for staying strictly in-bounds during a test. Toggle it in the Project tab's NETWORK pane (default: off). While it's on, the capture proxy forwards only the requests your scope allows. Everything else is blocked before it reaches the origin (the client gets a 403 with an X-Gori-Sandbox: blocked header) and recorded as an aborted flow so the attempt stays visible. "Allowed" means the scope evaluated as an allowlist: at least one include rule must match, and no exclude rule may match.
Because it is an allowlist, a scope with no include rules blocks all traffic, so add an include for your target first (enabling the sandbox with an empty scope asks you to confirm exactly this). A red sandbox chip in the top bar stays lit whenever it's on, and the NETWORK row spells out the current effect right next to the toggle.
The sandbox governs proxied and captured traffic only. Repeater, Fuzzer, Miner, and the MCP send_request tool enforce scope on their own (they refuse an out-of-scope target with SCOPE_BLOCKED). For HTTPS the sandbox relies on TLS interception to read request URLs: a host that can't be in scope is refused at the CONNECT step, and interceptable connections are kept on HTTP/1.1 so every request is checked individually.
Sitemap
The Sitemap tab collapses History into a deduplicated tree of host β path endpoints, with method chips and scope markers. It's a quick way to see the shape of a target's attack surface. Press g to fold path-param ids, so /user/1 and /user/2 share one node and /user/<uuid> collapses into a single {uuid}.
host β path tree with method chips, so you can read a target's surface at a glance.Protocol Support
gori understands the protocols it carries:
| Protocol | Support |
|---|---|
| HTTP/1.1 | Full capture and repeater |
| HTTP/2 | Transparent relay after ALPN, raw frame log, HPACK decode, stream β flow assembly |
| WebSocket | Live message capture and repeater (no permessage-deflate) |
| gRPC | Framed over HTTP/2 with status trailers; protobuf shown as raw bytes (no .proto schema) |
| Server-Sent Events | Parsed into discrete events at display time |
On top of the wire protocols, gori decodes common payloads inline:
- JWT: header and payload decoded from
Authorization, cookies, URLs, and bodies (signatures are shown but never verified). - SAML: base64 (and DEFLATE for the redirect binding) decoded for
SAMLRequest/SAMLResponse. - GraphQL:
query,operationName, andvariablesparsed from POST bodies and?query=parameters. - Form params:
application/x-www-form-urlencodedandmultipart/form-datarequest bodies, plus the URL query string, decoded into a flat key=value list in the PARAMS pane (multipart file parts are summarised).
Filtering History
History is searchable with gori's query language. A few examples:
status:5xx flows that errored
host:api.example.com a single host
method:POST body:password POST requests mentioning "password"
dur:>500 responses slower than 500 ms
path~/admin/ path matching a regex
Type a query in the History filter bar, or run it headless:
gori run history -q 'status:5xx host:api.example.com'
Match & Replace (Rewriter tab)
The Rewriter tab is the Match & Replace editor: rules that rewrite requests and responses in flight. It is hidden by default, so reach it from the tab-bar β― menu or the command palette (Ctrl-P β Match & Replace, or Go to Rewriter).
Each rule has an operation:
| Operation | What it does |
|---|---|
| Replace | Find and replace text in the head or body, by literal substring or regex |
| Add header | Append a Name: value header |
| Set header | Replace a header's value by name, or add it if absent |
| Remove header | Drop a header by name |
A Replace rule targets the request or response, and the head (request/status line + headers) or body (the entity). Choose literal or regex matching; a regex replacement supports $1/$2 capture-group interpolation (write $$ for a literal $). Header operations always act on the head and match by header name, case-insensitively. An empty value deletes the matched text or removes the header.
Scope any rule to a host glob so it only fires for matching traffic: a plain string matches as a substring (example.com matches api.example.com), and * is a wildcard (*.example.com). Leave it empty to apply to every host.
Manage the list with a add, e/Enter edit, x enable/disable, d delete, Shift-J/Shift-K reorder (rules apply top to bottom), and space for the full menu. The editor shows a live preview of how many recent flows a rule would affect. Rules are per-project and take effect as soon as you save, with no restart.
A body rule buffers the message to rewrite it and re-syncs Content-Length automatically (a chunked body is de-chunked and re-framed); head rules keep the body streaming untouched. A compressed (Content-Encoding: gzip/br/β¦) body isn't decompressed, so a literal pattern won't match it, and streaming responses (SSE, close-delimited, WebSocket upgrades) are left to stream. Enabling any rule forces matching hosts to HTTP/1.1, since HTTP/2 heads never reach the rewrite seam.
The same rules are scriptable headless: gori run rewriter (list / add / rm / enable / disable / preview) and the MCP create_rule / update_rule / list_rules / preview_rule tools.
Import
You don't have to capture everything live. From the command palette (Ctrl-P):
| Action | Source |
|---|---|
| Import: HAR | Browser or proxy HAR export β full request/response flows |
| Import: URLs | Text file, one URL per line β skeleton request flows |
| Import: OpenAPI | OpenAPI/Swagger JSON or YAML β one request template per operation |
Malformed entries are skipped rather than aborting the whole import. Imported flows land in History like captured traffic, so you can filter, Repeater, Fuzz, and scan them the same way.
Host Overrides
Host overrides are a /etc/hosts-style map: dial a specific IP for a hostname without changing DNS. Two layers exist:
| Layer | Where | Precedence |
|---|---|---|
| Project | Project tab β HOST OVERRIDES pane (a / e / d) |
Wins on collision |
| Global | Preferences (Ctrl-,) β Network & Tabs β Network β Hostname overrides, Ctrl-P β Settings: Hostnames, or hostname_overrides in settings.json |
Fallback |
Useful for staging hosts, IP-based virtual hosts, or pointing a production hostname at a lab box while keeping the Host header intact.
Project Tab
The Project home tab is more than a summary. Focusable panes (cycle with Tab):
| Pane | Purpose |
|---|---|
| SCOPE | Include/exclude rules (host, string, or regex) |
| HOST OVERRIDES | Per-project dial map |
| ENV | Per-project $KEY variables for outbound requests. See Repeater & Fuzzer |
| DESCRIPTION | Free-form project notes |
| NETWORK | Scope-lens + sandbox toggles, plus per-project network pins (bind / upstream) that override the global Settings default |
Scope rules and host overrides are also scriptable: gori run project scope add --kind=include --type=host --pattern=api.example.com, gori run project host-override add --host=api.example.com --ip=10.0.0.1. Full flags are in the CLI Reference.
Next Steps
- Repeater & Fuzzer: act on the flows you capture
- Decoder: encode, decode, and hash without leaving the TUI
- Scanning & Issues: automated and manual analysis
- Query Language: the full filter syntax