From 86bb2b176b149f6c1726027f26eb5fcccd5aa61b Mon Sep 17 00:00:00 2001 From: Todd Schiller Date: Thu, 4 Jun 2026 17:19:46 -0400 Subject: [PATCH] Skip SVG text nodes in prompt-injection-redact (#133) Injection-shaped text inside an inline SVG's Codestin Search App + ${FIXTURES.OVERRIDE_GUARDRAILS} + ${FIXTURES.DISREGARD} + + + + `; + promptInjectionRedactRule.apply(document.body); + + expect(document.querySelector("article")).not.toBeNull(); + expect(document.querySelector("h1")?.textContent).toBe( + "Product title that stays visible.", + ); + expect(document.querySelector(`.${PLACEHOLDER_CLASS}`)).toBeNull(); + }); + it("does not process text inside SCRIPT or STYLE", () => { document.body.innerHTML = ` diff --git a/extension/src/rules/prompt-injection-redact.ts b/extension/src/rules/prompt-injection-redact.ts index 59572ef..63552fd 100644 --- a/extension/src/rules/prompt-injection-redact.ts +++ b/extension/src/rules/prompt-injection-redact.ts @@ -54,7 +54,16 @@ function findContainer(textNode: Text): HTMLElement | null { function apply(root: ParentNode): void { const containers = new Set(); - for (const node of walkTextNodes(root, { minLength: MIN_TEXT_LENGTH })) { + for (const node of walkTextNodes(root, { + minLength: MIN_TEXT_LENGTH, + // SVG /<desc>/<text> are the injection carriers inside SVG, and + // `svg-text-strip` handles them by blanking the text in place. Letting + // prompt-injection-redact also fire on those text nodes is destructive: + // the SVG has no p/li/td ancestor, so `findContainer` escalates all the + // way up to the surrounding <article>/<section> and the entire product + // header gets replaced with a single placeholder (#133). + shouldSkipParent: (parent) => parent.closest("svg") !== null, + })) { if (!containsInjection(node.nodeValue ?? "")) { continue; }