Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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