{"record":{"id":"fff4b5482128fa0f","repo":"davila7/claude-code-templates","slug":"cross-origin-request-rejected","errorCode":null,"errorMessage":"Cross-origin request rejected","messagePattern":"Cross-origin request rejected","errorType":"http","errorClass":null,"httpStatus":403,"severity":"warning","filePath":"cli-tool/src/sandbox-server.js","lineNumber":74,"sourceCode":"// CORS middleware — restrict to the local Studio UI origin only.\n// A wildcard (`*`) origin combined with the command-executing endpoints below\n// lets any web page the developer visits drive requests into this server\n// (drive-by RCE). Only allow the same-origin UI served from localhost:PORT.\nconst ALLOWED_ORIGINS = new Set([\n    `http://localhost:${PORT}`,\n    `http://127.0.0.1:${PORT}`,\n]);\napp.use((req, res, next) => {\n    const origin = req.headers.origin;\n    if (origin && ALLOWED_ORIGINS.has(origin)) {\n        res.header('Access-Control-Allow-Origin', origin);\n    }\n    res.header('Vary', 'Origin');\n    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');\n    // Reject cross-origin requests outright for the state-changing endpoints.\n    if (origin && !ALLOWED_ORIGINS.has(origin)) {\n        return res.status(403).json({ success: false, error: 'Cross-origin request rejected' });\n    }\n    if (req.method === 'OPTIONS') {\n        res.sendStatus(200);\n    } else {\n        next();\n    }\n});\n\n// JSON parsing middleware\napp.use(express.json());\n\n// Store active tasks\nconst activeTasks = new Map();\n\n// Serve the sandbox interface at root\napp.get('/', (req, res) => {\n    // Try local file first (when running from npm package)\n    const localPath = path.join(__dirname, 'sandbox-interface.html');","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-tool/src/sandbox-server.js#L56-L92","documentation":"HTTP 403 from the sandbox-server CORS middleware: any request carrying an Origin header not in the ALLOWED_ORIGINS set is rejected before reaching the state-changing endpoints. This is deliberate CSRF-style protection for a local sandbox server.","triggerScenarios":"A browser page on a non-allowed origin (e.g. an open port on localhost with a different port number, or a public website) makes a fetch to the sandbox server with credentials/content-type that attach an Origin header, and that origin isn't in ALLOWED_ORIGINS.","commonSituations":"Serving your frontend on a different port than the one allow-listed (localhost:3000 vs localhost:5173); accessing via 127.0.0.1 when only localhost is allowed (they are distinct origins); a malicious or accidental cross-site request from a web page you have open.","solutions":["Serve your client from an origin that's in ALLOWED_ORIGINS (check sandbox-server.js for the set) or add your exact origin (scheme+host+port) to it","Use http://localhost:PORT consistently rather than mixing 127.0.0.1 and localhost","If calling from Node/curl (no Origin header), the check is skipped — use a non-browser client for scripting","Confirm you're not accidentally embedding the sandbox URL in an external web page"],"exampleFix":"// before\n// client served at http://localhost:5173, only localhost:3000 allowed -> 403\n// after (sandbox-server.js)\nconst ALLOWED_ORIGINS = new Set(['http://localhost:3000', 'http://localhost:5173']);","handlingStrategy":"validation","validationCode":"const allowed = new Set(['http://localhost:3000']); // mirror server set\nif (typeof window !== 'undefined' && !allowed.has(window.location.origin)) {\n  console.warn('requests to sandbox server will be rejected from', window.location.origin);\n}","typeGuard":null,"tryCatchPattern":"catch (e) { if (e.status === 403 && /Cross-origin/.test(e.message)) showOriginHint(); else throw e; }","preventionTips":["Serve the UI and the sandbox server from the same origin/port","Pick one hostname (localhost) and stick to it","Keep the ALLOWED_ORIGINS set in sync with every port you develop on"],"tags":["cors","http-403","csrf-protection","browser"],"backgroundTag":"cors-origin-rejected","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}