You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
│ ├─ navigation, form, history, location, and getter masking hooks
21
21
│ ├─ storage namespace facades
22
22
│ ├─ worker and iframe containment hooks
23
+
│ ├─ basic self-fingerprint masking hooks
23
24
│ └─ WebRTC/WebTransport/device API blocking stubs
24
25
└─ transformed target HTML as the top-level document
25
26
@@ -41,7 +42,7 @@ The relay server terminates only the browser WebSocket and yamux session. It use
41
42
- Target TCP connections are opened through WebSocket -> yamux -> Tor SOCKS5 DOMAINNAME. The kernel does not call `http.Transport` for target egress.
42
43
- HTTPS uses uTLS over the Tor stream with ALPN selecting HTTP/2 when available and HTTP/1.1 fallback; target WebSocket upgrade pins HTTP/1.1.
43
44
- Target response headers are passed through a constructor policy before the browser receives a `Response`.
44
-
-Runtime code does not install anti-bot deception hooks such as `Function.prototype.toString` masking.
45
+
-Anti-bot spoofing is not a project goal. The runtime applies limited self-fingerprint masking only to reduce trivial detection of its own hooks and host-resource leaks (`Function.prototype.toString`, Canvas/Audio extraction jitter, and speech voice lists).
45
46
46
47
## Main components
47
48
@@ -50,7 +51,7 @@ The relay server terminates only the browser WebSocket and yamux session. It use
| Share URL envelope |`web/zp-core.js`, `internal/shareurl/*`| Compatible JavaScript and Go implementations of `/p/<encrypted>#k=<key>` using AES-256-CBC, HMAC-SHA256, HKDF, and raw base64url. |
52
53
| Service Worker |`web/sw.js`| Classifies every controlled request, blocks unknowns, manages in-memory tab/entry state, calls the WASM kernel, exposes runtime bridge APIs. |
53
-
| Runtime prelude |`web/runtime-prelude.js`, `web/worker-prelude.js`| Installs target-realm containment hooks before target scripts run. Main-window WebSocket/navigation/form/history/location/storage/worker/iframe/device APIs are hooked; main-window fetch/XHR/EventSource are not runtime-polyfilled today. Worker `fetch` is bridged through `/__zp/api/fetch`. |
54
+
| Runtime prelude |`web/runtime-prelude.js`, `web/worker-prelude.js`| Installs target-realm containment hooks before target scripts run. Main-window WebSocket/navigation/form/history/location/storage/worker/iframe/device APIs are hooked; main-window fetch/XHR/EventSource are not runtime-polyfilled today. Worker `fetch` is bridged through `/__zp/api/fetch`. Patched function source strings, Canvas/Audio extraction, and speech voices receive basic masking to reduce runtime self-fingerprinting, not to provide full anti-bot spoofing. |
@@ -107,19 +108,19 @@ The Go WASM kernel exposes `__zp_kernel_init`, `__go_jshttp`, `__zp_stream`, and
107
108
108
109
`internal/headers.ConstructorPolicy` strips target-controlled policy, storage, network-control, hop-by-hop, redirect, and transformed-body headers before constructing a browser `Response`. It defaults cache behavior to `Cache-Control: no-store`.
109
110
110
-
`web/runtime-prelude.js` installs hooks for high-risk browser APIs from inside the target realm. Main-window WebSocket, `sendBeacon`, navigation, forms, history/location masking, storage facades, Worker/SharedWorker constructors, service worker registration blocking, high-risk device/network API blockers, and iframe containment attempts are present. Click navigation handles normal anchors plus script-created elements that carry a URL-valued `href` property, which covers sites that navigate from button click handlers. Main-window `fetch`, XHR, and EventSource currently rely on Service Worker fetch interception instead of dedicated runtime wrappers; worker `fetch` is wrapped by `web/worker-prelude.js` through `/__zp/api/fetch`.
111
+
`web/runtime-prelude.js` installs hooks for high-risk browser APIs from inside the target realm. Main-window WebSocket, `sendBeacon`, navigation, forms, history/location masking, storage facades, Worker/SharedWorker constructors, service worker registration blocking, high-risk device/network API blockers, and synchronous iframe containment are present. Click navigation handles normal anchors plus script-created elements that carry a URL-valued `href` property, which covers sites that navigate from button click handlers. Main-window `fetch`, XHR, and EventSource currently rely on Service Worker fetch interception instead of dedicated runtime wrappers; worker `fetch` is wrapped by `web/worker-prelude.js` through `/__zp/api/fetch`. The runtime also masks patched function source strings, jitters Canvas/Audio readout APIs, and fixes `speechSynthesis.getVoices()` to a Windows Chrome-shaped list as a basic self-fingerprint defense.
111
112
112
113
Browser `window.location` cannot be made indistinguishable from the target origin from ordinary page JavaScript in a same-origin proxy document: many `Location` properties are browser-owned/unforgeable and the real address bar origin remains the proxy origin. ZeroProxy therefore uses best-effort getter masking plus navigation traps, and treats Service Worker/CSP classification as the security boundary.
113
114
114
-
Current limitation: dynamic iframe hardening is not yet the synchronous clean-realm containment required for acceptance. Some paths instrument iframes after creation or insertion, which leaves a high-risk gap that must be closed or proven blocked by browser E2E tests.
115
+
Current limitation: spoofing is deliberately narrow. These masking hooks reduce obvious proxy/runtime fingerprints and host-resource contradictions, but they are not a complete CreepJS/FingerprintJS anti-detection system and should not be treated as an anonymity proof.
115
116
116
117
## Plan implementation assessment
117
118
118
119
Overall status: **Phase 0 prototype / partial implementation**. The repository implements the primary architecture spine and many security-critical primitives from `PLAN.md`, but it is not yet complete enough to treat as an accepted high-assurance browsing engine.
119
120
120
121
| PLAN.md section | Current status | Evidence / gap |
121
122
|---|---|---|
122
-
| 0. Correction directives | Partial | Top-level target document, encrypted `/p` route shape, AES-CBC+HMAC share envelope, and no anti-bot spoofing hooks are present. Strict `connect-src` is not fully implemented by `web/zp-core.js`; browser direct-egress prevention still needs E2E proof. |
123
+
| 0. Correction directives | Partial | Top-level target document, encrypted `/p` route shape, AES-CBC+HMAC share envelope, limited runtime self-fingerprint masking, and synchronous iframe clean-realm containment are present. Strict `connect-src` is not fully implemented by `web/zp-core.js`; browser direct-egress prevention still needs broader E2E proof. |
123
124
| 1. System goals | Partial | Client memory state, unknown-request blocking, Tor/yamux/uTLS path, and safe errors exist. Encrypted IndexedDB persistence and full escape-vector coverage are absent. |
124
125
| 2. Overall architecture | Mostly implemented | Static shell, Service Worker, Go WASM kernel, relay WebSocket pipe, yamux, SOCKS5, uTLS, HTTP/2 and HTTP/1.1 fetch, HTML transform, cookie jar, and runtime prelude exist. |
125
126
| 3. URL and encryption | Implemented |`web/zp-core.js` and `internal/shareurl` implement HKDF, AES-256-CBC, HMAC verification-before-decrypt, raw base64url, and protocol allowlists. Tests cover JS tamper rejection and Go envelope construction. |
@@ -131,13 +132,13 @@ Overall status: **Phase 0 prototype / partial implementation**. The repository i
131
132
| 9. Tor stream isolation | Implemented at code level |`zpiso.Token` derives site-granular HMAC tokens; SOCKS5 rejects IP literals and sends DOMAINNAME ATYP. Deployment still requires correctly configured Tor. |
| 11. Phase 0 CSP | Partial | The shell and server apply Phase 0-style CSP headers. The server's `zeroCSP` restricts `connect-src` to `'self'` and the proxy WebSocket origin, but `web/zp-core.js` currently generates `connect-src * blob: data: <ws-origin>` for Service Worker-constructed target responses, so the strict PLAN `connect-src` invariant is not met. |
134
-
| 12. Runtime prelude | Partial | WebSocket, `sendBeacon`, navigation/form/history/location, storage, worker, iframe, and device blockersexist. Main-window fetch/XHR/EventSource runtime wrappers are absent; those requests rely on Service Worker fetch interception. XHR/EventSource/WebSocket fidelity is prototype-level, and direct `location.href` defense relies on layered CSP/SW enforcement where descriptors cannot be replaced. |
135
+
| 12. Runtime prelude | Partial | WebSocket, `sendBeacon`, navigation/form/history/location, storage, worker, iframe, device blockers, basic patched-function/Canvas/Audio/speech masking, and synchronous iframe containment exist. Main-window fetch/XHR/EventSource runtime wrappers are absent; those requests rely on Service Worker fetch interception. XHR/EventSource/WebSocket and fingerprinting-surface fidelity are prototype-level, and direct `location.href` defense relies on layered CSP/SW enforcement where descriptors cannot be replaced. |
135
136
| 13. Worker containment | Partial | Worker/SharedWorker constructors, data/blob workers, service worker registration blocking, worklet addModule wrapping, and worker prelude exist. Worker APIs are not all routed with browser-native fidelity; several are blocked. |
136
-
| 14. Dynamic iframe containment | Partial / high risk | Iframe creation/insertion/src/srcdoc hooks and about:blankcontainment exist, but clean about:blankrealm hardening is not yet synchronous enough for acceptance. |
137
+
| 14. Dynamic iframe containment | Partial | Iframe creation/insertion/src/srcdoc hooks and synchronous `contentWindow`/`contentDocument`containment exist for clean about:blankrealms. Broader browser coverage is still needed for adversarial descriptor and navigation edge cases. |
137
138
| 15. History/location | Partial |`pushState`, `replaceState`, `popstate`, scroll restore, bound `location.assign`/`replace` navigation helpers, click-time navigation capture, and best-effort getter masking are present. Native `window.location` cannot be fully spoofed to another origin in a standard same-origin proxy document, so browser descriptor edge cases need E2E coverage. |
138
139
| 16. Cookie jar | Mostly implemented | Go jar stores `Set-Cookie`, excludes HttpOnly from `document.cookie`, enforces path/domain/secure, and projects cookies onto target requests. Runtime document.cookie has a lightweight parallel model and should be reconciled with the Go jar behavior. |
139
140
| 17. Safe error pages | Mostly implemented | Required error class names and safe HTML pages exist in core, Service Worker, kernel, and server. Error mapping is coarse and should be made more precise. |
140
-
| 18. Mandatory successor review | Not complete | Source/unit tests cover selected invariants, but required browser E2E bypass tests for dynamic iframes, workers, direct navigation, and native escape vectors have not been implemented. |
141
+
| 18. Mandatory successor review | Not complete | Source/unit tests cover selected invariants, and browser E2E covers the current dynamic iframe and basic fingerprint-masking paths. Required browser E2E coverage for workers, direct navigation, native escape vectors, forms, and unclassified subresources remains incomplete. |
141
142
142
143
### Notable current deltas from PLAN.md
143
144
@@ -146,7 +147,7 @@ Overall status: **Phase 0 prototype / partial implementation**. The repository i
146
147
- The PLAN topbar/virtual address bar injection was intentionally removed; `internal/htmltx/topbar.go` documents that target pages stay on `/p` routes while runtime getters mask target location values.
147
148
- Main-window fetch/XHR/EventSource runtime wrappers from PLAN §12 are not implemented. Controlled network requests are expected to be caught by the Service Worker fetch handler; worker `fetch` is bridged separately by `worker-prelude.js`.
148
149
- PLAN's strict `connect-src 'self' <proxy-websocket-origin>` is not fully met for target responses because `web/zp-core.js` emits `connect-src * blob: data: <ws-origin>`.
149
-
- Target response bodies stream into JavaScript `Response` objects, but request/upload body handling, dynamic iframe clean-realm containment, encrypted IndexedDB persistence, and required browser E2E escape tests are not acceptance-grade.
150
+
- Target response bodies stream into JavaScript `Response` objects, but request/upload body handling, broader dynamic iframe edge cases, encrypted IndexedDB persistence, and required browser E2E escape tests are not acceptance-grade.
150
151
151
152
## Verification surface
152
153
@@ -169,7 +170,7 @@ CI environment and gates:
169
170
-`GOOS=js GOARCH=wasm go build -o /tmp/zeroproxy-kernel.wasm ./cmd/wasm-kernel`.
The Puppeteer E2E test does not require Tor. It builds temporary ZeroProxy binaries, starts a local target HTTP server, starts an in-process SOCKS5 server that accepts the kernel's SOCKS5 username/password handshake, launches Chrome against `proxy.localhost`, and verifies that proxied navigation stays on `/p` routes while target HTTP requests carry the configured Windows Chrome User-Agent.
173
+
The Puppeteer E2E test does not require Tor. It builds temporary ZeroProxy binaries, starts a local target HTTP server, starts an in-process SOCKS5 server that accepts the kernel's SOCKS5 username/password handshake, launches Chrome against `proxy.localhost`, and verifies that proxied navigation stays on `/p` routes while target HTTP requests carry the configured Windows Chrome User-Agent. It also covers the current synchronous dynamic-iframe containment path and basic runtime fingerprint-masking invariants.
173
174
174
175
Equivalent local commands:
175
176
@@ -188,7 +189,7 @@ These checks prove unit/source policy coverage, buildability, and one local brow
188
189
Treat the implementation as a working Phase 0 prototype until all of these are satisfied:
189
190
190
191
1. Browser E2E tests prove that target pages cannot escape through dynamic iframes, workers, direct navigation, native WebSocket, WebRTC, WebTransport, device APIs, forms, or unclassified subresources.
191
-
2.Iframe instrumentation is made synchronous for clean about:blank realms or those iframes are blocked before target script regains control.
192
+
2.Broader adversarial iframe descriptor, navigation, and nested-realm edge cases are browser-tested beyond the current clean about:blank coverage.
192
193
3. Runtime wrapper behavior is hardened for expected browser API fidelity, especially XHR, WebSocket close/error semantics, EventSource streaming, FormData/file uploads, and descriptor edge cases.
193
194
4. Request/upload body streaming, cancellation, and backpressure semantics are hardened where required.
194
195
5. Cookie, storage, and history semantics are reconciled across runtime state, Service Worker state, and Go kernel state.
Copy file name to clipboardExpand all lines: README.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,15 +20,15 @@ Implemented core spine:
20
20
- Go WASM exports: `__go_jshttp`, `__zp_stream`, `__zp_kernel_init`, and `__zp_cookie_set`.
21
21
- A single browser WebSocket pipe carrying yamux streams to the relay server, then Tor SOCKS5 DOMAINNAME CONNECT, uTLS for HTTPS, HTTP/2 when ALPN selects `h2`, and HTTP/1.1 fallback/direct handling.
22
22
- Tokenizer-based HTML transform that injects the runtime prelude, launders document navigation URLs through encrypted `/p` routes, drops dangerous tags and headers, and handles `srcdoc`.
23
-
- Runtime containment for WebSocket, `sendBeacon`, navigation, forms, history/location masking, storage facades, workers, iframes, and high-risk device/network APIs. Main-window `fetch`, XHR, and EventSource currently rely on Service Worker interception rather than runtime polyfills; worker `fetch` is bridged through `/__zp/api/fetch`.
23
+
- Runtime containment for WebSocket, `sendBeacon`, navigation, forms, history/location masking, storage facades, workers, iframes, and high-risk device/network APIs. Main-window `fetch`, XHR, and EventSource currently rely on Service Worker interception rather than runtime polyfills; worker `fetch` is bridged through `/__zp/api/fetch`. The runtime also applies basic self-fingerprint masking for patched function source strings, Canvas/Audio extraction jitter, and speech voice lists; broad anti-bot spoofing is not a project goal.
24
24
- Relay server static asset service and `/__zp/ws-pipe` WebSocket endpoint.
25
25
- Go and JavaScript share URL implementations that use the same envelope format.
26
26
27
27
Not complete enough for production or high-assurance acceptance:
28
28
29
-
- Browser E2E tests do not yet prove dynamic iframe, worker, direct navigation, native WebSocket, WebRTC/WebTransport, device API, form, and unclassified subresource non-escape.
30
-
- Dynamic iframe clean-realm containment is still weaker than the synchronous hardening required for acceptance.
31
-
- Main-window runtime API compatibility is prototype-level for fetch, XHR, EventSource, WebSocket, uploads, and descriptor edge cases.
29
+
- Browser E2E tests cover the current iframe clean-realm and basic fingerprint-masking checks, but do not yet prove every worker, direct navigation, form, device API, and unclassified subresource non-escape path.
30
+
- Dynamic iframe containment is synchronous for `contentWindow`/`contentDocument` reads and common insertion APIs, but remains prototype-level and should keep gaining adversarial browser coverage.
31
+
- Main-window runtime API compatibility is prototype-level for fetch, XHR, EventSource, WebSocket, uploads, descriptor edge cases, and fingerprinting surface fidelity.
32
32
- Response bodies are streamed into JavaScript `Response` objects, but request/upload body handling and browser backpressure/cancellation behavior are still prototype-level.
33
33
- Encrypted IndexedDB persistence is not implemented.
34
34
- Tor daemon deployment and real Tor-egress E2E validation are not included in this repository.
0 commit comments