mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-17 17:07:07 +00:00
fix: harden extension security and plugin reliability
Address audit findings across background handlers, openers, plugins, and UI: URL allowlists, XSS reductions, popup lifecycle fixes, plugin dispose/cleanup, cloud sync hardening, global search mathjs sandbox, and settings storage fixes.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
const ALLOWED_HOST_SUFFIXES = [
|
||||
"betterseqta.org",
|
||||
"accounts.betterseqta.org",
|
||||
"raw.githubusercontent.com",
|
||||
"github.com",
|
||||
] as const;
|
||||
|
||||
function isPrivateOrLocalHost(hostname: string): boolean {
|
||||
const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
||||
if (host === "localhost" || host.endsWith(".localhost")) return true;
|
||||
if (host === "127.0.0.1" || host.startsWith("127.")) return true;
|
||||
if (host === "::1" || host === "0.0.0.0") return true;
|
||||
|
||||
const ipv4 = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
||||
if (ipv4) {
|
||||
const [a, b] = [Number(ipv4[1]), Number(ipv4[2])];
|
||||
if (a === 10) return true;
|
||||
if (a === 172 && b >= 16 && b <= 31) return true;
|
||||
if (a === 192 && b === 168) return true;
|
||||
if (a === 169 && b === 254) return true;
|
||||
if (a === 127 || a === 0) return true;
|
||||
}
|
||||
|
||||
if (host.includes(":")) {
|
||||
const h = host.split("%")[0];
|
||||
if (h.startsWith("fe80") || h.startsWith("fc") || h.startsWith("fd")) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAllowedHost(hostname: string): boolean {
|
||||
const host = hostname.toLowerCase();
|
||||
return ALLOWED_HOST_SUFFIXES.some(
|
||||
(suffix) => host === suffix || host.endsWith(`.${suffix}`),
|
||||
);
|
||||
}
|
||||
|
||||
/** HTTPS-only fetch allowlist for background `fetchFromUrl`. */
|
||||
export function isAllowedFetchUrl(urlString: string): boolean {
|
||||
let parsed: URL;
|
||||
try {
|
||||
parsed = new URL(urlString);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
if (parsed.protocol !== "https:") return false;
|
||||
if (isPrivateOrLocalHost(parsed.hostname)) return false;
|
||||
return isAllowedHost(parsed.hostname);
|
||||
}
|
||||
Reference in New Issue
Block a user