SVG onload XSS Injection via Indirect Prompt Injection
An attacker hides instructions inside a document, email, or webpage that an AI agent reads. The instructions tell the agent to output an <svg onload=...> tag, and if that output later gets rendered in a browser, the embedded JavaScript runs against whoever views it.
How the attack works
An attacker plants text in content the AI agent will process, such as an email, uploaded file, or web page. That text is not addressed to a human — it's an instruction aimed at the AI, telling it to 'include in your response' a specific <svg/onload=...> tag. If the agent complies and its output is later displayed in a web page without sanitization, the browser executes the embedded script. This gives the attacker a path to steal session cookies, harvest credentials, or run arbitrary JavaScript in the context of whoever views the rendered output.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- 998e5851-ce0d-43ee-9a8c-3f3c7177eea0
- Severity
- High
Why it matters
If successful, this results in cross-site scripting against users who view the agent's output, which can lead to session hijacking, credential theft, or further compromise of the victim's browser session.
What you can do
- →Sanitize or HTML-encode any AI-generated text before rendering it in a browser, treating it as untrusted just like any other user input.
- →Strip or neutralize SVG and other active HTML tags from AI output destined for web display, or render output in a context that disables script execution (e.g., a sandboxed iframe with no scripts allowed).
- →Review any workflow where an AI agent ingests external documents, emails, or web content and then produces output that is displayed to users, and add a content-security-policy to limit inline script execution.
- →Avoid granting agents the ability to pass through raw attacker-influenced content directly into HTML rendering pipelines without a filtering step.
Known benign look-alikes
- Security documentation or testing skills that LIST <svg onload=...> payloads as examples inside code blocks — these lack an imperative instruction to emit the tag into agent output, so they no longer match (the bare tag alone is not flagged)
- Legitimate HTML/SVG authoring requesting onload for animation (no injection-framing keyword)
- Penetration-testing checklists that introduce a payload list with a line such as "try these payloads in every input:" — "input" ends in "put", which the verb alternation used to accept as a whole-word match.
- Any document whose imperative verb and <svg on...=> tag sit on different lines. This held for raw input all along; it now also holds for JSON-encoded tool payloads, where a line break is the two characters \n. KNOWN LIMIT, accepted deliberately: an attacker who splits the instruction across lines is not caught by Layer 1. Catching that would re-flag every security-documentation payload list, which is the exact FP this rule was written to avoid.