---
title: "CVE-2026-61500: Rejetto HFS Fixed in July, Attacked a Day After the Mythos Write Up"
description: "Horizon3 used Anthropic's Mythos to find a Math.random flaw in Rejetto HFS. The fix shipped July 13, the technical write up landed September 30, and attacks began the next day."
author: "Jahanzaib Ahmed"
date: 2026-10-05
category: "trends"
readingTime: "8 min read"
tags: ["ai news", "anthropic", "mythos", "ai-security", "node.js", "vulnerability"]
canonical: https://www.jahanzaib.ai/blog/rejetto-hfs-cve-2026-61500-mythos
source: https://www.jahanzaib.ai
---
# CVE-2026-61500: Rejetto HFS Fixed in July, Attacked a Day After the Mythos Write Up

CVE-2026-61500 is a critical flaw in Rejetto HFS, an open source file server, and Anthropic's Mythos model found it for Horizon3 researcher Zach Hanley. The fix shipped on July 13. Horizon3 published its technical write up on September 30, and the next evening VulnCheck's canary servers caught a China hosted attacker going after real HFS hosts. If you run HFS, update to 3.2.1 or later today. Node.js developers should read the grep section.

## How Horizon3 says Mythos found CVE-2026-61500

Horizon3 joined Anthropic's restricted access [Project Glasswing](https://www.anthropic.com/project/glasswing) in July and runs [Mythos inside its own vulnerability research pipeline](https://horizon3.ai/attack-research/disclosures/anthropic-mythos-rejetto-hfs-rce/). Hanley pointed that pipeline at HFS 3.x, the TypeScript rewrite of the old Delphi server. One of the many agents it spawns looks only for cryptographic weakness, and it flagged the way HFS builds its session cookies.

The chain it found has two parts. HFS signs session cookies with a key built from `Math.random()`. And the unauthenticated login handshake hands the client another raw `Math.random()` output on every call. A second agent re-read the code and confirmed the finding as a true positive. Then Mythos wrote the proof of concept itself, with a Z3 solver doing the maths, and ran an arbitrary command on the server.

Horizon3 says nobody told the model to chain the two facts. The team writes that it had dropped this kind of cryptographic bug before, because it lacked the maths background and because the exploit took too long to be worth weaponizing. It credits Mythos with supplying both the maths and the patience.

79 daysfrom the [3.2.1 release](https://github.com/rejetto/hfs/releases/tag/v3.2.1) on July 13 to Horizon3's September 30 write up

1 dayfrom write up to first attack, per [The Register](https://www.theregister.com/security/2026/10/03/anthropics-super-bug-hunting-model-mythos-is-hardcore-good-at-math-as-latest-vuln-under-attack-shows/5300933) and VulnCheck

12leaked `Math.random()` outputs Horizon3 samples before solving

## Fixed July 13, explained September 30

The timeline matters more than the exploit. The [VulnCheck advisory](https://www.vulncheck.com/advisories/rejetto-hfs-session-forgery-via-predictable-signing-key) is dated July 13, scores the flaw 9.3 on CVSS 4.0, and lists HFS 3.0.0 up to but not including 3.2.1 as affected. The HFS release notes for that day say only that multiple security vulnerabilities were found and credit Hanley together with Anthropic Research. No details, no exploit.

The project also tried to warn its own users. The [release commit](https://github.com/rejetto/hfs/commit/15f0eb32f856016b6a3a04c8679b9a12eb18c203) edits the update metadata so that versions in the affected range are flagged as dangerous with a request to update. So the warning existed and the patch existed. What did not exist was a public explanation of how to exploit the bug, until September 30.

| Date | Event | Source |
| --- | --- | --- |
| July 13 | HFS 3.2.1 released, advisory dated, CVSS 9.3 | HFS release |
| September 30 | Horizon3 publishes the Mythos write up, 79 days later | Horizon3 |
| October 1 | VulnCheck canaries see a China hosted attacker | The Register |
| October 2 | Four more hits from two US addresses | The Register |

My read: a quiet advisory protected nobody who was not already patching, and a detailed write up turned the bug into a race that attackers started within a day. The Register reports 286 CVEs on VulnCheck's tracker for Mythos and Glasswing, with only one seen exploited before Thursday.

## Why the leak mattered more than the weak key

Using `Math.random()` for a secret is a known mistake. Alone, it would not have been enough here, because an attacker needs to see outputs of the generator to predict it. HFS supplied them. The [fix commit](https://github.com/rejetto/hfs/commit/59472e534bf7e056d708382d02935c2eaf956927) shows both halves being replaced.

![Six step attack chain for CVE-2026-61500: login request, leaked number, recover state, rewind to key, forge cookie, run code](https://cdn.sanity.io/images/qajb7q5q/production/9335216f1c87056e956ed74d19fcedb18efc264e-1376x768.png?w=1200&q=75&auto=format&fit=max)

_The weak link is the leaked number. Remove it, or use a real random source for the key, and the chain breaks._

1.  **The weak key.** With no `COOKIE_SIGN_KEYS` setting, HFS generated its Koa cookie key from three consecutive `Math.random()` calls at startup. Horizon3 explains that V8 uses xorshift128+ for this, and that its outputs can be run backwards.
2.  **The leak.** The login step stored `Math.random()` as a handshake identifier, and the session cookie is signed but not encrypted, so the client can read it. Per Horizon3, any valid username is enough to get the number back, no password needed.
3.  **The solve.** Feed the observed numbers to Z3, recover the generator state, step it back to startup, rebuild the key and check it against your own signed cookie.
4.  **The payoff.** Sign a session for the admin user, then use the admin API's custom code feature to run commands on the host.

The raw Mythos output quoted in the Horizon3 write up says recovery works because the leaked numbers and the key come from the same V8 isolate. That is why the pairing matters. A `Math.random()` secret that never leaks any sibling outputs is a smaller risk, but I would not bet a server on it.

The patched code takes the signing key from `randomBytes(32)` and the handshake identifier from `randomUUID()`. Both come from Node's cryptographic generator, which the [Node.js crypto docs](https://nodejs.org/api/crypto.html) describe as producing cryptographically strong data.

## Patch HFS today

**Warning:** exploitation is live. Treat any HFS below 3.2.1 as exposed.

1.  **Check the version.** Anything from 3.0.0 to 3.2.0 is affected; the old Delphi era 2.x line sits outside the advisory's range. The [HFS releases page](https://github.com/rejetto/hfs/releases) listed 3.3.4 as the latest stable build on October 5, so upgrade to that rather than stopping at 3.2.1. Skim the release notes between your version and the target first, since you are jumping several releases.
2.  **Restart after upgrading.** I have not tested whether a forged cookie survives the key change, so assume it might and check for admin changes anyway.
3.  **Look for code you did not write.** The admin chain ends in the custom server code option, which is stored in the HFS config. If it holds a server code module you cannot account for, assume the host was compromised and rebuild it, and check your access logs for repeated login requests from one address. That is my judgment from the attack path, not guidance from Horizon3 or VulnCheck.
4.  **Set your own key if you cannot upgrade yet.** The patched source still reads `COOKIE_SIGN_KEYS` from the environment, so a value from a cryptographic source removes the guessable default. The code splits that variable on commas, and the patched default is 32 random bytes, so match that length. Treat it as a stopgap only.

## Grep your own Node code

You do not need HFS to be affected by this bug class. Run this grep first on any Node code that did not get a line by line review, and that includes a lot of assistant written code.

```
grep -rnE "Math\.random" --include=*.ts --include=*.js --exclude-dir=node_modules .
```

Then triage every hit by asking one question: does the value reach a cookie, token, URL or response? If so it is in the security bin. The [MDN reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) is blunt: "Do not use them for anything related to security." Shuffling a carousel is fine, anything that touches auth is not.

| What you are generating | Use this instead |
| --- | --- |
| Cookie or session signing key | crypto.randomBytes(32), or a key from your secrets manager |
| Handshake, invite or request ID | crypto.randomUUID() |
| Password reset or API token | crypto.randomBytes(32).toString('base64url') |
| Code running in a browser | crypto.getRandomValues() |
| UI shuffles, jitter, sample data | Math.random() is fine |

The second check is the one the HFS bug teaches. Ask what your server echoes back. A response body, a cookie or a header that contains a value from a weak generator is a free observation for an attacker, and that can expose every other value from the same stream. Then separate the two jobs. In the HFS code Horizon3 analysed, a secret key and a public identifier drew from the same generator, and the public one gave the secret away. Keep secrets on the cryptographic source and treat any identifier you send across a [trust boundary](https://www.jahanzaib.ai/glossary/trust-boundary) as public.

## Shorten the gap between fix and running fix

Horizon3 argues that bug classes once judged too expensive to weaponize will now get weaponized. One CVE does not prove that, but the gap between a fix existing and your running it is the part you control. Here is the rule I would use: for anything reachable from the internet, a security release is applied within a week, and within a day once a public write up exists. This case shows why the second clause matters, because the window closed in about 24 hours.

For a small business that means a named owner for every internet facing tool, including the file server in the corner. If you want that routine built around your own stack, the [production tune up](https://www.jahanzaib.ai/agents/production-tune-up) is where I start. For credentials on the AI side, see [stolen AI API keys](https://www.jahanzaib.ai/blog/anthropic-threat-report-stolen-ai-api-keys) and [capping what a Claude key can spend](https://www.jahanzaib.ai/blog/claude-api-key-setup-first-request).

## Frequently asked questions

### What is CVE-2026-61500?

It is a critical session forgery flaw in Rejetto HFS 3.0.0 through 3.2.0. HFS signed cookies with a key derived from `Math.random()` and leaked outputs of the same generator at login, so an attacker could forge an admin session and run code. VulnCheck scores it 9.3 on CVSS 4.0.

### Which HFS version fixes it?

HFS 3.2.1, released July 13, fixes it by switching to cryptographic random sources. As of October 5 the releases page lists 3.3.4 as the latest stable build, so upgrade to the newest release rather than the minimum fixed version, then restart the service.

### Is CVE-2026-61500 being exploited?

Yes. VulnCheck canaries saw a China hosted address attack real hosts on October 1, the day after Horizon3's write up, and four more hits on October 2 from two US addresses that appear to be a proxy, according to The Register.

### Is Math.random() safe for tokens or session IDs in Node.js?

No. MDN says it does not provide cryptographically secure numbers and should not be used for anything related to security. On the server, use `crypto.randomBytes()` for keys and tokens and `crypto.randomUUID()` for identifiers. In the browser, use `crypto.getRandomValues()`. Keep `Math.random()` for shuffles and sample data.

### Was this a zero day that Mythos found?

No. The flaw was reported and fixed in HFS 3.2.1 on July 13. Horizon3 explained how Mythos found it and how to exploit it on September 30. The first attacks came the day after the write up, 80 days after the fix, against hosts that had not patched.

## Related

- [Anthropic's Opus 5.5 Hands Flagged Cyber Work to Opus 4.8. On the API, It Hands You Nothing.](https://www.jahanzaib.ai/blog/claude-opus-5-5-fallback-model-cyber-safeguards)
- [Anthropic Deleted the Cowork Tab. That Tab Was the Permission Prompt.](https://www.jahanzaib.ai/blog/claude-cowork-merge-agent-permission-boundary)
- [Anthropic's Agents Never Coordinated. OpenAI's Found a Package Cache.](https://www.jahanzaib.ai/blog/amodei-pace-the-frontier-ai-agent-isolation)

---

Canonical HTML version: https://www.jahanzaib.ai/blog/rejetto-hfs-cve-2026-61500-mythos
