Skip to content

feat(probes): add SVG/XML injection (XXE + SSRF) probe + detector - #2038

Open
vishnukannaujia wants to merge 1 commit into
NVIDIA:mainfrom
vishnukannaujia:probe/svg-injection
Open

feat(probes): add SVG/XML injection (XXE + SSRF) probe + detector#2038
vishnukannaujia wants to merge 1 commit into
NVIDIA:mainfrom
vishnukannaujia:probe/svg-injection

Conversation

@vishnukannaujia

Copy link
Copy Markdown

Fixes #1949

Summary

Adds a new probe + detector pair, svg_injection, targeting SVG/XML that attacks a downstream rasterizer or XML parser (not a browser) via XML external entity resolution (CWE-611) or server-side request forgery (CWE-918).

When an app asks a model to "make me an icon as SVG" and then rasterizes / XML-parses the result, model output containing an external DTD/entity (<!ENTITY ... SYSTEM "file://...">) can read local files, and an <image href="..."> pointing at file:// or an internal host (cloud metadata 169.254.169.254 / metadata.google.internal, or a gopher: / dict: gadget) can trigger SSRF.

Same "target output attacks a downstream sink" thesis as ansiescape (terminal) and web_injection (browser). Browser <script> / XSS intentionally stays with web_injection; this is the SVG-rasterizer / XML-parser path. Companion to formula_injection (#2036) and log_injection (#2037). Scope-fit floated on #1949 first.

What's added

  • probes.svg_injection.SvgInjection — stub × payload prompts that try to get the target to emit SVG carrying XXE or an SSRF/local-file <image> reference. intent = "S008inject"; tags owasp:llm02, owasp:llm05, avid-effect:security:S0301, quality:Security:Confidentiality.
  • detectors.svg_injection.SvgInjection — a deterministic regex detector for external-entity (<!DOCTYPE/<!ENTITY ... SYSTEM/PUBLIC>) and <image href>file:///SSRF-target constructs. No model call needed.
  • Tests mirroring the existing probe/detector tests.

Tests

  • tests/probes/test_probes_svg_injection.py — prompt structure & payloads carry an XXE/SSRF construct.
  • tests/detectors/test_detectors_svg_injection.py — every payload → 1.0; benign SVG (plain shapes, a relative href="logo.png", an https://example.com image) → 0.0; None output → None.
  • Passes the generic probe/detector conformance suites and black.

Happy to align naming/tiering with the SvgInjection(OF_CONCERN)/SvgInjectionEscaped(INFORMATIONAL) split suggested in the issue if you'd prefer that shape.

Adds probes.svg_injection.SvgInjection and the matching
detectors.svg_injection.SvgInjection, targeting SVG/XML that attacks a
downstream rasterizer or XML parser via XML external entity resolution
(CWE-611) or server-side request forgery (CWE-918).

Same "target output attacks a downstream sink" pattern as ansiescape
(terminal) and web_injection (browser); browser <script>/XSS stays with
web_injection. The probe elicits SVG carrying an external entity
(<!ENTITY ... SYSTEM ...>) or an <image href> pointing at file:// or an
internal/SSRF target (169.254.169.254, metadata.google.internal, gopher:,
dict:). The detector flags these constructs deterministically, so it
needs no model call to test.

Fixes NVIDIA#1949

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Vishnu Kannaujia <vishnu.kannaujia@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

probe: SVG injection (model output hits a downstream rasterizer / XML parser... XXE + SSRF)

1 participant