metadata
name: browser-engine-security
domain: browser
triggers:
languages:
- c
- cpp
- rust
- javascript
frameworks:
- v8
- spidermonkey
- jsc
- blink
- gecko
- webkit
- chromium
asset_types:
- browser
- engine
- jit
- renderer
- sandbox
tools:
- domato
- fuzzilli
- jsfunfuzz
- rr
- gdb
- lldb
severity_focus:
- P1
- P2
Browser Engine Security
When to load
V8, SpiderMonkey, JavaScriptCore, WebKit, Blink, Servo source trees; WebAssembly runtimes; PDF renderers shipped inside browsers.
Bug classes that pay (Pwn2Own / Chrome VRP / TCC tier)
- JIT type confusion β speculative type narrowing wrong; e.g. range analysis assumes int but value is double. Triggered by complex array/typed-array interplay.
- OOB in JIT'd code β bounds-check elimination over-aggressive;
arr[length-1]withlength= 0 turns into negative index. - Use-after-free in DOM β node removed during a callback while parent iteration holds a raw pointer.
- Renderer β sandbox escape β IPC message handler trusts renderer-controlled enum; Mojo interface allowing file path traversal.
- WebAssembly engine β JIT for SIMD / GC proposals, structural typing bugs in the new GC opcodes.
- PDF / image parser β PDFium, libwebp, libavif β these alone have produced $100K+ Chrome bounties.
- Site-isolation bypass β confused-deputy in process model, leaks of cross-origin secrets via timing or cache.
Methodology
- Read the recent fix landings β Chromium
chromium/srcrepo,masterbranch commits with[security]orFixed:referencingcrbug.com/<id>. Public 14 weeks after fix; unpublished bugs leave patterns visible. - Re-fuzz the patched function β use Fuzzilli with the patched binary; you're hunting for the next bug in the same area.
- Differential fuzzing β V8 vs JSC vs SpiderMonkey on the same corpus; output divergence = bug.
- Focus the fuzzer on the proposal under active development β intl, Temporal, GC, JSPI, ShadowRealm. New code = least audited.
- Symbolic execution on JIT IR β pin specific operations
(
Int32Add,LoadElement) with manticore-style constraints.
Exploitation pattern (modern V8)
- AddrOf primitive via leaked pointer in TypedArray length confusion.
- Arbitrary read/write by faking a JSArray with crafted map.
- Code execution by overwriting WebAssembly RWX page (post-V8 21, need pivot via builtin trampoline or RWX in the JIT compiler).
- Sandbox escape via separate Mojo bug β chain is required for the $100K+ payouts.
Reporting
Chrome VRP: file via g.co/vulnz, attach minimal repro <200 LOC>,
include exact commit hash you tested against, ASAN log, and a sentence
on the security boundary crossed.