Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
**Vulnerability:** The application was passing unvalidated HTML variables, specifically `citation.formattedHtml`, to React's `dangerouslySetInnerHTML` prop in multiple components (`src/components/wiki/sortable-citation.tsx`, `src/app/cite/page.tsx`, `src/app/share/[code]/page.tsx`).
**Learning:** This is a classic pattern for Cross-Site Scripting (XSS). If a citation's contents originated from an untrusted source or were maliciously formatted, an attacker could execute arbitrary scripts in a user's session when the citation is rendered.
**Prevention:** Always sanitize any untrusted or dynamic HTML before rendering it in React. In a Next.js (SSR) application, use a library like `isomorphic-dompurify` to safely strip malicious scripts from the HTML payload on both the client and server side without hydration errors.
## 2025-05-01 - [XSS via unsanitized dangerouslySetInnerHTML]
**Vulnerability:** The application was passing unvalidated HTML variables, specifically `generatedCitation.html` in `src/components/wiki/citation-add-modal.tsx`, to React's `dangerouslySetInnerHTML` prop.
**Learning:** Similar to a previously discovered vulnerability pattern, untrusted HTML metadata (sourced from URLs, ISBNs, DOIs) was being injected into the DOM. This exposes the user session to Cross-Site Scripting (XSS) attacks.
**Prevention:** Always sanitize any untrusted or dynamic HTML before rendering it in React using a library like `isomorphic-dompurify`.
3 changes: 2 additions & 1 deletion src/components/wiki/citation-add-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from "react";
import { WikiButton } from "./wiki-button";
import { formatCitation } from "@/lib/citation";
import { buildCitationFields } from "@/lib/citation/build-fields";
import DOMPurify from "isomorphic-dompurify";
import type { CitationStyle, SourceType, CitationFields } from "@/types";

interface CitationAddModalProps {
Expand Down Expand Up @@ -266,7 +267,7 @@ export function CitationAddModal({
</p>
<p
className="text-wiki-text leading-relaxed"
dangerouslySetInnerHTML={{ __html: generatedCitation.html }}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(generatedCitation.html) }}
/>
</div>
)}
Expand Down
Loading