fix(security): client href scheme check, outbound fetch timeouts, origin-scoped CORS (closes task/resolver-security-hardening)
Source: task/resolver-security-hardening (plan/steward-linker-security) — defense-in-depth: client trusted resolver href, outbound fetches had no timeout, CORS was blanket-*. - F1: extension/content.js makeLink re-validates primary.url scheme via a new pure Extract.isSafeHttpUrl helper (in extract.js, unit-tested); a non-http(s) url (javascript:/data:/garbage) is dropped and the plain text is kept. - F2: each of the three resolver outbound fetches (Spotify token, Spotify search, ollama /api/chat) now carries signal: AbortSignal.timeout(5000) so a hung upstream fails fast (caught per-candidate -> null), zero-dep. - F3: resolver CORS reflects the request Origin only for moz-extension://* or null (the extension's background-script origin), with Vary: Origin, instead of blanket access-control-allow-origin: *. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-1
@@ -119,5 +119,19 @@
|
||||
return all;
|
||||
}
|
||||
|
||||
return { matchesIn, cueMatchesIn, albumMatchesIn, allMatchesIn };
|
||||
// True only for http/https URLs — reject javascript:, data:, garbage, empty.
|
||||
// The resolver's url flows into an injected link's href, so the content script
|
||||
// re-validates the scheme client-side before assigning it (defense in depth; the
|
||||
// resolver already validates server-side, but a swapped/buggy one must not inject
|
||||
// a javascript:/data: href into reddit's DOM).
|
||||
function isSafeHttpUrl(u) {
|
||||
try {
|
||||
const p = new URL(u).protocol;
|
||||
return p === "http:" || p === "https:";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return { matchesIn, cueMatchesIn, albumMatchesIn, allMatchesIn, isSafeHttpUrl };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user