See, edit, replay and auto-tamper the HTTP your web app sends — right inside your browser.
A lightweight, Burp-style proxy as a Chromium extension. No proxy setup, no certificates, no external app.
Interceptor is a browser extension for web developers and security testers who want to inspect and manipulate their own app's traffic without leaving the browser. It's the everyday 20% of Burp Suite — intercept, history, and repeater — plus one thing Burp makes you do by hand: Auto mode, which rewrites chosen fields (like a payment amount) on every request automatically, so you can test server-side validation in seconds.
Because it's built on the Chrome DevTools Protocol, it can truly pause, edit, forward, and drop live requests and responses — something a normal webRequest extension cannot do.
⚠️ Use it on apps you own or are authorized to test. See Responsible use.
- 🧲 Intercept — pause requests (and responses) and edit the raw method, path, query, headers or body before they continue. Forward, drop, or forward-and-catch-the-response.
- 📜 HTTP History — a live table of every request from the target tab, with full headers (including
Cookie/Set-Cookie), bodies, timing and size. Search URLs, headers, and bodies; filter by method/status/type; import or export HAR. - 🔁 Repeater — hand-craft a raw request and fire it as many times as you like. What you type is exactly what goes on the wire — including
Cookie,Origin,User-AgentandSec-*headers. - 📥 cURL import — paste a command from DevTools to create an editable Repeater request. Nothing executes or sends during import.
- 🗂️ Collections & variables — organize named requests in folders with notes. Reuse
{{host}},{{baseUrl}}, or your own variables across Repeater and Runner. Import/export portable collections; work is saved locally automatically. - 🧪 Runner — replace a value with
{{payload}}, try up to 50 values sequentially, and inspect status, timing, size, and response-text checks. Cancel a run, export CSV, or compare results. - 🗺️ Site Map — group captured requests into endpoints by origin, method, and path. See call counts, statuses, timing, and query field names; jump back to History or replay an endpoint.
- 🔎 Inspector — read query/form fields, nested JSON values, request cookies, response headers, and
Set-Cookieattributes. Send any field to Decoder. - ⚡ Auto mode — force one or more fields to a fixed value automatically. Limit changes with URL include/exclude patterns, then run against this tab or all tabs from the toolbar popup.
- ⚖️ Comparer — send responses from History or Repeater into a side-by-side line diff, with optional JSON normalization and a copyable unified diff.
- 🔓 Decoder — JSON, URL, Base64, hex, HTML entities, JWT inspection, and SHA-256/SHA-512 hashes, all locally.
- 🧰 API Builder — Postman-style HTTP requests with JSON/form/raw bodies, Bearer/Basic/API key auth, variables, response tests, and saved collections.
- ✅ Response assertions — check status, headers, JSON Pointer values, response text, time, and size in Builder, Repeater, and Runner. No test scripts execute.
- 🛡️ Security Review — passive checks of captured headers, cookies, CORS, caching, transport, URL credentials, and debug errors; manual credential comparison and reports.
- ⇌ WebSockets — observe sent/received text and binary frame previews from the attached tab, filter, decode, and export.
- 💾 Workspace — automatic saving on your PC, named environments, full backup/import with restore preview and undo, and optional password encryption.
↔️ Resizable panes — drag dividers throughout split tools, or focus them and use arrow keys. Wide and stacked sizes save locally, survive reloads, and travel in full backups. Double-click a divider to reset it, or reset all sizes in Workspace.- 🕘 Response snapshots — Repeater retains the last five responses for each tab and compares successive sends. Set a request timeout and duplicate requests with one click.
- 🧩 Works in Brave, Chrome and Edge. Pure JavaScript, no build step, no dependencies, no telemetry or cloud storage.
Install Interceptor from the Chrome Web Store, or load the source unpacked in about a minute:
- Download this repo (
git cloneor Code → Download ZIP and extract). - Open your browser's extensions page:
- Brave:
brave://extensions - Chrome:
chrome://extensions - Edge:
edge://extensions
- Brave:
- Turn on Developer mode (top-right).
- Click Load unpacked and select the project folder.
- Pin Interceptor to the toolbar. Done.
git clone https://github.com/user-github-me/interceptor.git
# then "Load unpacked" → select the interceptor/ folder- Click the Interceptor toolbar icon.
- Under URL safety scope, add your local or staging URL, such as
localhost:*/*or*.staging.example.com/api/*. - Choose All tabs (or This tab). The default rule already forces common payment fields to
1. - Use your app's checkout. Every in-scope
amount,payableAmount,totalAmount, … goes out as1. - Check your server: did it re-price server-side, or did it trust the client? If the order total drops, your validation is bypassable.
Open the panel to see rewrites in the Auto log. Attach to the app's tab to also record its full HTTP History.
- Click Open workbench → in the popup and pick your app's tab under Target tab, then Attach. Your browser shows an "Interceptor started debugging this browser" banner — that's expected; it's how the extension gets low-level access.
- Click Intercept is OFF to turn it ON.
- Use your app. Requests pause in the queue — edit anything and Forward (⌘/Ctrl+Enter), or Drop them.
- Send a captured request to Repeater, or use Import cURL to bring one in from DevTools.
- Save it to Collections and add a name, folder, and reproduction notes.
- Set workspace variables as
name=value, one per line. For example,host=localhost:3000can be used asHost: {{host}}in a saved request. - Click Send to Runner. Replace the value you want to vary with
{{payload}}, then put one value on each line in Payloads. Values are inserted literally; include quotes for JSON strings or URL encoding for query values. - Set the delay and timeout, then Start run. Each result can be opened in Repeater or compared with the first result. Starting the run sends all listed requests to the chosen target.
Runner uses one origin per run, sends one request at a time, and follows no redirects. It checks literal response text when you supply an expected value. Stop cancels the current request and remaining payloads. Missing variables block sending. Collections exports include request text but omit workspace variables; raw requests may still include credentials you pasted.
Use Command+K on macOS or Ctrl+K on Windows/Linux to jump to any workbench tool. Shortcut hints and button tooltips follow your system automatically.
- In Workspace, create an environment (such as Local or Staging) with
baseUrlandtokenvariables. Environment values override the shared values in Collections. - In API Builder, select a method, enter
{{baseUrl}}/api/health, choose authentication, and add headers or a JSON/form body. Click Send request to send it, or Save request to keep it in Collections. - Add response assertions in Builder, Repeater, or Runner:
[
{ "type": "status", "equals": 200 },
{ "type": "header", "name": "Content-Type", "contains": "application/json" },
{ "type": "json", "path": "/data/active", "equals": true },
{ "type": "time", "max": 1000 }
]JSON paths use JSON Pointer (/items/0/id, ~1 for /, ~0 for ~). Headers
support equals, contains, or absent: true; JSON fields support equals or
absent: true. Other checks: bodyContains with value, and size with max
bytes. JSON assertions reject numbers that cannot be represented exactly in the
supported range; inspect exact large numeric tokens in Inspector or use literal body text checks. Failed network sends
fail every assertion. Truncated responses are labeled as capped previews.
Collections → Import collection accepts Interceptor JSON and Postman v2-style collections, including nested folders, variables, raw/form bodies, and bearer auth. Postman variables become an environment. Unsupported auth/body modes are reported; file uploads and pre-request/test scripts are not imported or executed. Ordinary collection exports omit variables; full workspace backups include them.
Security Review → Review HTTP History sends no traffic. Its observations are context for testing, not confirmed vulnerabilities. Credential comparison sends two GET/HEAD/OPTIONS requests to one origin with redirects off; it strips only credential headers, keeping query/body values. Successful anonymous responses may be intentional. WebSockets records frames while Intercept has a tab attached; it does not pause or inject messages.
All workbench data saves automatically in the current browser profile’s local database, within the documented preview limits. Outgoing Builder, Repeater, Runner and credential-comparison requests also appear in HTTP History. Workspace → Download full backup exports history, snapshots, collections, environments, results, tool drafts, security observations, and frames. Set a password of at least eight characters to encrypt it. To restore, enter the same password, choose Import backup, review the counts, then choose Replace workspace. Detach and finish active requests first. Restore sends no requests, leaves Auto mode off, and keeps a local undo copy. Backups can contain credentials; downloaded files remain after uninstalling. Storage belongs to this browser profile, not a cloud account.
Interceptor is built on the Chrome DevTools Protocol (CDP) via the chrome.debugger API — the only way an extension can genuinely pause and mutate live traffic (the webRequest API can observe and block, but not rewrite bodies or edit responses).
┌───────────────────────────┐ ┌──────────────────────────────┐
│ Toolbar popup (popup.js) │ │ Dashboard page (dashboard.js)│
│ • Auto mode on/off │ │ • Intercept queue + editor │
│ • scope: this tab / all │ │ • HTTP history + HAR │
│ • field → value rules │ │ • Repeater + HAR import │
│ • URL safety scope │ │ • Comparer + Decoder │
└─────────────┬─────────────┘ └───────────────┬──────────────┘
│ chrome.storage │ CDP: Fetch + Network
▼ ▼ (its own debuggee)
┌─────────────────────────────────────────────────────────────────────┐
│ Background service worker (background.js) │
│ • Owns Auto mode: attaches the debugger to the target tab(s) │
│ automatically and rewrites fields via CDP "Fetch.requestPaused" │
│ • Survives service-worker idle (debugger sessions persist) │
│ • Hands a tab off to the dashboard when you attach manually │
└─────────────────────────────────────────────────────────────────────┘
│
▼
http.js — dependency-free engine:
raw HTTP parse/serialize, cURL/HAR,
and the field-rewrite rules (query, form,
nested JSON, multipart; type-preserving)
- Auto mode runs entirely in the background service worker, so it needs no open panel and can cover every tab. Attaching the debugger from the worker keeps working even after the worker goes idle.
- Manual intercept/history/repeater run in the dashboard page, which holds its own debugger session. When you attach it to a tab, it "claims" that tab and the worker steps aside — coordinated through a single serialized queue so the two never fight over one tab.
http.jshas zero DOM/chrome.*usage, so the whole request-rewriting engine is unit-tested in plain Node.
Each rule is a list of field names (comma-separated) plus one value. A field is rewritten wherever it appears in:
| Location | Example |
|---|---|
| Query string | ?amount=4999 → ?amount=1 |
Form body (x-www-form-urlencoded) |
amount=4999 → amount=1 |
| JSON body (including deeply nested) | {"order":{"amount":4999}} → {"order":{"amount":1}} |
| Multipart form fields | name="amount" part value → 1 |
Matching is case-insensitive on the whole field name (AmountToPay matches amountToPay), a field you didn't list (like quantity) is left untouched, and JSON types are preserved (a numeric field stays a number). The default rule covers the usual suspects: amount, payableAmount, payingAmount, amountToPay, paymentAmount, totalAmount, grandTotal, orderTotal, subtotal, price, unitPrice, amountDue, netAmount, finalAmount, chargeAmount, billAmount, totalPrice, payment — add your app's own field names in the popup.
Use URL safety scope to constrain those rules. Each line can be plain text, a glob such as *.example.test/api/*, or a regular expression such as /^https:\/\/api\.example\.test\//i. Globs match the whole URL, or the host and path when you omit the scheme. Plain text matches anywhere in the URL. Regex flags i, m, s, and u are supported. A blank include list allows all HTTP(S) URLs; exclusions always win. Invalid patterns pause automatic rewriting until fixed. Tab-only targets live in session storage, so a browser restart cannot accidentally reuse an old tab ID.
| Permission | Why |
|---|---|
debugger |
The core: pause, edit, forward and drop live requests/responses via CDP. |
tabs |
List tabs to target and coordinate attach/detach. |
storage |
Save local settings/rules and session coordination; the complete workspace is saved locally in IndexedDB. |
webRequest |
Show the "Actual request sent" view in Repeater. |
declarativeNetRequestWithHostAccess |
Let Repeater send otherwise-forbidden headers (Cookie, Origin, User-Agent, …) exactly as typed. |
clipboardWrite |
Copy raw messages, cURL commands, decoded output, and diffs when you click a copy button. |
<all_urls> |
Access traffic from the sites you select and send your API tests to their chosen targets. |
There are no analytics or telemetry. Analysis and storage are local; active API tools send requests only to the targets you choose.
- One manually-attached tab at a time for the deep intercept/history/repeater workflow (Auto mode can cover all tabs).
- WebSocket frames can be inspected but are not paused/modified. Server-Sent Events are not intercepted as individual events.
- Bodies are edited as UTF-8 text; binary and oversized bodies are passed through unchanged. History keeps up to 2,500 entries, 750,000 characters per body, and a 64-million-character total text budget. Repeater previews up to 4 MB per response.
- Raw panes render up to 200,000 characters to keep large responses responsive while resizing. Copy and exports retain the stored text within each tool's capture limits.
- Workspaces save automatically in the browser profile on your PC. Repeater supports 100 tabs; Collections 100 requests; environments 50; WebSockets 1,000 capped frames. Browser disk quotas still apply; the UI reports save failures and offers backup download.
- Runner is limited to 50 payloads and keeps capped response previews. Site Map and passive Security Review cover recorded/imported traffic; they do not crawl sites or prove vulnerabilities automatically.
- cURL import supports literal URLs, method, headers, body, cookies, Basic auth, and redirects. Unsupported options and file uploads are rejected instead of silently omitted.
- Browsers can't send a body with
GET/HEAD, so Repeater can't either. - Traffic from other-process iframes and some service workers may not be captured.
- For a self-signed HTTPS dev cert, open the URL in a tab and accept it once before using Repeater.
Pure JS, no build and no runtime dependencies. Run the tracked Node test suite and syntax checks with:
npm test
npm run checkTo prepare store artifacts locally (Node 22+, Python 3 and a Chromium packer):
npm run release
npm run release:sign -- --key local/key.pem
npm run release:verifyThe signed build requires your existing signing key and previous local CRX;
it does not create a replacement key. Outputs stay under ignored
local/release-1.1.0/. ZIP and CRX payloads contain the same runtime files; the
verification report checks signatures, identity continuity, content and checksums.
The browser integration check uses a local echo server and an isolated Chromium profile with the unpacked extension loaded and remote debugging enabled:
node tests/browser-integration.mjs http://127.0.0.1:9226
node tests/browser-popup.mjs http://127.0.0.1:9226 --screenshotsIt checks debugger attachment, request/response edits, Auto scope and worker
handoff, Repeater headers and rule cleanup, response limits, HAR import,
Inspector, Site Map, variables, Runner cancellation, snapshots, Builder authentication
and assertions, credential comparisons, live WebSocket frames, encrypted full
backups, restoration without traffic, and local persistence across reloads.
It also checks every draggable split, keyboard/reset actions, saved sizes, both
themes at narrow widths, auth/body modes, exports, Postman import, storage failures,
encrypted file import, and restore undo. Add --screenshots --store-screenshots
to create local workbench captures and five 1280×800 store images.
manifest.json MV3 manifest
background.js service worker — Auto mode engine + tab coordination
popup.html/.js/.css toolbar popup — Auto mode scopes & rules
dashboard.html/.js/.css the panel — intercept, history, repeater, comparer, decoder
http.js dependency-free HTTP + rewrite engine (unit-tested)
workbench.js HAR import, comparer, and decoder helpers
workflow.js cURL import, variables, endpoint mapping, and inspection helpers
workflow-ui.js/.css collections, Inspector, Site Map, Runner, and tool switcher
lab.js assertions, passive review, Postman import, backup validation/encryption
lab-ui.js/.css API Builder, Security Review, WebSockets, environments, backup UI
local-store.js IndexedDB storage for complete local workspaces
tests/ Node tests for parsing, rewriting, scope, HAR, diff, and codecs
icons/ extension icons
docs/screenshots/ images used in this README
This is a tool for testing your own applications, or ones you have explicit permission to test. Intercepting or tampering with traffic to services you don't control may be illegal and is not the intent of this project. You are responsible for how you use it.
Start with a bug report or feature issue, agree on a focused scope, and implement it on a feature branch. Open a linked PR for review. Read CONTRIBUTING.md for setup, templates, browser verification, and design constraints. GitHub Actions runs the syntax and regression checks on PRs.
The v1.1 feature work in PR #1 has merged and its linked issues are closed. Release validation and follow-up fixes use separate issues and PRs. An issue closes when its implementing PR merges into main with a Closes #number reference.
MIT — do what you like, no warranty.














