From 17d76d628040c22b78e43eaea26965abd0eceb0e Mon Sep 17 00:00:00 2001 From: web3dev1337 <160291380+web3dev1337@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:56:00 +1000 Subject: [PATCH 1/4] fix: allow WSL2 172.x subnet in CORS origin whitelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WSL2 uses a 172.x.x.x virtual network — browsers connecting via the WSL IP were rejected by the CORS policy added in the public-release security hardening. Co-Authored-By: Claude Opus 4.6 (1M context) --- server/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/index.js b/server/index.js index e0ff7c97..4decef5a 100644 --- a/server/index.js +++ b/server/index.js @@ -238,7 +238,8 @@ const io = new Server(httpServer, { origin.startsWith('http://localhost:') || origin.startsWith('http://127.0.0.1:') || origin.startsWith('http://[::1]:') || - origin.startsWith('http://100.'); + origin.startsWith('http://100.') || + origin.startsWith('http://172.'); if (allowed) { callback(null, true); From 0463993f348853c6c370ee85ee933f5f20845759 Mon Sep 17 00:00:00 2001 From: web3dev1337 Date: Sat, 18 Jul 2026 11:53:59 +1000 Subject: [PATCH 2/4] fix: scope WSL2 CORS whitelist to the private 172.16.0.0/12 block Review feedback: a bare "http://172." prefix whitelists all of 172.0.0.0/8, which includes active public internet space (Cloudflare 172.64/13, Google 172.217/16). WSL2 vEthernet addresses only come from the RFC1918 172.16-172.31 range, so match exactly that. Co-Authored-By: Claude Fable 5 --- server/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/index.js b/server/index.js index 4decef5a..3c723c1c 100644 --- a/server/index.js +++ b/server/index.js @@ -239,7 +239,10 @@ const io = new Server(httpServer, { origin.startsWith('http://127.0.0.1:') || origin.startsWith('http://[::1]:') || origin.startsWith('http://100.') || - origin.startsWith('http://172.'); + // WSL2 vEthernet addresses live in the RFC1918 172.16.0.0/12 block + // (172.16-172.31 only) — a bare "172." prefix would also whitelist + // public internet space (e.g. Cloudflare/Google ranges in 172/8). + /^http:\/\/172\.(1[6-9]|2\d|3[01])\./.test(origin); if (allowed) { callback(null, true); From 7c2be67428de9a1c1390b454d9712cdd0b199877 Mon Sep 17 00:00:00 2001 From: web3dev1337 Date: Sun, 19 Jul 2026 09:47:12 +1000 Subject: [PATCH 3/4] feat: allow the remaining RFC1918 private ranges in the CORS whitelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Devices on the home LAN reach the orchestrator through the Windows portproxy with origins like http://192.168.0.53:2080, which the whitelist rejected — Socket.IO connections from a phone or second PC failed even though the private 172.16/12 (WSL) and CGNAT 100/8 (Tailscale) ranges were already allowed. Adds 192.168/16 and 10/8; all public space stays blocked. Co-Authored-By: Claude Fable 5 --- server/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server/index.js b/server/index.js index 3c723c1c..ce70f86d 100644 --- a/server/index.js +++ b/server/index.js @@ -239,10 +239,14 @@ const io = new Server(httpServer, { origin.startsWith('http://127.0.0.1:') || origin.startsWith('http://[::1]:') || origin.startsWith('http://100.') || - // WSL2 vEthernet addresses live in the RFC1918 172.16.0.0/12 block - // (172.16-172.31 only) — a bare "172." prefix would also whitelist - // public internet space (e.g. Cloudflare/Google ranges in 172/8). - /^http:\/\/172\.(1[6-9]|2\d|3[01])\./.test(origin); + // Private (RFC1918) ranges only — home/office LAN devices reaching the + // orchestrator via the Windows portproxy (phone, second PC) present + // origins like http://192.168.0.53:2080. A bare "172." prefix would + // also whitelist public internet space (e.g. Cloudflare/Google ranges + // in 172/8), so the 172 block is matched exactly (172.16-172.31). + /^http:\/\/172\.(1[6-9]|2\d|3[01])\./.test(origin) || + origin.startsWith('http://192.168.') || + origin.startsWith('http://10.'); if (allowed) { callback(null, true); From abfd491e41aaa7bdfcf8acd0523a9b981af60d77 Mon Sep 17 00:00:00 2001 From: web3dev1337 Date: Sun, 19 Jul 2026 12:34:51 +1000 Subject: [PATCH 4/4] chore: use a generic example address in the CORS comment Co-Authored-By: Claude Fable 5 --- server/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/index.js b/server/index.js index ce70f86d..ab417951 100644 --- a/server/index.js +++ b/server/index.js @@ -241,7 +241,7 @@ const io = new Server(httpServer, { origin.startsWith('http://100.') || // Private (RFC1918) ranges only — home/office LAN devices reaching the // orchestrator via the Windows portproxy (phone, second PC) present - // origins like http://192.168.0.53:2080. A bare "172." prefix would + // origins like http://192.168.1.23:2080. A bare "172." prefix would // also whitelist public internet space (e.g. Cloudflare/Google ranges // in 172/8), so the 172 block is matched exactly (172.16-172.31). /^http:\/\/172\.(1[6-9]|2\d|3[01])\./.test(origin) ||