Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🦊 PwnChrome

A PwnFox-style web security testing extension β€” for Chrome.

Colored containers Β· isolated cookie & storage jars Β· one-click Burp proxy Β· JS injection toolbox

Manifest V3 Chrome Burp Suite Release


Colored container tabs β€” blue, green, yellow, red

PwnChrome is a Chrome alternative to PwnFox (the Firefox extension by YesWeHack). It brings the same workflow to Chromium browsers: spin up color-coded containers, log in as several users on the same site at the same time, and pipe everything through Burp with one click β€” each container's traffic automatically tagged for the PwnFox Burp extension.

Note

Why this is harder on Chrome. PwnFox relies on Firefox's native containers (contextualIdentities), which give each container its own cookie jar for free. Chrome has no such thing β€” there's no container API, and Manifest V3 removed blocking webRequest. So PwnChrome has to re-engineer containers from scratch on top of declarativeNetRequest + webRequest: it controls what each colored tab sends, captures what it receives, and emulates per-color isolation by hand. See How it works.

Note

A container is a color. All tabs sharing a color share one cookie/storage jar. Different colors are isolated from each other. Uncolored tabs use Chrome's normal store.


Table of contents


Screenshots

Burp HTTP history, colored per container β€” the PwnFox Burp extension reads X-PwnFox-Color:

Burp HTTP history colored per container

Popup

PwnChrome popup
Options β€” proxy + JS toolbox

PwnChrome options page

Install

Chrome no longer loads unpacked extensions from the command line, so use the UI.

From a release (recommended)

  1. Download pwnchrome.zip from the Releases page and unzip it.
  2. Open chrome://extensions and enable Developer mode (top-right).
  3. Click Load unpacked and select the unzipped PwnChrome/ folder.

From source

git clone https://github.com/Vozec/PwnChrome.git

Then chrome://extensions β†’ Developer mode β†’ Load unpacked β†’ select the PwnChrome/ folder.

The toolbar icon is red when disabled, green when enabled. The master switch and Burp proxy are on by default, so you can start tagging tabs right away.


Container colors

The color β†’ header mapping is identical to PwnFox, so the existing Burp extension works with zero changes.

Tab color X-PwnFox-Color value
blue blue
turquoise cyan
green green
yellow yellow
orange orange
red red
pink pink
purple magenta

Usage with Burp

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   X-PwnFox-Color: red    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   colored history   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  red tab    β”‚ ───────────────────────► β”‚              β”‚ ──────────────────► β”‚         β”‚
β”‚ (user 1)    β”‚      isolated cookies    β”‚ Burp @ :8080 β”‚                     β”‚ PwnFox  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                          β”‚  (proxy)     β”‚                     β”‚  (Burp  β”‚
β”‚  blue tab   β”‚ ───────────────────────► β”‚              β”‚ ──────────────────► β”‚  ext)   β”‚
β”‚ (user 2)    β”‚   X-PwnFox-Color: blue   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      isolated cookies
  1. Start Burp with a proxy listener on 127.0.0.1:8080 (default).
  2. Install Burp's CA certificate in Chrome (visit http://burp β†’ CA Certificate) so HTTPS works.
  3. Install the PwnFox extension in Burp (BApp Store or the repo's burp/ jar).
  4. The master switch and Burp proxy are ON by default β€” just click a color to open a tagged tab.
  5. Open a second tab, give it a different color, log in as another user β€” both sessions stay separate, and Burp colors each container's requests automatically.

How it works

Chrome's MV3 constraints shape the whole design:

  • No contextualIdentities (Firefox containers) β€” emulate with per-color state.
  • No blocking webRequest for normal extensions β€” use declarativeNetRequest (DNR) to modify headers.
  • DNR modifies headers before webRequest can read them β€” so DNR can't both strip and let us read Set-Cookie. The fix is a clean split of duties:
flowchart LR
    subgraph out [Outgoing request]
      A[Colored tab] -->|DNR sets Cookie to jar| B[Burp / server]
      A -->|DNR sets X-PwnFox-Color| B
    end
    subgraph in [Incoming response]
      B -->|Set-Cookie| C[webRequest read-only]
      C -->|store| D[(Per-color jar)]
      C -->|HttpOnly: remove from shared store| E[chrome.cookies]
    end
    D -.->|rebuilds| F[DNR Cookie rules]
    F -.-> A
Loading

Sending is fully controlled by DNR (synchronous, race-free): a catch-all remove Cookie rule gives the tab an empty session, plus one set Cookie rule per registrable domain injecting the container's jar. Receiving is observed by a read-only webRequest listener that captures Set-Cookie into the jar and removes HttpOnly cookies from the shared store so they can't leak to other containers.

Storage is handled by a MAIN-world shim injected on each navigation: it namespaces localStorage/sessionStorage by color and overrides document.cookie; an isolated-world relay.js forwards cookie writes back to the service worker.


Isolation: what's reliable, what's approximate

Important

For 100% native isolation (cookies + storage + IndexedDB + cache), use a separate Chrome profile per identity. PwnChrome emulates isolation inside a single profile β€” excellent for cookies, best-effort for storage.

Reliable

  • Colored tabs send only their container's cookies, even with many colors active at once (DNR is synchronous).
  • HttpOnly auth cookies are captured per color and kept out of the shared store.
  • Same color shares a jar; different colors are isolated.
  • Survives a browser restart: jars persist, and the tabβ†’color map is rebuilt from the restored 🦊 <color> tab groups on startup.
  • HTTP cache disabled for colored tabs (Cache-Control: no-store), so a cached resource can't leak between containers.

Approximations (by design)

Area Behavior
Jar keying Keyed by registrable domain (eTLD+1 via a small built-in suffix list). A site and its subdomains share cookies; host-only cookies may be over-sent to sibling subdomains.
Secure flag Not enforced on injected cookies (sent regardless of scheme) β€” fine for HTTPS targets.
Storage shim timing Injected as early as possible per navigation, but not guaranteed before the first page script; an early localStorage/document.cookie read may briefly see the shared store.
HTTP cache Not partitioned per container (the cache key ignores headers) β€” so it's disabled for colored tabs instead.
Not isolated IndexedDB and the Cache API (service-worker caches).

Permissions

Permission Why
declarativeNetRequest Inject X-PwnFox-Color and rewrite the Cookie header per container.
webRequest Read-only capture of Set-Cookie from responses.
cookies Remove HttpOnly container cookies from the shared store.
proxy One-click Burp proxy configuration.
scripting + webNavigation Inject the MAIN-world storage/cookie shim on navigation.
tabs + tabGroups Map tabs to colors and show containers as colored tab groups.
storage Persist config and cookie jars.
<all_urls> Containers and proxy apply to any site under test.

Project structure

PwnChrome/
β”œβ”€β”€ manifest.json          # MV3 manifest
β”œβ”€β”€ icons/                 # generated PNGs (gen_icons.py) + green/red status variants
└── src/
    β”œβ”€β”€ config.js          # shared config + color definitions
    β”œβ”€β”€ cookies.js         # cookie engine: parse/serialize, jar, registrable domain
    β”œβ”€β”€ background.js      # service worker: DNR rules, cookie capture, proxy, shim, icon
    β”œβ”€β”€ inject.js          # content script: toolbox injection
    β”œβ”€β”€ relay.js           # content script: relays document.cookie writes to the SW
    β”œβ”€β”€ popup/             # toolbar popup (containers, isolation toggles, proxy)
    └── options/           # proxy host/port + toolbox editor

Development & testing

The cookie engine and the service-worker logic are pure enough to test in Node with a stubbed chrome API (no browser needed):

  • src/cookies.js β€” Set-Cookie parsing, eTLD+1, jar merge/expiry, HttpOnly exclusion from document.cookie.
  • src/background.js β€” DNR rule construction, Set-Cookie capture β†’ jar β†’ rule rebuild, HttpOnly removal, multi-tab sharing per color, simultaneous distinct sessions across colors, restart reconcile, clearJar.

Regenerate the icons after editing gen_icons.py:

python3 icons/gen_icons.py

Warning

Live end-to-end testing via --load-extension is blocked on recent Chrome builds (the switch is ignored). Load the extension through chrome://extensions and verify behavior manually, or use the stubbed-chrome Node harness for logic.


Limitations vs Firefox PwnFox

Firefox PwnFox PwnChrome
Containers Native contextualIdentities Emulated per color
Cookie isolation Native, perfect DNR + webRequest (robust, eTLD+1-keyed)
Storage isolation Native MAIN-world shim (best-effort)
HTTP cache Isolated Disabled for containers (can't be partitioned)
IndexedDB / Cache API Isolated Not isolated (use separate profiles)
Proxy scope Per-request (per container possible) Global only β€” Chrome has no per-tab proxy API
X-PwnFox-Color yes yes β€” identical mapping
Remove security headers yes not included
postMessage logger yes not included

Proxy is global in Chrome: chrome.proxy.onRequest is Firefox-only and PAC scripts can't see tab IDs. When the proxy is on, all traffic goes through Burp β€” the color header still separates containers Burp-side.


Credits & license

  • Inspired by and interoperable with PwnFox by YesWeHack β€” the X-PwnFox-Color header and Burp extension are theirs.
  • Built for the Chromium/MV3 platform.

Use only against systems you are authorized to test.

Not affiliated with YesWeHack or PortSwigger.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages