T09 · Insecure Skill Coding Practices
- Location
references/network-csp.md:96- Finding
Privileged Network Relay Uses Caller-Controlled URLs and Bypassable Allowlist Validation
- Content
View full analysis
{ if (message.type !== "__RELAY_FETCH") return false; // Security: validate sender is a content script in a tab if (!sender.tab?.id) { sendResponse({ error: "Unauthorized: not from a tab" }); return true; } // Security: validate URL against allowlist try { const url = new URL(message.url); const allowed = ALLOWED_ORIGINS.some((o) => message.url.startsWith(o)); if (!allowed) { sendResponse({ error: `URL not allowed: ${url.origin}` }); return true; } } catch { sendResponse({ error: "Invalid URL" }); return true; } fetch(message.url, message.init || {}) ``` The same unsafe design appears in the RPC example: ```typescript registerHandler("fetch.relay", async (params, sender) => { // Security: validate URL against allowlist const allowed = ["https://api.example.com", "https://cdn.example.com"]; if (!allowed.some((base) => params.url.startsWith(base))) { throw { code: 403, message: "URL not in allowlist" }; } const res = await fetch(params.url, { method: params.method ?? "GET", headers: params.headers, body: params.body, }); ``` Other quick-reference handlers perform an entirely unrestricted fetch: ```typescript if (msg.type === "FETCH") { const res = await fetch(msg.url); return { ok: res.ok, data: await res.text() }; } ``` ### Technical Analysis The service worker performs network requests using a URL, method, headers, and body supplied through extension messaging. ...[truncated 2541 chars]- Remediation
View remediation
