# Ruby OpenSSL Library - IV Reuse in GCM Mode

Ruby OpenSSL Cipher silently uses a static IV in aes-*-gcm when random_iv is set before key, enabling two-time-pad decryption of ciphertexts.

- Payout: hidden
- Severity: medium
- Program: Ruby
- Found by: offftherecord
- Disclosed: 2021-03-07
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/170548
- Library page: https://bugbountylibrary.com/r/h1%3A170548
- Tags: area:oss domain:oss impact:data-leak kind:bounty platform:hackerone sev:medium tech:ruby technique:source-review vuln:crypto

**Target:** OpenSSL::Cipher AES-GCM encryption in Ruby stdlib
**Root cause:** Setting the IV before the key causes the cipher to discard the random IV and fall back to a static default nonce; the API does not enforce or document ordering.
**Steps:**
1. `cipher = OpenSSL::Cipher.new('aes-256-gcm')`
2. `iv = cipher.random_iv` (before key)
3. `cipher.key = '11111111111111111111111111111111'`
4. `cipher.auth_data = ""`; encrypt same plaintext twice
5. Observe identical ciphertext and tag despite different returned IVs
6. XOR the two ciphertexts and crib-drag to recover plaintext
**How found:** Researcher read the AEAD docs, noticed key/IV ordering unspecified, and tested setting random_iv before key; identical ciphertext across runs with different printed IVs revealed the static nonce.
**Exploitation:** Attacker collects multiple ciphertexts produced by the vulnerable ordering; since the effective nonce is static, XORing ciphertexts cancels the keystream, and crib-dragging recovers plaintext.
**Insight:** When an API returns a value (random_iv) that the underlying cipher silently ignores due to call ordering, compare ciphertexts across runs with fixed plaintext/key to detect nonce reuse rather than trusting the returned IV.

