# Cloudreve is vulnerable to Account Takeover via Weak Cryptographic Token Generation (Insecure PRNG Seeding)

Cloudreve seeded math/rand with UnixNano to generate secret_key and hash_id_salt, letting attackers brute-force the seed and forge admin JWTs.

- Payout: Research
- Severity: high
- Program: Cloudreve
- Found by: orenyomtov
- Disclosed: 2026-03-31
- CVE: CVE-2026-25726
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-f8xp-wvcx-p6f4
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-f8xp-wvcx-p6f4
- Tags: area:web domain:web impact:ato impact:privesc kind:research platform:ghsa sev:high tech:go tech:jwt technique:source-review vuln:account-takeover vuln:auth-bypass vuln:crypto

**Target:** Go web application secret_key / hash_id_salt generation and JWT signing
**Root cause:** secret_key and hash_id_salt are generated at first startup using math/rand seeded with time.Now().UnixNano(), a non-cryptographic PRNG with a guessable seed, and persisted in the database.
**Steps:**
1. Obtain admin account creation time via public API endpoints to bound the seed window.
2. Brute-force time.Now().UnixNano() seed candidates, using a known hashid to validate each candidate seed.
3. Derive the predicted secret_key from the recovered seed.
4. Forge a valid JWT signed with the predicted secret_key for an admin user.
5. Use the forged JWT to authenticate as administrator.
**How found:** Code review of secret generation in pkg/util/common.go and inventory/setting.go revealed math/rand seeded with time.Now().UnixNano() used for security-critical secrets; finder realized the seed is recoverable from a known timestamp plus a hashid oracle.
**Exploitation:** Attacker narrows the PRNG seed search using the admin's creation timestamp from public APIs, validates candidate seeds against a known hashid, recovers secret_key, and forges JWTs for arbitrary users including admins, achieving full account takeover. Brute-force demonstrated under 3 hours on a consumer PC.
**Escalation:** Forged admin JWT yields full account takeover and privilege escalation; persists on upgraded servers if secrets were originally generated by an old version.
**Insight:** When auditing Go apps, grep for math/rand usage feeding tokens, salts or keys; if the seed is time-based, look for any public timestamp (account creation, install date) plus a deterministic output (hashid) to validate brute-forced seeds offline.

