{"id":"CVE-2026-126076","kind":"vulnerability","aliases":["CVE-2026-126076","GHSA-2586-8ghr-69fj"],"related":[],"title":"Action Pack: Possible restoration of destroyed sessions in Action Dispatch CacheStore","description":"### Impact\n`ActionDispatch::Session::CacheStore` writes a session back to the cache at the end of each request that loaded it, without checking that the session's cache entry still exists. When a concurrent request destroys the session, through `reset_session` on logout or by deleting its cache entry on the server, a request that loaded the session earlier and finishes later restores it under its original session ID. Logout and server-side revocation could therefore fail to end a session, and an attacker who holds a stolen session cookie could keep that session valid across the victim's logout.\n\nApplications that use `config.session_store :cache_store` are affected, with any cache backend. `ActionDispatch::Session::CookieStore` is not affected, nor is `ActionDispatch::Session::MemCacheStore` with Dalli 4.0.0 or later, whose session store does not write back a session that was deleted.\n\n### Details\nThe fixed releases record which session a request loaded and skip the write when that session's cache entry no longer exists. Changes that such a request makes to the destroyed session are discarded, and Rack logs a warning that the session could not be saved. Each request that writes back a session it loaded makes one additional cache read.\n\n### Releases\nThe fixed releases are available at the normal locations.\n\nPatches for those who cannot upgrade at once:\n- 8.1: https://github.com/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f.patch\n- 8.0: https://github.com/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5.patch\n\n### Credit\nFound by the team during internal code review.","summary":"Rails' ActionDispatch CacheStore session store writes a session back to the cache after a concurrent logout or server-side deletion, so the destroyed session comes back under its original ID. An attacker holding a stolen session cookie can keep that session valid after the victim logs out.","severity":"medium","cvss":4.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"actionpack","fixed":["8.1.4.1"],"affected":">= 8.1, < 8.1.4.1","ecosystem":"rubygems"},{"name":"actionpack","fixed":["8.0.5.2"],"affected":"< 8.0.5.2","ecosystem":"rubygems"},{"name":"actionpack","fixed":["8.1.4.1"],"affected":">= 8.1.0.beta1, < 8.1.4.1","ecosystem":"rubygems"}],"ecosystems":["rubygems"],"tags":["cache-store-sessions","cwe-613","package","rails","ruby","self-hosted"],"not_affected_if":["cookie-store","memcache-store-dalli-4","no-session-revocation"],"how_to_check":"- Check the Rails version in `Gemfile.lock` for `actionpack`.\n- Look for `config.session_store :cache_store` in `config/initializers` or `config/application.rb`; CookieStore is not affected.\n- Check whether the app's Dalli version is `4.0.0` or later if it uses MemCacheStore; that store is not affected.","fix":"- `actionpack` `8.1.4.1` for the 8.1 line.\n- `actionpack` `8.0.5.2` for the 8.0 line.\n- Patch files for teams that cannot upgrade at once are linked in the advisory.","status":"open","published_at":"2026-11-04T03:01:46+00:00","first_seen_at":"2026-11-10T21:01:34+00:00","triaged_at":"2026-11-10T21:01:54+00:00","updated_at":"2026-11-10T21:23:01+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-11-10T21:01:54Z","model":"claude-haiku-5-5","output":{"fix":"- `actionpack` `8.1.4.1` for the 8.1 line.\n- `actionpack` `8.0.5.2` for the 8.0 line.\n- Patch files for teams that cannot upgrade at once are linked in the advisory.","reach":"internet","title":"Rails: cache-store sessions can be restored after logout or revocation","impact":"medium","summary":"Rails' ActionDispatch CacheStore session store writes a session back to the cache after a concurrent logout or server-side deletion, so the destroyed session comes back under its original ID. An attacker holding a stolen session cookie can keep that session valid after the victim logs out.","audience":"businesses","category":"package","nicknames":[],"who_cares":["rails","ruby","self-hosted","cache-store-sessions"],"confidence":0.85,"fix_status":"available","needs_auth":"yes","worst_case":"Revoked session stays valid, so a stolen cookie keeps working after logout.","analyst_note":"","how_to_check":"- Check the Rails version in `Gemfile.lock` for `actionpack`.\n- Look for `config.session_store :cache_store` in `config/initializers` or `config/application.rb`; CookieStore is not affected.\n- Check whether the app's Dalli version is `4.0.0` or later if it uses MemCacheStore; that store is not affected.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["cookie-store","memcache-store-dalli-4","no-session-revocation"],"who_is_affected":"Applications that store sessions with Rails' cache store (`config.session_store :cache_store`) on any cache backend are exposed. Apps using the cookie store, or MemCacheStore with Dalli 4.0.0 or later, are not affected. Teams that rely on logout or server-side session revocation are the ones who need to act.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000845,"input_tokens":5107,"output_tokens":669,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-126076':14A,23A '-2026':13A,22A '-2586':16A '-613':32B '-8':17A '/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5.patch':313C '/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f.patch':309C '4.0.0':212C '69fj':20A '8.0':310C '8.1':306C 'across':181C 'action':1A,9A 'actiondispatch':40B,87C,199C,207C 'actionpack':24A,25A,26A 'addit':285C 'affect':194C,204C 'applic':186C 'attack':71B,169C 'avail':293C 'back':47B,65B,93C,221C,278C 'backend':198C 'cach':28B,50B,96C,112C,132C,191C,197C,245C,286C 'cache-store-sess':27B 'cachestor':11A,41B,89C 'cannot':302C 'chang':250C 'check':107C 'code':321C 'come':64B 'concurr':53B,118C 'config.session':189C 'cooki':76B,175C 'cookiestor':201C 'could':160C,176C,270C 'credit':314C 'cve':12A,21A 'cwe':31B 'dalli':211C 'delet':59B,130C,226C 'destroy':6A,62B,120C,258C 'detail':227C 'discard':261C 'dispatch':10A 'earlier':143C 'end':99C,164C 'entri':113C,133C,246C 'exist':115C,249C 'fail':162C 'finish':145C 'fix':229C,290C 'found':315C 'ghr':19A 'ghr-69fj':18A 'ghsa':15A 'github.com':308C,312C 'github.com/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5.patch':311C 'github.com/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f.patch':307C 'hold':72B,171C 'host':38B 'id':69B,153C 'impact':86C 'intern':320C 'keep':78B,177C 'later':146C,214C 'load':104C,140C,236C,282C 'locat':297C 'log':85B,264C 'logout':54B,127C,154C,185C 'longer':248C 'make':255C,283C 'memcachestor':209C 'normal':296C 'one':284C 'origin':68B,151C 'pack':2A 'packag':33B 'patch':298C 'possibl':3A 'rack':263C 'rail':34B,39B 'read':287C 'record':231C 'releas':230C,288C,291C 'request':102C,119C,138C,235C,254C,275C 'reset':124C 'restor':4A,147C 'review':322C 'revoc':159C 'rubi':35B 'save':273C 'self':37B 'self-host':36B 'server':57B,136C,157C 'server-sid':56B,156C 'session':7A,30B,42B,46B,63B,75B,80B,88C,92C,110C,122C,125C,142C,152C,166C,174C,179C,200C,208C,216C,223C,233C,243C,259C,269C,280C 'side':58B,158C 'skip':238C 'still':114C 'stolen':74B,173C 'store':29B,43B,190C,192C,217C 'team':318C 'therefor':161C 'upgrad':303C 'use':188C 'valid':81B,180C 'victim':84B,183C 'warn':266C 'whose':215C 'without':106C 'write':44B,90C,220C,240C,277C","nicknames":[],"mitigations":[],"who_affected":"Applications that store sessions with Rails' cache store (`config.session_store :cache_store`) on any cache backend are exposed. Apps using the cookie store, or MemCacheStore with Dalli 4.0.0 or later, are not affected. Teams that rely on logout or server-side session revocation are the ones who need to act.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["actionpack"],"ptokens":["actionpack"],"labels":["cachestoresessions","cwe613","medium","package","rails","ruby","rubygems","selfhosted"],"campaign_type":null,"search_a":"'-126076':14A,23A '-2026':13A,22A '-2586':16A '-8':17A '69fj':20A 'action':1A,9A 'actionpack':24A,25A,26A 'cachestor':11A 'cve':12A,21A 'destroy':6A 'dispatch':10A 'ghr':19A 'ghr-69fj':18A 'ghsa':15A 'pack':2A 'possibl':3A 'restor':4A 'session':7A","search_b":"'-613':32B 'actiondispatch':40B 'attack':71B 'back':47B,65B 'cach':28B,50B 'cache-store-sess':27B 'cachestor':41B 'come':64B 'concurr':53B 'cooki':76B 'cwe':31B 'delet':59B 'destroy':62B 'hold':72B 'host':38B 'id':69B 'keep':78B 'log':85B 'logout':54B 'origin':68B 'packag':33B 'rail':34B,39B 'rubi':35B 'self':37B 'self-host':36B 'server':57B 'server-sid':56B 'session':30B,42B,46B,63B,75B,80B 'side':58B 'stolen':74B 'store':29B,43B 'valid':81B 'victim':84B 'write':44B","search_c":"'/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5.patch':313C '/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f.patch':309C '4.0.0':212C '8.0':310C '8.1':306C 'across':181C 'actiondispatch':87C,199C,207C 'addit':285C 'affect':194C,204C 'applic':186C 'attack':169C 'avail':293C 'back':93C,221C,278C 'backend':198C 'cach':96C,112C,132C,191C,197C,245C,286C 'cachestor':89C 'cannot':302C 'chang':250C 'check':107C 'code':321C 'concurr':118C 'config.session':189C 'cooki':175C 'cookiestor':201C 'could':160C,176C,270C 'credit':314C 'dalli':211C 'delet':130C,226C 'destroy':120C,258C 'detail':227C 'discard':261C 'earlier':143C 'end':99C,164C 'entri':113C,133C,246C 'exist':115C,249C 'fail':162C 'finish':145C 'fix':229C,290C 'found':315C 'github.com':308C,312C 'github.com/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5.patch':311C 'github.com/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f.patch':307C 'hold':171C 'id':153C 'impact':86C 'intern':320C 'keep':177C 'later':146C,214C 'load':104C,140C,236C,282C 'locat':297C 'log':264C 'logout':127C,154C,185C 'longer':248C 'make':255C,283C 'memcachestor':209C 'normal':296C 'one':284C 'origin':151C 'patch':298C 'rack':263C 'read':287C 'record':231C 'releas':230C,288C,291C 'request':102C,119C,138C,235C,254C,275C 'reset':124C 'restor':147C 'review':322C 'revoc':159C 'save':273C 'server':136C,157C 'server-sid':156C 'session':88C,92C,110C,122C,125C,142C,152C,166C,174C,179C,200C,208C,216C,223C,233C,243C,259C,269C,280C 'side':158C 'skip':238C 'still':114C 'stolen':173C 'store':190C,192C,217C 'team':318C 'therefor':161C 'upgrad':303C 'use':188C 'valid':180C 'victim':183C 'warn':266C 'whose':215C 'without':106C 'write':90C,220C,240C,277C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-04T03:01:46+00:00","kev":null,"cvss_vector":"CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-2586-8ghr-69fj","url":"https://github.com/rails/rails/security/advisories/GHSA-2586-8ghr-69fj","severity":"medium","published_at":"2026-11-04T03:01:46+00:00","modified_at":"2026-11-10T20:56:09+00:00","first_seen_at":"2026-11-10T21:01:34+00:00","fetched_at":"2026-11-10T21:01:34+00:00","note":null},{"source":"ghsa","external_id":"GHSA-2586-8ghr-69fj","url":"https://github.com/advisories/GHSA-2586-8ghr-69fj","severity":"medium","published_at":"2026-11-10T21:19:09+00:00","modified_at":"2026-11-10T21:19:10+00:00","first_seen_at":"2026-11-10T21:23:01+00:00","fetched_at":"2026-11-10T21:23:01+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-126076","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-126076","severity":null,"published_at":"2026-11-10T21:19:26+00:00","modified_at":"2026-11-10T21:19:26+00:00","first_seen_at":"2026-11-10T21:46:15+00:00","fetched_at":"2026-11-10T21:46:16+00:00","note":null}],"documents":[{"id":118470,"url":"https://github.com/rails/rails/security/advisories/GHSA-2586-8ghr-69fj","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":"2026-11-04T03:01:46+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":118831,"url":"https://api.github.com/repos/rails/rails/security-advisories/GHSA-2586-8ghr-69fj","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":118833,"url":"https://github.com/rails/rails/commit/5bb5ec66ed8faaf590ffe1222d7a5eb6e9d050f5","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":118834,"url":"https://github.com/rails/rails/commit/d479192cf88a8b30a335a8bc25188a2d8e0f8d9f","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":67840,"url":"https://github.com/rails/rails/releases/tag/v8.0.5.2","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":67841,"url":"https://github.com/rails/rails/releases/tag/v8.1.4.1","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}