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
feat(socks5): added internal SOCKS5 parser for local testing
- Implement internal SOCKS5 parser in relay server for direct target dialing in local tests.
- Add postMessage hooks to preserve frame target origins across compartments.
- Add stable test runner for consistent local and CI test execution.
- Update README and ARCHITECTURE documentation for internal SOCKS5 mode.
- Extend E2E test suite with additional proxy behavior and origin validation.
Copy file name to clipboardExpand all lines: README.md
+20-11Lines changed: 20 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,10 +3,10 @@
3
3
ZeroProxy is a client-owned virtual browsing prototype that runs target pages on the proxy origin without a browser extension. Its design goal is that target-site HTTP, TLS, and WebSocket traffic leaves only through this path:
4
4
5
5
```text
6
-
Service Worker -> Go WASM kernel -> WebSocket/yamux -> Tor SOCKS5 -> uTLS -> HTTP/2 or HTTP/1.1
6
+
Service Worker -> Go WASM kernel -> WebSocket/yamux -> SOCKS5 CONNECT -> uTLS -> HTTP/2 or HTTP/1.1
7
7
```
8
8
9
-
The relay server terminates only the browser WebSocket/yamux pipe. Target HTTP parsing, redirects, cookies, header policy, HTML rewriting, and target WebSocket framing are owned by the Go WASM kernel and browser-side runtime.
9
+
The relay server terminates only the browser WebSocket/yamux pipe. In production it byte-bridges each yamux stream to a Tor SOCKS5 listener; for local compatibility tests `-socks internal` makes the relay parse the kernel's SOCKS5 CONNECT itself and dial the requested target directly. Target HTTP parsing, redirects, cookies, header policy, HTML rewriting, and target WebSocket framing are owned by the Go WASM kernel and browser-side runtime.
10
10
11
11
## Status
12
12
@@ -18,16 +18,16 @@ Implemented core spine:
18
18
- AES-256-CBC + HMAC-SHA256 URL envelope with HKDF-separated encryption/MAC keys and HMAC verification before decryption.
19
19
- Service Worker request classifier that handles every controlled request, blocks unknown requests instead of falling back to native `fetch(event.request)`, and requires a per-tab runtime capability token on privileged runtime bridge messages.
20
20
- Go WASM exports: `__go_jshttp`, `__zp_stream`, `__zp_kernel_init`, and `__zp_cookie_set`.
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
-
- 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`.
21
+
- A single browser WebSocket pipe carrying yamux streams to the relay server, then SOCKS5 DOMAINNAME CONNECT, uTLS for HTTPS, HTTP/2 when ALPN selects `h2`, and HTTP/1.1 fallback/direct handling. `-socks 127.0.0.1:9050` preserves the Tor bridge; `-socks internal` is a Tor-free development/test mode that parses SOCKS5 on the relay and dials targets directly from the relay process.
22
+
- Tokenizer-based HTML transform that injects the runtime prelude, launders executable external scripts through `/__zp/api/script?u=...`, rewrites iframe/frame document URLs to encrypted `/p` routes, preserves author-visible anchor/form attributes for runtime navigation interception, drops dangerous tags and headers, strips executable event attributes through the JS rewriter, and handles `srcdoc`.
23
23
- Runtime containment for main-window `fetch`, XHR, EventSource, WebSocket, `sendBeacon`, navigation, forms, history/location masking, storage facades, workers, iframes, and high-risk device/network APIs. Main-window and worker `fetch` paths are bridged through `/__zp/api/fetch` so strict `connect-src 'self'` does not block target API calls before the Service Worker can route them. Runtime-to-Service-Worker control messages carry a closure-held per-tab capability token. 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
- Phase 2 JavaScript rewriting is wired through an OXC parser/WASM service: target-response CSP no longer permits `connect-src *`, external and inline script sources are parsed before execution, dangerous global/window/location access is rewritten to runtime membrane helpers, parse/transform failures fail closed, and dynamic compilation paths such as `Function`, constructor-constructor escapes, `eval`, and string timers execute under the runtime's virtual global scope; blob/data worker scripts remain blocked when they cannot be rewritten synchronously.
25
25
- Relay server static asset service and `/__zp/ws-pipe` WebSocket endpoint.
26
26
- Go and JavaScript share URL implementations that use the same envelope format.
27
27
28
28
Not complete enough for production or high-assurance acceptance:
29
29
30
-
- 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
+
- Browser E2E tests cover internal SOCKS5 relay mode, dynamic script laundering, compound location assignments, iframe postMessage delivery, iframe clean-realm containment, and basic fingerprint-masking checks, but do not yet prove every worker, direct navigation, form, device API, and unclassified subresource non-escape path.
31
31
- Dynamic iframe containment is synchronous for `contentWindow`/`contentDocument` reads and common insertion APIs, but remains prototype-level and should keep gaining adversarial browser coverage.
32
32
- Main-window runtime API compatibility is prototype-level for fetch, XHR, EventSource, WebSocket, uploads, descriptor edge cases, and fingerprinting surface fidelity.
33
33
- Response bodies are streamed into JavaScript `Response` objects, but request/upload body handling and browser backpressure/cancellation behavior are still prototype-level.
@@ -41,7 +41,7 @@ See [`ARCHITECTURE.md`](./ARCHITECTURE.md) for the implementation map and accept
41
41
- Go 1.26 or the Go toolchain version required by `go.mod`.
42
42
- Node.js LTS and npm for the JavaScript and Puppeteer E2E tests.
43
43
- A browser with Service Worker and WebAssembly support. CI uses Puppeteer's pinned Chrome for Testing.
44
-
- A Tor SOCKS5 listener configured with stream isolation for manual target browsing. CI uses an in-process test SOCKS5 proxy instead of Tor.
44
+
- A Tor SOCKS5 listener configured with stream isolation for anonymized manual target browsing. Tor is not required for the automated Puppeteer suite or local compatibility checks that run the relay with `-socks internal`.
45
45
46
46
Example Tor setting:
47
47
@@ -58,6 +58,14 @@ tor --SocksPort "127.0.0.1:9050 IsolateSOCKSAuth" --DataDirectory /tmp/zeroproxy
58
58
59
59
Keep that process running and wait until Tor logs `Bootstrapped 100% (done)` before expecting target browsing to work. If Tor is managed by your OS service manager instead, use the same `SocksPort` setting in `torrc` and start the service before starting ZeroProxy.
60
60
61
+
For Tor-free local compatibility testing, start ZeroProxy with the internal relay SOCKS5 parser instead of starting Tor:
Internal mode is not an anonymity mode: target TCP connections are direct dials from the relay process. It exists so CI and local browser compatibility tests can exercise the browser → Service Worker → WASM → WebSocket/yamux → SOCKS5 parsing pipeline without an external proxy daemon.
68
+
61
69
## Build and run locally
62
70
63
71
Build the browser bundle, Go WASM kernel, and relay server from the repository root:
@@ -92,15 +100,15 @@ Server flags:
92
100
-`-addr`: HTTP listen address. Default: `:8080`.
93
101
-`-web`: built static web asset directory containing `index.html`, `sw.js`, and `/__zp/*` assets. Default: `dist/web`.
94
102
-`-kernel`: compiled Go WASM kernel served at `/__zp/kernel.wasm`. Default: `dist/kernel.wasm`.
95
-
-`-socks`: Tor SOCKS5 address. Default: `127.0.0.1:9050`.
103
+
-`-socks`: Tor SOCKS5 address, or `internal` for the relay's built-in SOCKS5 CONNECT parser/direct dialer used by tests. Default: `127.0.0.1:9050`.
96
104
97
105
Open the browser shell on the proxy origin:
98
106
99
107
```text
100
108
http://proxy.localhost:8080/
101
109
```
102
110
103
-
Use `proxy.localhost` from the start so the shell, Service Worker, and encrypted `/p/<encrypted>#k=<key>` routes share one origin. The server starts even if Tor is not reachable, but target browsing needs the configured Tor SOCKS5 listener.
111
+
Use `proxy.localhost` from the start so the shell, Service Worker, and encrypted `/p/<encrypted>#k=<key>` routes share one origin. The server starts even if Tor is not reachable. Target browsing needs either a configured Tor SOCKS5 listener or the explicit non-anonymous `-socks internal` test mode.
104
112
105
113
## Verification commands
106
114
@@ -113,11 +121,11 @@ npm test
113
121
npm run build
114
122
```
115
123
116
-
`npm test` runs both JavaScript source-policy tests and the Puppeteer E2E suite. The E2E test builds temporary ZeroProxy artifacts with `scripts/build.mjs`, starts a local target HTTP server, starts an in-process SOCKS5 proxy, launches Puppeteer's Chrome, and verifies browser traffic through the ZeroProxy server without requiring Tor.
124
+
`npm test` runs both JavaScript source-policy tests and the Puppeteer E2E suite. The E2E test builds temporary ZeroProxy artifacts with `scripts/build.mjs`, starts a local target HTTP server, starts the relay with `-socks internal`, launches Puppeteer's Chrome, and verifies browser traffic through the ZeroProxy server without requiring Tor.
117
125
118
126
CI is defined in `.github/workflows/ci.yml` and runs on pushes to `main`, pull requests, and manual dispatch. It uses an Ubuntu 24.04 LTS runner, installs Go from `go.mod`, installs the current Node.js LTS release, runs `npm ci`, runs the Go and full JavaScript/Puppeteer test suites, and builds deployable `dist/` artifacts.
119
127
120
-
These checks cover source/unit policy invariants, buildability, and a local-browser E2E path through a test SOCKS5 proxy. They do not start Tor, validate real Tor deployment behavior, or prove production traffic compatibility.
128
+
These checks cover source/unit policy invariants, buildability, and a local-browser E2E path through the relay's internal SOCKS5 parser/direct dialer. They do not start Tor, validate real Tor deployment behavior, or prove production traffic compatibility.
121
129
122
130
## Repository map
123
131
@@ -127,8 +135,9 @@ These checks cover source/unit policy invariants, buildability, and a local-brow
127
135
|`web/sw.js`| Service Worker classifier, in-memory tab state, runtime API bridge, WASM kernel calls. |
128
136
|`web/runtime-prelude.js`, `web/worker-prelude.js`| Target-realm containment hooks and worker bootstrap. |
129
137
|`scripts/build.mjs`| Full build pipeline for browser bundles, generated WASM support assets, Go WASM kernel, and relay server. |
138
+
|`scripts/test.mjs`| Stable local/CI test runner that executes JavaScript policy tests and the Puppeteer E2E suite in sequence. |
130
139
|`cmd/wasm-kernel`| Go WASM transport kernel exposed to the Service Worker. |
131
-
|`cmd/zeroproxy-server`| Static asset server and Gorilla WebSocket/yamux-to-Tor relay. |
140
+
|`cmd/zeroproxy-server`| Static asset server and Gorilla WebSocket/yamux relay to Tor SOCKS5 or the `-socks internal` direct-dial SOCKS5 parser. |
132
141
|`internal/zphttp`, `internal/socks5`, `internal/utlskernel`, `internal/wsproto`, `internal/yamuxconn`, `internal/wsconn`| Target transport path. |
133
142
|`internal/htmltx`, `internal/headers`, `internal/cookiejar`, `internal/shareurl`, `internal/zpiso`| HTML rewriting, response header policy, cookie handling, share URL envelope, Tor isolation tokens. |
134
143
|`test/js`, `test/e2e`, `internal/*/*_test.go`| JavaScript source-policy tests, Puppeteer browser E2E tests, and Go unit tests. |
flag.StringVar(&s.webDir, "web", "dist/web", "built static web asset directory")
35
38
flag.StringVar(&s.kernelWASM, "kernel", "dist/kernel.wasm", "compiled Go WASM kernel path")
36
-
flag.StringVar(&s.socksAddr, "socks", "127.0.0.1:9050", "Tor SOCKS5 address configured with IsolateSOCKSAuth")
39
+
flag.StringVar(&s.socksAddr, "socks", "127.0.0.1:9050", "Tor SOCKS5 address with IsolateSOCKSAuth, or 'internal' for the built-in test SOCKS5 parser/direct dialer")
0 commit comments