feat(giskard-checks): add XSSOutputCheck for OWASP LLM02 output safety 🤖🤖🤖🤖 - #2517
feat(giskard-checks): add XSSOutputCheck for OWASP LLM02 output safety 🤖🤖🤖🤖#2517nuthalapativarun wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces XSSOutputCheck, a deterministic check designed to detect potential Cross-Site Scripting (XSS) payloads in LLM outputs (OWASP LLM02) using regular expressions. It also includes comprehensive unit tests. The review feedback points out two important issues: first, the regex pattern for event handlers (r"on\w+\s*=") is too broad and will cause false positives on common variables like online = True, so it should be restricted to specific event handlers. Second, a test case meant to verify the data URI pattern actually triggers the script tag pattern instead, which should be corrected to ensure accurate pattern matching.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| _XSS_PATTERNS: list[tuple[str, str]] = [ | ||
| (r"<script", "script tag"), | ||
| (r"javascript\s*:", "javascript: URI"), | ||
| (r"on\w+\s*=", "event handler attribute"), |
There was a problem hiding this comment.
The regex pattern r"on\w+\s*=" is highly prone to false positives. It will match common safe words and variable assignments starting with "on" followed by an equals sign (e.g., online = True, only = 1, one = "value", ongoing = ...).
To prevent these false positives, restrict the pattern to a specific list of common HTML event handlers (e.g., onclick, onload, onerror, etc.) and use a word boundary \b.
| (r"on\w+\s*=", "event handler attribute"), | |
| (r"\bon(?:click|load|error|mouseover|focus|blur|change|submit)\s*=", "event handler attribute"), |
| ("x=eval;x('alert(1)')", "eval() call"), | ||
| ("steal(document.cookie)", "document.cookie access"), | ||
| ("var c = document . cookie;", "document.cookie access"), | ||
| ('src="data:text/html,<script>alert(1)</script>"', "data: URI with script"), |
There was a problem hiding this comment.
The test case input 'src="data:text/html,<script>alert(1)</script>"' contains <script, which matches the first pattern r"<script" (labeled "script tag") instead of the intended "data: URI with script" pattern. This causes the test assertion to fail.
To correctly test the data URI pattern, use an input where the mime-type contains script but does not contain <script, such as "data:text/javascript,alert(1)".
| ('src="data:text/html,<script>alert(1)</script>"', "data: URI with script"), | |
| ("data:text/javascript,alert(1)", "data: URI with script"), |
|
Addressed both issues from the bot review:
|
0863a13 to
9602306
Compare
…llowlist Replace the broad on\w+\s*= pattern with an explicit allowlist of HTML event handler names to eliminate false positives on identifiers like online=True or onboarding_status. Fix the data: URI test case which previously triggered the script-tag pattern instead of the data-URI pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9602306 to
5a788af
Compare
|
Rebased this branch onto the latest
The Ready for a human review whenever convenient. Thanks! |
|
Bumping this — the XSS output check is ready to merge, CI is just sitting on the |
|
Hi team — following up on PR #2517 (XSSOutputCheck). Rebased 2026-06-27; MERGEABLE; same |
davidberenstein1957
left a comment
There was a problem hiding this comment.
Thanks for the careful work here — the allowlist fix for event handlers and the corrected data-URI test case are solid, and the test coverage is thorough.
We're not going to land this shape as written. I just left guidance on #2454 that applies directly here:
- We already have
RegexMatching+Not(...)for deterministic payload detection. A dedicatedXSSOutputCheck(and follow-ups for SQLi / shell / path) hardcodes one pattern catalog into the public checks API without enough reuse to justify four near-identical check types. - LLM02-style coverage belongs in scan as an opt-in scenario generator + probe data (same pattern as LLM01 /
PromptInjectionScenarioGenerator), not as first-class builtin checks ingiskard-checks. - Regex on model text is a payload-emission heuristic, not full insecure output handling — that caveat should live with the scan probes/docs, not as a permanent
XSSOutputChecksurface.
What we'd take instead
If you're still interested in contributing:
- A
giskard-scanscenario generator taggedowasp:llm-top-10-2025:LLM02/threat-type:insecure-output-handling - Seed prompts (JSONL or similar) that try to elicit XSS / SQLi / shell / path payloads
- Wire checks with existing
Not(RegexMatching(...)), patterns as data — not newChecksubclasses - Opt-in via the vulnerability suite registry (not default-on for every scan)
Happy to review a PR along those lines. Please don't open separate follow-up PRs for SQLi / Shell / Path checks in this style — one generator + pattern data is enough.
Sorry for the long wait on human review; the CI authorize gate and silence weren't a great experience. Appreciate the patience and the quality of the contribution.
|
Also: please drop or change |
Description
Adds
XSSOutputCheck, the first check in the OWASP LLM02 output-handling detectors pack. Detects common XSS payload patterns in LLM output using regex matching.Additional detectors (SQLi, Shell injection, Path traversal) will follow in separate PRs.
Related Issue
Closes #2454
Type of Change
Checklist