In February 2024, a critical security oversight was revealed involving Red Hat’s ose-olm-catalogd-container—a core part of the Operator Lifecycle Manager in OpenShift. Many believed CVE-2023-39325 and CVE-2023-44487, collectively known as the “Rapid Reset” vulnerability in HTTP/2, were behind them. But CVE-2024-12698 shows how quick and partial fixes can leave systems exposed, especially when authentication is involved.
Let’s break down what happened, how attackers can exploit this, and how you (or your company) can avoid the same mistake.
You might already know these bugs by their CVE numbers
- CVE-2023-39325
- CVE-2023-44487
Both describe a clever attack on HTTP/2, where an attacker floods a server with rapid streams and resets, overwhelming resources and causing denial of service.
In plain English: Attackers could knock your API offline by opening and closing connections really fast.
OLM’s Rapid Reset Fix: Only for Unauthenticated Streams
OpenShift’s OLM (Operator Lifecycle Manager) manages Kubernetes operators. The ose-olm-catalogd-container provides catalog APIs using gRPC, which often runs over HTTP/2 and inherits its weaknesses.
After the initial Rapid Reset advisories, OpenShift shipped updates to block the attacks. However, the patch only checked for unauthenticated streams. If a connection was authenticated (as in with a client certificate or token), the patched code would let it through without restriction.
In short: Only strangers were checked for Rapid Reset abuse. Trusted users—including attackers who were able to authenticate—could still blow up your OLM!
CVE-2024-12698: Details and Exploit
This oversight was formalized as CVE-2024-12698. Here’s what makes it unique:
Authenticated users were implicitly trusted, bypassing the fix.
- Any attacker who could obtain credentials (even via lateral movement or public service account tokens) could use the rapid reset method to take down the OLM APIs.
Code Snippet: The Flawed Check
> This is a simplified excerpt, based on patches and analysis. See Red Hat’s commit for the full context.
// Pseudocode illustrating the vulnerability
if !authenticated(conn) {
if rapidResetDetected(conn) {
block(conn)
}
} else {
// Authenticated connections: no additional checks
serve(conn)
}
What’s wrong? Authenticated connections need the same rate limiting/checks, but the code doesn't enforce it.
Exploiting the Flaw: Proof of Concept
This attack isn’t rocket science. You only need a valid credential (maybe a low-privilege service account).
import grpc
import threading
def rapid_reset_attack(target, creds):
def reset_loop():
while True:
try:
channel = grpc.secure_channel(target, creds)
# Open a stream, then quickly close
stub = MyCatalogStub(channel)
response = stub.StreamListCatalog(...)
channel.close()
except Exception as e:
pass
threads = []
for _ in range(100): # Simultaneous attackers
t = threading.Thread(target=reset_loop)
t.start()
threads.append(t)
This weaponizes the same rapid open-close loop, but with a valid token. The server, thinking you’re legit, treats your connections as safe—until the service crashes under the load.
How Was It Fixed?
Eventually, Red Hat pushed a fix to extend the same Rapid Reset protections to all streams—authenticated or not.
> See their release note
> - Bug 2254995 - Protect all HTTP/2 streams against rapid reset, not just unauthenticated
Now, no matter who you are, if you try to spam the server with rapid resets, you'll get blocked.
Apply security controls universally: Don’t create “blind spots.”
- Watch your downstream dependencies: If your tool chains upstream code, security holes can cascade quickly.
References
- Red Hat OLM operator CVE-2024-12698 advisory
- NVD CVE-2024-12698 entry
- Upstream patch discussion
- How the Rapid Reset attack works (Cloudflare blog)
- Kubernetes pod service account token risks
Final Thoughts
CVE-2024-12698 is a classic example of a “fix that wasn’t quite fixed.” Always test patches and think like an attacker—even the ones who have the right keys. Protect all doors, not just the front one.
Timeline
Published on: 12/18/2024 05:15:07 UTC
Last modified on: 01/21/2025 09:28:08 UTC