defuddle vulnerable to XSS via unescaped string interpolation in _findContentBySchemaText image tag
Date: 2026-03
Affected: npm/defuddle
Attack vector: xss
Category: vulnerability-disclosure
Severity: Low
CVE: CVE-2026-30830
CWE: CWE-79

### Summary The `_findContentBySchemaText` method in `src/defuddle.ts` interpolates image `src` and `alt` attributes directly into an HTML string without escaping: ```typescript html += `<img src="${imageSrc}" alt="${imageAlt}">`; ``` An attacker can use a `"` in the `alt` attribute to break out of the attribute context and inject event handlers. This is a separate vulnerability from the sanitization bypass fixed in f154cb7 — the injection happens during string construction, not in the DOM, so `_stripUnsafeElements` cannot catch it. ### Details When `_findContentBySchemaText` finds a sibling image outside the matched content element, it reads the image's `src` and `alt` attributes via `getAttribute()` and interpolates them into a template literal. `getAttribute('alt')` returns the raw attribute value. If the alt contains `"`, it terminates the `alt` attribute in the interpolated HTML string, and subsequent content becomes new attributes (including event handlers). The recently added `_stripUnsafeElements()` (commit f154cb7) strips `on*` attributes from DOM elements, but the `alt` attribute's name is `alt` (not `on*`), so it is preserved with its full value. The `onload` handler is created by the string interpolation, not present in the original DOM. ### PoC Input HTML: ```html <!DOCTYPE html> <html> <head> <title>PoC</title> <script type="application/ld+json"> {"@type": "Article", "text": "Long article text repeated many times to exceed the extracted content word cou


Mitigations:

Architectural layers (MAESTRO):