Files
Mangalord/frontend/src/lib/safeHref.ts
MechaCat02 958d5bd713 fix: scheme-validate crawler source_url before rendering as a link
Harvested source_url (external content) rendered as an admin <a href> without
scheme validation — a javascript:/data: link would execute on click (audit M2).
safeExternalHref() gates to http(s); CrawlerHistoryTable/DeadJobsTable fall back
to plain text otherwise. Tested in safeHref.test.ts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 21:16:08 +02:00

22 lines
830 B
TypeScript

/**
* Return `url` only if it is a well-formed `http(s)` URL that is safe to place
* in an `href`, otherwise `null`.
*
* Crawler `source_url` values are external/untrusted content harvested from
* scraped source sites. Svelte does NOT sanitize URL schemes in `href`
* bindings, so a harvested `javascript:`/`data:`/`vbscript:` link would execute
* (or phish) in the admin origin on click. Callers render the title as plain
* text when this returns `null`.
*/
export function safeExternalHref(url: string | null | undefined): string | null {
if (!url) return null;
let parsed: URL;
try {
parsed = new URL(url);
} catch {
// Relative or malformed — not a safe external link.
return null;
}
return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? url : null;
}