July 28, 2026 at 12:00:00 AM UTC
linkat-directory sanitizes untrusted AT Protocol data before rendering it
linkat-directory
the security fix
Nothing rendered from remote AT Protocol data was previously validated. A board card's url went straight into an anchor href — a javascript: or data:text/html, value would have worked. Avatar/banner URLs went into <img src> and, worse, into an inline CSS url(), where a crafted value could break out of the declaration and inject further CSS. The PDS endpoint from the identity resolver was concatenated into fetch targets with no scheme check.
A new src/lib/utils/untrusted.ts centralizes the checks: link URLs restricted to http/https/mailto, media to http/https, CSS background URLs scheme-checked and quote-escaped, PDS origin required to be https with no credentials/path/query/fragment. Board records are now parsed defensively too — bounded to 100 cards per board and 500 characters per field, where a missing record.cards.length used to throw outright.
other fixes
- Same
pnpm-workspace.yamlplaceholder-boolean issue that brokewebsite-comm-template's install (pnpm 11 rejected the literal string"set this to true or false") — fixed, and the Vercel adapter runtime pinned tonodejs22.x. DynamicHeaddestructured$props()at the top level to build its metadata fallback chain — in Svelte 5 runes mode this only captures the initial value, so title/description/canonical URL never updated after the first page load. Rewritten with$derived.- Added
robots.txt/sitemap.xml(self-hosted directory, so absolute URLs derive fromPUBLIC_ORIGIN), removed a never-filled-in placeholder<meta name="author">, and stopped a malformedlocalStoragecache entry from breaking the whole profile load.
all entries