| CWEs | CWE-367 (TOCTOU), CWE-362 (Race Condition), CWE-453 (Insecure Default State) |
| Affected | The rainbet-style seed-rotation in this repo (loopback only) |
The loopback target (`startVulnerableTarget()` in `index.js`) implements
1. **Pre-commit hash disclosure** — the `seedRotateScheduled` broadcast
includes `nextSeedHash` before the rotation is committed.
2. **Uncommitted-window bet processing** — `place_bet` packets arriving while
`rotationPending === true` are processed with the *old* server seed and
3. **Missing state reset on commit** — `rotateSeed()` does not invalidate the
queued outcome or the client-seed game state, so the first clean
post-rotation bet receives the attacker-influenced outcome.
git clone
Interactive flow: pick a rainbet-style game (mines / coinflip / crash /
limbo / dice), optionally provide hex seeds (blank = random / probe mode),
2. Open the race window and probe candidate payloads,
3. Run post-rotation verification rounds,
4. Report whether round 1 was replayed from the race window,
[PASS] race window opened (rotation scheduled)
[PASS] probe packets processed during window (bet_ack queued)
[PASS] post-rotation round 1 was replayed (state confusion)
[PASS] later rounds use fresh entropy (not replayed)
[PASS] round-1 outcome matches race-window candidate
ALL CHECKS PASSED - CVE-2026-31337 reproduced against rainbet-style
## Remediation guidance (for the pattern)
If a real system exhibited this pattern, the fixes would be:
- Never disclose `nextSeedHash` before the rotation commit (CWE-200).
- Reject all bet packets while a rotation is pending, atomically
(single-threaded queue + per-connection sequence numbers).
- Reset all per-client-seed game state and invalidate queued outcomes on
rotation commit; re-derive HMAC inputs from the new seed only.
Rainbet is a real brand name used here only as a stylistic reference for the
's game set and terminology. This project is not affiliated with,
endorsed by, or connected to rainbet.com, and it never communicates with any
external service. All exploitation happens against `127.0.0.1`.
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
