deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

SlowMist: Six Intercepted Qubic Network Headers Were Enough to Rebuild Wallet Seeds

Security firm SlowMist says Qubic wallet seeds were generated with JavaScript's Math.random(), and the same values leaked through plaintext network headers, letting attackers drain 2.94 trillion QU.

SlowMist: Six Intercepted Qubic Network Headers Were Enough to Rebuild Wallet Seeds

Security firm SlowMist has explained how attackers managed to drain roughly 2.94 trillion QU from 1,404 Qubic wallets, a theft the project disclosed on Oct. 18. According to SlowMist's analysis, published Oct. 20 and reported by Basis Desk, the wallet generated private key seeds with JavaScript's Math.random(), and the same random stream leaked into network packet headers that traveled unencrypted.

How seed generation failed

SlowMist found that Qubic Wallet assembled its 55-character account seeds by drawing letters from Math.random(). In V8 engines that function runs on xorshift128+, a fast algorithm never designed for cryptography. The upshot is at most 64 bits of genuine entropy, even though the 55-character format implies a nominal 258.5 bits. There was no second layer of protection either: the derived characters were converted directly into the private key, with no password or hardware entropy mixed in. Predicting the generator's output meant predicting the key.

The leak over the wire

The flaw became remotely exploitable because the wallet also consumed the same random number stream when building network traffic. SlowMist reported that a request header named dejaVu was populated with values truncated from Math.random(). Those headers were carried inside balance and tick requests sent over plaintext TCP to peers, after TLS protection ended at the default web bridge, so anyone positioned on the path could read them.

Six observations and fifteen milliseconds

Capturing six consecutive dejaVu values was enough to break everything open. The researchers converted the truncated values into interval constraints and fed them into the Z3 solver, which recovered the PRNG's full 128-bit internal state in roughly 15 milliseconds. Once the state was known, outputs could be computed backwards and forwards, including the values that had gone into seed generation. Because balance queries also exposed the account's public key, an observer could generate candidate seeds, verify them offline, and forge signatures to empty the wallet. Basis Desk notes that Qubic had already paused its network once the unauthorized transfers were detected.

Why it matters

The incident is a textbook case of two independent weaknesses reinforcing each other. Using Math.random() for key material is a long-standing anti-pattern, and reusing that same stream for data visible to third parties turned a local design flaw into a remote attack that required nothing more than passive observation of ordinary traffic. For wallet and application developers the lessons are concrete: draw keys only from a cryptographically secure source such as crypto.getRandomValues, keep random streams isolated per purpose, and do not assume encryption holds end-to-end when TLS terminates at an intermediary. The numbers also show how little safety constrained randomness provides in practice. A key space nominally measured at 258.5 bits collapsed to a 128-bit internal state that a standard solver recovered in milliseconds from six header values any on-path observer could capture.

  • #security
  • #cryptography
  • #javascript
  • #cryptocurrency
  • #blockchain

Related posts