Intercept
The intercept section short-circuits HTTP requests before they reach the upstream server. The proxy returns a response you supply, instead of forwarding the request. Use it to:
- Block telemetry or fingerprinting requests that would otherwise leak the proxy.
- Serve local replacements for static assets — favicons, JavaScript files, images.
- Redirect a request to a different resource (for example, to swap the extension of a downloaded file).
Only requests can be intercepted. Response interception is not supported (you modify responses with Rewrite instead).
Shape
intercept: {
requests: [
{ trigger: { hostname: "accounts.google.com", path: "/" },
response: { status: 200, data: "@index.html" } }
{ trigger: { hostname: "browser.events.data.microsoft.com", path: "*" },
response: { status: 403, mime_type: "application/json" } }
{ trigger: { hostname: "akira.lab.evilginx.com",
path: "~/assets/evilginx\\.[a-z0-9]*\\.svg" },
response: { status: 302, redirect: "/assets/poop.png" } }
{ trigger: { hostname: "akira.lab.evilginx.com", path: "/assets/poop.png" },
response: { status: 200, data: "@img/poop.png", mime_type: "image/png" } }
]
}
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
trigger | trigger | yes | — | Selects the request to intercept. |
response.status | int | yes | — | HTTP status code to return. Use 301/302 for redirects, 403/404 for blocks, 200 for served content. |
response.data | string | no | "" | The response body. A string literal, or @<file> to load from the phishlet's static/ directory. |
response.mime_type | string | no | auto-detected | Content-Type header. If omitted and data was loaded with @, the parser infers the type from the file extension (falling back to application/octet-stream). |
response.redirect | string | no | "" | If non-empty, returned in the Location header. Set status to 301 or 302 for the browser to follow it. |
options.block_request | bool | no | true | When true, the upstream request is suppressed. When false, the proxy still sends the request upstream but lets you replace the response body. |
Common patterns
Serving a local replacement
Pin a phishlet's landing page to a file you ship in static/:
{
trigger: { hostname: "accounts.google.com", path: "/" },
response: { status: 200, data: "@index.html" }
}
The MIME type defaults to text/html because the file extension is .html.
Blocking telemetry
Return a non-success status with no body to silently kill a telemetry endpoint:
{
trigger: { hostname: "browser.events.data.microsoft.com", path: "*" },
response: { status: 403, mime_type: "application/json" }
}
The browser receives a 403 Forbidden and the upstream is never contacted.
Swapping a resource by redirecting
Browsers fetch a resource at the URL you point them at. To swap an SVG for a PNG (and force the file extension to change), return a redirect to a second route that is itself intercepted:
{ trigger: { hostname: "akira.lab.evilginx.com",
path: "~/assets/evilginx\\.[a-z0-9]*\\.svg" },
response: { status: 302, redirect: "/assets/boop.png" } }
{ trigger: { hostname: "akira.lab.evilginx.com", path: "/assets/boop.png" },
response: { status: 200, data: "@img/boop.png", mime_type: "image/png" } }
The first rule matches any evilginx.<hash>.svg request and points the browser at /assets/boop.png. The second rule serves that file from static/img/boop.png.
Modifying a real response without blocking the request
Set options.block_request: false to let the upstream serve the request normally but still control what the visitor receives:
{
trigger: { hostname: "api.example.com", path: "/v1/status" },
response: { status: 200, data: '{"status":"ok"}', mime_type: "application/json" },
options: { block_request: false }
}
The upstream still gets the request — useful when the server needs to register the call for accounting — but the visitor sees your replacement response.