NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
MEDIUM severity

Cross-Site Scripting (XSS) via SVG Schema innerHTML Injection in @pdfme/schemasGHSA-87v3-4cfp-cm76

MEDIUM

GHSA-87v3-4cfp-cm76 is a medium-severity (CVSS 6.1) Cross-site Scripting (XSS) vulnerability in @pdfme/schemas. A fix is available for @pdfme/schemas — see the affected versions and patch details below.

Also known asCVE-2026-82868
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 30, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for GHSA-87v3-4cfp-cm76.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs18th percentile — riskier than 18% of all scored CVEsHighest risk
0.00%0.25%0.51%0.76%0.2%0.3%0.3%Sep 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

10other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
@pdfme/schemasnpm
296Kdownloads / week

Description

Summary

The SVG schema plugin in @pdfme/schemas renders user-supplied SVG content using container.innerHTML = value without any sanitization, enabling arbitrary JavaScript execution in the user's browser.

Details

In packages/schemas/src/graphics/svg.ts, line 87, the SVG schema's ui renderer assigns raw SVG markup directly to innerHTML when in viewer mode or form mode with readOnly: true:

// svg.ts, line 81-94 (non-editable rendering path)
} else {
  if (!value) return;
  if (!isValidSVG(value)) {
    rootElement.appendChild(createErrorElm());
    return;
  }
  container.innerHTML = value;  // <-- VULNERABLE: unsanitized SVG injected into DOM
  const svgElement = container.childNodes[0];
  if (svgElement instanceof SVGElement) {
    svgElement.setAttribute('width', '100%');
    svgElement.setAttribute('height', '100%');
    rootElement.appendChild(container);
  }
}

The isValidSVG() function (lines 11-37) only validates that the string contains <svg and </svg> tags and passes DOMParser well-formedness checks. It does NOT strip or block:

  • <script> tags embedded in SVG
  • Event handler attributes (onload, onerror, onclick, etc.)
  • <foreignObject> elements containing HTML with event handlers
  • <animate> / <set> elements with onbegin / onend handlers
  • SVG <use> elements referencing malicious external resources

All of these are valid SVG and pass isValidSVG(), but execute JavaScript when inserted via innerHTML.

Attack Vectors

1. Malicious Template (readOnly SVG schema)

An attacker crafts a template JSON with a readOnly SVG schema containing a malicious content value. When loaded into the pdfme Form or Viewer component, the SVG executes JavaScript.

2. Application-Supplied Inputs + Viewer

If an application uses the pdfme Viewer component and passes user-controlled data as inputs for a non-readOnly SVG schema, the attacker's SVG flows directly to innerHTML.

Proof of Concept

Loading the following template into a pdfme Form or Viewer component triggers JavaScript execution:

{
  "basePdf": { "width": 210, "height": 297, "padding": [20, 20, 20, 20] },
  "schemas": [[
    {
      "name": "malicious_svg",
      "type": "svg",
      "content": "<svg xmlns='http://www.w3.org/2000/svg' onload='alert(document.domain)'><rect width='100' height='100' fill='red'/></svg>",
      "readOnly": true,
      "position": { "x": 20, "y": 20 },
      "width": 80,
      "height": 40
    }
  ]]
}

Additional payloads that bypass isValidSVG() and execute JavaScript:

<!-- Via foreignObject -->
<svg xmlns="http://www.w3.org/2000/svg"><foreignObject width="200" height="60"><body xmlns="http://www.w3.org/1999/xhtml"><img src="x" onerror="alert(1)"/></body></foreignObject></svg>

<!-- Via animate onbegin -->
<svg xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100"><animate attributeName="x" values="0" dur="0.001s" onbegin="alert(1)"/></rect></svg>

Impact

An attacker who can supply a malicious template (via file upload, shared template URL, multi-tenant template storage, or updateTemplate() API) can execute arbitrary JavaScript in the context of any user who views or fills the template. This enables:

  • Session hijacking via cookie/token theft
  • Keylogging of form inputs (including sensitive data being entered into PDF forms)
  • Phishing attacks by modifying the rendered page
  • Data exfiltration from the application

The attack is particularly concerning for multi-tenant SaaS applications using pdfme where templates may be user-supplied.

Suggested Fix

Sanitize SVG content before DOM insertion using DOMPurify or a similar library:

import DOMPurify from 'dompurify';

// Replace line 87:
container.innerHTML = DOMPurify.sanitize(value, { USE_PROFILES: { svg: true } });

Alternatively, parse the SVG via DOMParser, strip all script elements and event handler attributes, then append the sanitized DOM nodes.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@pdfme/schemasall versions5.5.9npm install @pdfme/schemas@5.5.9

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @pdfme/schemas, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update @pdfme/schemas to 5.5.9 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-87v3-4cfp-cm76 is resolved across your whole dependency graph.

  3. Workarounds

    Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page.

Frequently Asked Questions

## Summary The SVG schema plugin in `@pdfme/schemas` renders user-supplied SVG content using `container.innerHTML = value` without any sanitization, enabling arbitrary JavaScript execution in the user's browser. ## Details In `packages/schemas/src/graphics/svg.ts`, line 87, the SVG schema's `ui` renderer assigns raw SVG markup directly to `innerHTML` when in viewer mode or form mode with `readOnly: true`: ```typescript // svg.ts, line 81-94 (non-editable rendering path) } else { if (!value) return; if (!isValidSVG(value)) { rootElement.appendChild(createErrorElm()); return; }
O3 Security · Impact-Aware SCA

Is GHSA-87v3-4cfp-cm76 in your dependencies?

Find it across npm, including transitive dependencies.

Cross-Site Scripting (XSS) via SVG Schema innerHTML…