From 3adba22ddf0333bf19f66c6978e2ced1ad887f19 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Sat, 12 Sep 2026 20:28:41 -0400 Subject: [PATCH] fix(security): bound KaTeX rendering of remote LaTeX maxSize 10, maxExpand 100, trust false, strict ignore, and a 5000-char cap (rendered as plain text beyond it), so a remote sender can't blow out layout or CPU with \rule{99999em} or deep macro expansion. Fixes #65 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA --- src/app/components/math/KaTeX.tsx | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/app/components/math/KaTeX.tsx b/src/app/components/math/KaTeX.tsx index ebaf17e7d..26d27cd68 100644 --- a/src/app/components/math/KaTeX.tsx +++ b/src/app/components/math/KaTeX.tsx @@ -21,12 +21,31 @@ type KaTeXProps = { * inline (in its error colour) rather than throwing. The HTML returned by * `renderToString` is produced by our own trusted call from a fixed options * object — it is safe to inject via `dangerouslySetInnerHTML`. + * + * `maxSize`/`maxExpand` cap how large a single glyph (`\\rule`, etc.) or macro + * expansion remote LaTeX can request, and `trust: false` disables commands + * that can embed arbitrary HTML/URLs (e.g. `\\includegraphics`, `\\href`) — + * without these a hostile `$$...$$` from a remote message can DoS or (via + * `trust`) inject unsafe links (Gitea #65). `strict: 'ignore'` keeps unknown- + * but-harmless LaTeX from spamming the console as before. Extremely long + * source is rendered as plain text rather than handed to KaTeX at all. */ +const MAX_LATEX_LENGTH = 5000; + export default function KaTeX({ latex, displayMode = false }: KaTeXProps) { + if (latex.length > MAX_LATEX_LENGTH) { + const Plain = displayMode ? 'div' : 'span'; + return {latex}; + } + const html = katex.renderToString(latex, { displayMode, throwOnError: false, output: 'htmlAndMathml', + maxSize: 10, + maxExpand: 100, + trust: false, + strict: 'ignore', }); const Wrapper = displayMode ? 'div' : 'span'; @@ -34,7 +53,7 @@ export default function KaTeX({ latex, displayMode = false }: KaTeXProps) { return ( );