diff --git a/.jules/sentinel.md b/.jules/sentinel.md index b5cd688..65c73f5 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -15,3 +15,9 @@ **Vulnerability:** Running `pnpm install` in the agent environment caused an unintended downgrade of `lucide-react` in `pnpm-lock.yaml`. **Learning:** The agent's global or cached `pnpm` version/config might conflict with the project's lockfile, especially when specific versions are pinned in `package.json`. **Prevention:** Always verify lockfile changes after installation and use `git checkout` to restore unrelated changes if they occur. + +## 2026-07-05 - [XSS in Custom Markdown Renderer] + +**Vulnerability:** The custom markdown-lite renderer in `blog.$slug.tsx` was using `dangerouslySetInnerHTML` without escaping the input text, allowing arbitrary HTML injection. +**Learning:** Custom renderers using `dangerouslySetInnerHTML` must escape all HTML special characters (&, <, >, ", ') *before* applying safe transformations (like regex-based bolding or links) to ensure defense-in-depth. +**Prevention:** Use a shared `escapeHTML` utility and a "strict escape first, then transform" pattern for any manual HTML construction. diff --git a/src/lib/api.ts b/src/lib/api.ts index 0773474..7fff65f 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -182,6 +182,15 @@ export function sanitizeNumero(numero: unknown): string { return ""; } +export function escapeHTML(s: string): string { + return s + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + export function normalize(s: string): string { if (!s || typeof s !== "string") return ""; return s diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 96a30ec..1464a14 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -403,3 +403,13 @@ const rootRouteChildren: RootRouteChildren = { export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { startInstance } from './start.ts' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + config: Awaited> + } +} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 735b26e..fa62d30 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -126,7 +126,7 @@ export function createSeoMeta(config: SeoConfig) { * Sécurise une chaîne JSON pour injection dans une balise