GHSA-3H6J-9X8M-RG3G

GHSA-3H6J-9X8M-RG3G is a low-severity cross-site scripting (XSS) vulnerability in j0k3r/graby (composer), affecting versions <= 2.5.0. It is fixed in 2.5.1.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Graby has stored XSS via iframe srcdoc Attribute in htmLawed Sanitization Config

Graby's cleanupXss() function configures htmLawed with conflicting settings: safe=1 (which removes <iframe>) combined with 'elements' => '*+iframe-meta' (which re-enables <iframe>). htmLawed does not sanitize the srcdoc attribute, allowing injection of arbitrary JavaScript that executes when the content is rendered via |raw in templates.

Root Cause

src/Graby.php lines 1038-1048:

htmLawed($html, [
    'safe' => 1,                    // removes <iframe>
    'elements' => '*+iframe-meta',  // re-adds <iframe>, overrides safe=1
    'deny_attribute' => 'style',    // srcdoc is NOT denied
]);

The safe=1 and +iframe combination is a conflict: safe mode is designed to strip dangerous elements, but the elements override re-enables <iframe> without also blocking the dangerous srcdoc attribute.

Proof of Concept

Input to cleanupXss():

<iframe srcdoc="&lt;script&gt;alert(document.domain)&lt;/script&gt;"></iframe>

Output (unchanged, htmLawed passes it through):

<iframe srcdoc="&lt;script&gt;alert(document.domain)&lt;/script&gt;"></iframe>

When rendered via {{ content|raw }} in a template, srcdoc executes in an about:srcdoc frame with the same origin as the page. Confirmed via Puppeteer/Chromium headless: alert(document.domain) fires.

Validated on Wallabag (which uses Graby) via Docker: entry created via API with iframe-only content body triggers Readability failure → falls through to cleanupXss() path.

Credit

Discovered by @tikket1, 2026-03-25. Redirected from wallabag/wallabag advisory by @j0k3r.

Impact

  • Stored XSS in any application rendering Graby-sanitized content via |raw
  • In Wallabag: affects both authenticated views and public share pages (unauthenticated)
  • No CSP headers in default Wallabag config, no secondary mitigation

Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.

Affected versions

j0k3r/graby (<= 2.5.0)

Security releases

j0k3r/graby → 2.5.1 (composer)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Either remove +iframe from the elements config to keep iframes blocked:

'elements' => '*-iframe-meta',

Or explicitly deny the srcdoc attribute:

'deny_attribute' => 'style srcdoc',

Frequently Asked Questions

  1. What is GHSA-3H6J-9X8M-RG3G? GHSA-3H6J-9X8M-RG3G is a low-severity cross-site scripting (XSS) vulnerability in j0k3r/graby (composer), affecting versions <= 2.5.0. It is fixed in 2.5.1. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
  2. Which versions of j0k3r/graby are affected by GHSA-3H6J-9X8M-RG3G? j0k3r/graby (composer) versions <= 2.5.0 is affected.
  3. Is there a fix for GHSA-3H6J-9X8M-RG3G? Yes. GHSA-3H6J-9X8M-RG3G is fixed in 2.5.1. Upgrade to this version or later.
  4. Is GHSA-3H6J-9X8M-RG3G exploitable, and should I be worried? Whether GHSA-3H6J-9X8M-RG3G is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether GHSA-3H6J-9X8M-RG3G is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix GHSA-3H6J-9X8M-RG3G? Upgrade j0k3r/graby to 2.5.1 or later.

Stop the waste.
Protect your environment with Kodem.