From 9c7074d561ccf396d2ff8cfbc85c95819ef2108d Mon Sep 17 00:00:00 2001 From: Aarav Sharma Date: Sun, 14 Jun 2026 08:29:32 -0600 Subject: [PATCH] chore(cors): broaden local origin matching for dev environments The previous localhost-only prefix check caused CORS failures when developers accessed the dev server via LAN IP (10.x, 172.16-31.x, 192.168.x), loopback (127.x), or IPv6 link-local/ULA addresses. This was common when using mobile devices on the same LAN for testing or when tunneling into the dev environment. Both gastown and wasteland were updated to use the same regex so they stay in sync. ## Summary - services/gastown/src/gastown.worker.ts - services/wasteland/src/wasteland.worker.ts --- services/gastown/src/gastown.worker.ts | 7 ++++--- services/wasteland/src/wasteland.worker.ts | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/services/gastown/src/gastown.worker.ts b/services/gastown/src/gastown.worker.ts index 86b6732a7e..d7bb8553c9 100644 --- a/services/gastown/src/gastown.worker.ts +++ b/services/gastown/src/gastown.worker.ts @@ -266,13 +266,14 @@ app.use('/api/mayor/:townId/tools/rigs/:rigId/agents/:agentId/*', async (c, next // ── CORS ──────────────────────────────────────────────────────────────── // Allow browser requests from the main Kilo app. In development, allow -// localhost origins for the Next.js dev server. +// localhost and LAN origins for the Next.js dev server. + +const localIpPattern = /^https?:\/\/(localhost|127\.\d+\.\d+\.\d+|10\.\d+\.\d+\.\d+|172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+|192\.168\.\d+\.\d+|\[(::1|fd[0-9a-f]{2}:[0-9a-f:]+|fe80:[0-9a-f:]+)\])(:\d+)?$/i; const corsMiddleware = cors({ origin: (origin, c: Context) => { if (c.env.ENVIRONMENT === 'development') { - // Allow any localhost origin in dev - if (origin.startsWith('http://localhost:')) return origin; + if (localIpPattern.test(origin)) return origin; } // Production origins const allowed = ['https://app.kilo.ai', 'https://kilo.ai']; diff --git a/services/wasteland/src/wasteland.worker.ts b/services/wasteland/src/wasteland.worker.ts index 9c7d3dd98e..b081f0df3f 100644 --- a/services/wasteland/src/wasteland.worker.ts +++ b/services/wasteland/src/wasteland.worker.ts @@ -89,12 +89,14 @@ app.use('*', async (c, next) => { // ── CORS ──────────────────────────────────────────────────────────────── // Allow browser requests from the main Kilo app. In development, allow -// localhost origins for the Next.js dev server. +// localhost and LAN origins for the Next.js dev server. + +const localIpPattern = /^https?:\/\/(localhost|127\.\d+\.\d+\.\d+|10\.\d+\.\d+\.\d+|172\.(1[6-9]|2[0-9]|3[0-1])\.\d+\.\d+|192\.168\.\d+\.\d+|\[(::1|fd[0-9a-f]{2}:[0-9a-f:]+|fe80:[0-9a-f:]+)\])(:\d+)?$/i; const corsMiddleware = cors({ origin: (origin, c: Context) => { if (c.env.ENVIRONMENT === 'development') { - if (origin.startsWith('http://localhost:')) return origin; + if (localIpPattern.test(origin)) return origin; } const allowed = ['https://app.kilo.ai', 'https://kilo.ai']; return allowed.includes(origin) ? origin : '';