npm / jsdom / 30.1.3

jsdom 30.1.3

Source
https://github.com/jsdom/jsdom
Tag scanned
v30.1.3
Compared with
v30.1.2 (2 signals introduced since)
Files
884 scanned, 327 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 37 info
Scan time
9.0 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 13 of 13 warn and critical signals; 13 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-22 21:00

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review dynamic-import scripts/generate-css-style-properties.js:74:37 new in this release

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

        // The property implementations can be loaded now that their definitions have been generated.
        const { shorthandProperties } = require(path.resolve(cssDir, "helpers/shorthand-properties.js"));
        const longhandsByShorthand = new Map();
        const shorthandsByLonghand = new Map();
    likely benign LLM, confidence 0.85 Build script loads generated shorthand property definitions.
    Reasoning

    Build script requiring a generated helper module via path.resolve from a fixed directory. Non-literal require in a code generator is ordinary.

  2. [embedded javascript] `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

            JSON.parse(xhr.responseText).authorization,
            crossOrigin ? "" : `Basic ${btoa(`${user}:password`)}`
          );
        }, `${crossOrigin ? "Cross-origin" : "Same-origin"} redirect, challenge at ${challengeAt}, ` +
  3. info warn → info by review dynamic-import benchmark/lib.js:33:19

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

    async function runSuite(suiteName) {
      const factory = require(path.join(benchmarkDir, suiteName));
      const bench = factory();
      await bench.run();
    likely benign LLM, confidence 0.80 Benchmark runner dynamically requires a suite factory by path.
    Reasoning

    Dynamic require of a benchmark suite path built from a suite name in a test/benchmark harness. Non-literal require is a flag but the context is a local developer benchmark runner; input is not attacker-controlled in normal use.

  4. line length 797 characters (raw pass, confidence 0.50)

    		<p class="copyright"><a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2011 <a href="http://www.w3.org/"><acronym title="World Wide Web Consortium">W3C</acronym></a><sup>®</sup> (<a href="http://www.csail.mit.edu/"><acronym title="Massachusetts Institute of Technology">MIT</acronym><
  5. line length 532 characters (raw pass, confidence 0.50)

    		<code>::first-letter</code> pseudo-elements: font properties, ‘<code class="property">text-decoration</code>’, ‘<code class="property">text-transform</code>’, ‘<code class="property">letter-spacing</code>’, ‘<code class="property">word-spacing</code>’ (when appropriate), ‘<code class="property">line
  6. info warn → info by review dynamic-execution lib/jsdom/browser/Window.js:787:14

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

        try {
          return atob(str);
        } catch {
          // Convert Node.js DOMException to one from our global.
    likely benign LLM, confidence 0.85 Implements window.atob base64 decoding for jsdom.
    Reasoning

    atob is a standard browser API used to implement the window.atob method for decoding base64 strings; it is legitimate and not a dropper step by itself.

  7. info dynamic-execution lib/jsdom/browser/Window.js:799:14

    `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

        try {
          return btoa(str);
        } catch {
          // Convert Node.js DOMException to one from our global.
  8. info critical → info by review dynamic-execution lib/jsdom/living/helpers/create-event-accessor.js:128:7

    `Function(...)` called with a non-literal body (ast pass, confidence 0.75)

          // eslint-disable-next-line no-new-func
          Function(body); // properly error out on syntax errors
          // Note: this won't execute body; that would require `Function(body)()`.
        } catch (e) {
    likely benign LLM, confidence 0.85 Compiles inline event handler body text to validate syntax in jsdom.
    Reasoning

    Function(body) is used to compile event handler attribute bodies, as in the browser spec, and the comment shows it is only used to surface syntax errors without executing. This is a known legitimate pattern in jsdom, though it is dynamic code construction from attribute content.

  9. info warn → info by review dynamic-import scripts/generate-css-style-properties.js:122:32

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            descriptorSource = `${camelizedProperty}.descriptor`;
            const implementation = require(path.resolve(propertiesDir, fileName));
            if (typeof implementation.resolveComputedValue === "function") {
              computedValueResolverRequires.push(
    likely benign LLM, confidence 0.85 Build script requires per-property implementation modules.
    Reasoning

    Code generator requiring property implementation files from a fixed directory listing. Benign build-time behavior.

  10. info warn → info by review encoding-base64 test/api/resources.js:600:12

    base64-like blob (92 bytes, compression ratio 0.99) (raw pass, confidence 0.60)

            element.src = "data:image/png;base64," +
              "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkqAcAAIUAgUW0RjgAAAAASUVORK5CYII=";
            dom.window.document.body.appendChild(element);
    likely benign LLM, confidence 0.90 Test fixture containing a small base64 PNG data URI.
    Reasoning

    A small PNG data URI embedded in a test fixture for image loading. Standard test content.

  11. file mixes tab and space indentation (17 tab-indented and 180 space-indented lines) (raw pass, confidence 0.40)

    exports.assertSize = function(descr, expected, actual) {
      var actualSize;
      assertNotNull(descr, actual);
      actualSize = actual.length;
  12. info warn → info by review long-line test/to-port-to-wpts/files/image.txt:1:1

    line length 3510 characters (raw pass, confidence 0.65)

    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKgAAACoCAYAAAB0S6W0AAAABmJLR0QA/wD/AP+gvaeTAAAJ7ElEQVR4nO3dX0yb9R7H8c+zwijNYHQdDDY7UzaWoRSjXizTQyTRGJPGbEYvTAgX58QLY+LfeG2OXnuGjhtONq7Ikl2OiyVqtgRDiI5Ejes8IyBjggp2qx0g0FLb37n4DgseB33a56Hfnn1eSZNlK6W/X988/fX5tczC/ceU+g4UySr1HdhOO0p9B4g2w0BJNQZKqjFQUo2BkmoMlFRjoKQaAyXVGCipxk
    likely benign LLM, confidence 0.90 Base64 image data stored in a text fixture file.
    Reasoning

    A long line in a text file that is a base64-encoded image fixture for WPT porting. Fixture data, not executable.

  13. info critical → info by review dynamic-execution test/to-port-to-wpts/jquery-fixtures/jquery-1.11.0.js:8550:5

    `Function(...)` called with a non-literal body (ast pass, confidence 0.90)

    	}) ) ?
    		( Function( "return " + str ) )() :
    		jQuery.error( "Invalid JSON: " + data );
    };
    likely benign LLM, confidence 0.90 Vendored jQuery 1.11.0 JSON parsing fallback using Function constructor.
    Reasoning

    This is the well-known jQuery parseJSON fallback using Function to parse JSON when native JSON.parse is unavailable. It is a vendored library fixture with a standard legacy pattern.

  14. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        testNode = addressList.item(2);
        testNode.setAttribute("class", "Yα");
        attributes = testNode.attributes;
  15. identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        testNode = addressList.item(2);
        testNode.setAttribute("class", "Yα");
        attributes = testNode.attributes;
  16. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

    
        assert.equal(value, "Yα", "attrValue1");
      });
  17. info unicode-mixed-script test/to-port-to-wpts/level1/html.js:195:26

    identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

    
        assert.equal(value, "Yα", "attrValue1");
      });
  18. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        testNode = addressList.item(2);
        testNode.setAttribute("class", "Yα");
        attributes = testNode.attributes;
  19. info unicode-mixed-script test/to-port-to-wpts/level1/html.js:277:37

    identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        testNode = addressList.item(2);
        testNode.setAttribute("class", "Yα");
        attributes = testNode.attributes;
  20. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        let domesticAttr = doc.createAttribute("title");
        domesticAttr.value = "Yα";
        firstNode.setAttributeNode(domesticAttr);
        let attributes = doc.getElementsByTagName("acronym").item(2).attributes;
  21. identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

        let domesticAttr = doc.createAttribute("title");
        domesticAttr.value = "Yα";
        firstNode.setAttributeNode(domesticAttr);
        let attributes = doc.getElementsByTagName("acronym").item(2).attributes;
  22. file mixes tab and space indentation (5 tab-indented and 44 space-indented lines) (raw pass, confidence 0.40)

    <!ATTLIST svg 
    	xmlns CDATA #IMPLIED
    	xmlns:xsi CDATA #IMPLIED
    	xsi:schemaLocation CDATA #IMPLIED>
  23. file mixes tab and space indentation (3 tab-indented and 125 space-indented lines) (raw pass, confidence 0.40)

    
      var doc = new dom.Document("html");
      var implementation = new dom.DOMImplementation(doc, {
        "XML" : ["1.0", "2.0"],
  24. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        doc,
        doc.createEntityNode("alpha", doc.createTextNode("α")),
        doc.createEntityNode("beta", doc.createTextNode("&#946;")),
        doc.createEntityNode("gamma", doc.createTextNode("&#947;")),
  25. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

      addresses[3].setAttribute("title", "Yes");
      addresses[3].setAttribute("class", "Yα");
      addresses[3].appendChild(doc.createTextNode("27 South Road. Dallas, Texas 98556"));
      names[3].appendChild(doc.createTextNode("Jeny Oconnor"));
  26. identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

      addresses[3].setAttribute("title", "Yes");
      addresses[3].setAttribute("class", "Yα");
      addresses[3].appendChild(doc.createTextNode("27 South Road. Dallas, Texas 98556"));
      names[3].appendChild(doc.createTextNode("Jeny Oconnor"));
  27. identifier `α` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

        doc,
        doc.createEntityNode("alpha", doc.createTextNode("α")),
        doc.createEntityNode("beta", doc.createTextNode("&#946;")),
        doc.createEntityNode("gamma", doc.createTextNode("&#947;")),
  28. identifier `Yα` contains homoglyph candidates: α (03B1)→a (in string/comment) (raw pass, confidence 0.35)

      addresses[3].setAttribute("title", "Yes");
      addresses[3].setAttribute("class", "Yα");
      addresses[3].setAttribute("id", "emp4_addr");
      addresses[3].appendChild(doc.createTextNode("27 South Road. Dallas, Texas 98556"));
  29. identifier `Yα` mixes scripts: Latin + Greek (in string/comment) (raw pass, confidence 0.40)

      addresses[3].setAttribute("title", "Yes");
      addresses[3].setAttribute("class", "Yα");
      addresses[3].setAttribute("id", "emp4_addr");
      addresses[3].appendChild(doc.createTextNode("27 South Road. Dallas, Texas 98556"));
  30. [embedded javascript] orphaned high surrogate \uD800 (no matching low surrogate) (token pass, confidence 0.65)

      ["a\0b", "a\uFFFDb", "A null becomes a replacement character"],
      ["a\uD800b", "a\uFFFDb", "A lone high surrogate becomes a replacement character"],
      ["a\uDFFFb", "a\uFFFDb", "A lone low surrogate becomes a replacement character"],
      ["a\u{1F600}b", "a\u{1F600}b", "A non-BMP character is preserved"]
  31. [embedded javascript] orphaned low surrogate \uDFFF (no preceding high surrogate) (token pass, confidence 0.65)

      ["a\uD800b", "a\uFFFDb", "A lone high surrogate becomes a replacement character"],
      ["a\uDFFFb", "a\uFFFDb", "A lone low surrogate becomes a replacement character"],
      ["a\u{1F600}b", "a\u{1F600}b", "A non-BMP character is preserved"]
    ];
  32. [embedded javascript] `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

    promise_test(async t => {
      const href = `data:text/css;base64,${btoa(`@import "${importedURL}";`)}`;
      const doc = await loadFrame(t, `<link rel=stylesheet href="${href}">`);
      const link = doc.querySelector("link");
  33. [embedded javascript] `eval` called with a non-literal expression (ast pass, confidence 0.75)

    testNodes.forEach(function(referenceName) {
      var reference = eval(referenceName);
      testNodes.forEach(function(otherName) {
        var other = eval(otherName);
    likely benign LLM, confidence 0.85 WPT test uses eval to resolve named test node variables.
    Reasoning

    eval of node variable names in a WPT test HTML file, used to look up test nodes by identifier. Test-harness code with no external input; eval is poor style but not malicious.

  34. [embedded javascript] `eval` called with a non-literal expression (ast pass, confidence 0.75)

      testNodes.forEach(function(otherName) {
        var other = eval(otherName);
        test(function() {
          var result = reference.compareDocumentPosition(other);
    likely benign LLM, confidence 0.85 WPT test evals node name strings to fetch test nodes.
    Reasoning

    Same eval-based identifier lookup in a WPT compareDocumentPosition test. Benign test code.

  35. [embedded javascript] `new Proxy(window, ...)` interposes on a global object — every property read goes through the handler (ast pass, confidence 0.90)

      test(() => {
        const proxy = new Proxy(window, {});
        assert_throws_js(TypeError, () => new EventConstructor("test", { view: proxy }));
      }, `${EventConstructor.name} rejects a transparent proxy around Window as view`);
    likely benign LLM, confidence 0.85 WPT test passes a Proxy wrapping window to check constructor rejection.
    Reasoning

    A transparent Proxy around window is used to test that UIEvent constructor rejects non-Window views. This is a conformance test for spec behavior, not a hijack.

  36. info warn → info by review dynamic-import test/web-platform-tests/wpt-server.js:17:12

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

    const configs = {
      default: require(configPaths.default),
      toUpstream: require(configPaths.toUpstream)
    };
    likely benign LLM, confidence 0.85 WPT server loads default config module from a path variable.
    Reasoning

    Test server loads config files by path from a configPaths object defined in the same file. Non-literal require in test tooling is ordinary.

  37. info warn → info by review dynamic-import test/web-platform-tests/wpt-server.js:18:15

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

      default: require(configPaths.default),
      toUpstream: require(configPaths.toUpstream)
    };
    likely benign LLM, confidence 0.85 WPT server loads toUpstream config module from a path variable.
    Reasoning

    Same config loading pattern for the toUpstream config path. Benign test tooling.

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.1.0
git clone https://github.com/jsdom/jsdom jsdom && cd jsdom
git checkout v30.1.3
disclude scan --severity info --diff v30.1.2 .