{"id":"GHSA-gmj8-hvj3-49mw","kind":"vulnerability","aliases":["GHSA-gmj8-hvj3-49mw"],"related":[],"title":"Missing SameSite attribute on session cookies from Action Pack session stores","description":"### Impact\nAction Pack session stores other than `ActionDispatch::Session::CookieStore` (`CacheStore`, `MemCacheStore`, and third-party stores built on `AbstractStore`, `AbstractSecureStore` or the session mixins) write the session cookie without a `SameSite` attribute, regardless of `config.action_dispatch.cookies_same_site_protection`, which defaults to `:lax`. Only `CookieStore` applies the configured policy. In browsers that do not treat a cookie without the attribute as `SameSite=Lax`, a cross-site request could carry the session cookie, possibly leading to cross-site request forgery against actions that do not verify an authenticity token, such as those of API-only applications.\n\nApplications are affected when they use a session store other than `CookieStore` and do not pass `same_site:` to `config.session_store`.\n\n### Details\nIn the fixed releases, every session store sets the session cookie's `SameSite` attribute from `cookies_same_site_protection` when its options have no `:same_site` key. An explicit `same_site:` option, including `same_site: nil`, and a `:same_site` value in a store's `DEFAULT_OPTIONS` still take precedence.\n\n### Workarounds\nPass `same_site:` when configuring the session store, for example `config.session_store :cache_store, same_site: :lax`.\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/2d9f502df941e31ce9bad0e846564f49396bed46.patch\n- 8.0: https://github.com/rails/rails/commit/f2392996be723708271a8d30bfcf0edc221e53ef.patch\n\n### Credit\nThis issue was responsibly reported by HackerOne researcher [tjvc](https://hackerone.com/tjvc).","summary":"Action Pack session stores other than CookieStore write the session cookie without a SameSite attribute, ignoring the configured cookies_same_site_protection default of :lax. In browsers that do not default such cookies to Lax, a cross-site request could carry the session cookie and enable cross-site request forgery against actions that skip authenticity token checks.","severity":"low","cvss":3.1,"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"}],"ecosystems":["rubygems"],"tags":["actionpack","api-only","cwe-352","package","rails","ruby","self-hosted"],"not_affected_if":["cookie-store","same-site-option-set"],"how_to_check":"- Check the Rails version with `bundle exec rails -v` or in Gemfile.lock for actionpack below `8.1.4.1` or below `8.0.5.2`\n- Look in config/initializers or config/application.rb for `config.session_store` and confirm whether it uses `:cache_store`, `:mem_cache_store` or a third-party store without a `same_site:` option\n- Check whether API-only actions skip authenticity token verification","fix":"- actionpack 8.1.x: move to `8.1.4.1`\n- actionpack 8.0.x: move to `8.0.5.2`\n- Workaround if upgrade is not possible: pass `same_site:` to `config.session_store`, for example `config.session_store :cache_store, same_site: :lax`","status":"open","published_at":"2026-11-04T03:02:05+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","triaged_at":"2026-11-09T22:57:25+00:00","updated_at":"2026-11-09T22:57:25+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:57:25Z","model":"claude-haiku-5-5","output":{"fix":"- actionpack 8.1.x: move to `8.1.4.1`\n- actionpack 8.0.x: move to `8.0.5.2`\n- Workaround if upgrade is not possible: pass `same_site:` to `config.session_store`, for example `config.session_store :cache_store, same_site: :lax`","reach":"internet","title":"Rails Action Pack: session cookies from non-default stores lack SameSite","impact":"low","summary":"Action Pack session stores other than CookieStore write the session cookie without a SameSite attribute, ignoring the configured cookies_same_site_protection default of :lax. In browsers that do not default such cookies to Lax, a cross-site request could carry the session cookie and enable cross-site request forgery against actions that skip authenticity token checks.","audience":"businesses","category":"package","nicknames":[],"who_cares":["rails","actionpack","ruby","self-hosted","api-only"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"cross-site requests carry the session cookie, enabling CSRF","analyst_note":"","how_to_check":"- Check the Rails version with `bundle exec rails -v` or in Gemfile.lock for actionpack below `8.1.4.1` or below `8.0.5.2`\n- Look in config/initializers or config/application.rb for `config.session_store` and confirm whether it uses `:cache_store`, `:mem_cache_store` or a third-party store without a `same_site:` option\n- Check whether API-only actions skip authenticity token verification","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["cookie-store","same-site-option-set"],"who_is_affected":"Applications running Action Pack that use a session store other than ActionDispatch::Session::CookieStore and do not pass same_site: to config.session_store. Applications that use the default cookie store are not affected by this flaw.","user_interaction":"yes","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000872,"input_tokens":5190,"output_tokens":705,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-352':29B '/rails/rails/commit/2d9f502df941e31ce9bad0e846564f49396bed46.patch':304C '/rails/rails/commit/f2392996be723708271a8d30bfcf0edc221e53ef.patch':308C '/tjvc).':321C '49mw':16A,21A '8.0':305C '8.1':301C 'abstractsecurestor':115C 'abstractstor':114C 'action':8A,36B,89B,96C,177C 'actiondispatch':102C 'actionpack':22A,23A,24B 'affect':195C 'api':26B,190C 'api-on':25B,189C 'appli':140C 'applic':192C,193C 'attribut':3A,50B,127C,154C,228C 'authent':92B,183C 'avail':288C 'browser':62B,145C 'built':112C 'cach':278C 'cachestor':105C 'cannot':297C 'carri':77B,164C 'check':94B 'config.action_dispatch.cookies':130C 'config.session':212C,276C 'configur':53B,142C,270C 'cooki':6A,46B,54B,68B,80B,123C,151C,167C,225C,230C 'cookiestor':42B,104C,139C,204C 'could':76B,163C 'credit':309C 'cross':73B,84B,160C,172C 'cross-sit':72B,83B,159C,171C 'cwe':28B 'default':58B,66B,135C,260C 'detail':214C 'enabl':82B 'everi':219C 'exampl':275C 'explicit':243C 'fix':217C,285C 'forgeri':87B,175C 'ghsa':13A,18A 'ghsa-gmj8-hvj3-49mw':12A,17A 'github.com':303C,307C 'github.com/rails/rails/commit/2d9f502df941e31ce9bad0e846564f49396bed46.patch':302C 'github.com/rails/rails/commit/f2392996be723708271a8d30bfcf0edc221e53ef.patch':306C 'gmj8':14A,19A 'hackeron':316C 'hackerone.com':320C 'hackerone.com/tjvc).':319C 'host':35B 'hvj3':15A,20A 'ignor':51B 'impact':95C 'includ':247C 'issu':311C 'key':241C 'lax':60B,70B,137C,157C,282C 'lead':169C 'locat':292C 'memcachestor':106C 'miss':1A 'mixin':119C 'nil':250C 'normal':291C 'option':236C,246C,261C 'pack':9A,37B,97C 'packag':30B 'parti':110C 'pass':208C,266C 'patch':293C 'polici':143C 'possibl':168C 'preced':264C 'protect':57B,133C,233C 'rail':31B 'regardless':128C 'releas':218C,283C,286C 'report':314C 'request':75B,86B,162C,174C 'research':317C 'respons':313C 'rubi':32B 'samesit':2A,49B,126C,156C,227C 'self':34B 'self-host':33B 'session':5A,10A,38B,45B,79B,98C,103C,118C,122C,166C,200C,220C,224C,272C 'set':222C 'site':56B,74B,85B,132C,161C,173C,210C,232C,240C,245C,249C,254C,268C,281C 'skip':91B 'still':262C 'store':11A,39B,99C,111C,201C,213C,221C,258C,273C,277C,279C 'take':263C 'third':109C 'third-parti':108C 'tjvc':318C 'token':93B,184C 'treat':149C 'upgrad':298C 'use':198C 'valu':255C 'verifi':181C 'without':47B,124C,152C 'workaround':265C 'write':43B,120C","nicknames":[],"mitigations":[],"who_affected":"Applications running Action Pack that use a session store other than ActionDispatch::Session::CookieStore and do not pass same_site: to config.session_store. Applications that use the default cookie store are not affected by this flaw.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["actionpack"],"ptokens":["actionpack"],"labels":["actionpack","apionly","cwe352","low","package","rails","ruby","rubygems","selfhosted"],"campaign_type":null,"search_a":"'49mw':16A,21A 'action':8A 'actionpack':22A,23A 'attribut':3A 'cooki':6A 'ghsa':13A,18A 'ghsa-gmj8-hvj3-49mw':12A,17A 'gmj8':14A,19A 'hvj3':15A,20A 'miss':1A 'pack':9A 'samesit':2A 'session':5A,10A 'store':11A","search_b":"'-352':29B 'action':36B,89B 'actionpack':24B 'api':26B 'api-on':25B 'attribut':50B 'authent':92B 'browser':62B 'carri':77B 'check':94B 'configur':53B 'cooki':46B,54B,68B,80B 'cookiestor':42B 'could':76B 'cross':73B,84B 'cross-sit':72B,83B 'cwe':28B 'default':58B,66B 'enabl':82B 'forgeri':87B 'host':35B 'ignor':51B 'lax':60B,70B 'pack':37B 'packag':30B 'protect':57B 'rail':31B 'request':75B,86B 'rubi':32B 'samesit':49B 'self':34B 'self-host':33B 'session':38B,45B,79B 'site':56B,74B,85B 'skip':91B 'store':39B 'token':93B 'without':47B 'write':43B","search_c":"'/rails/rails/commit/2d9f502df941e31ce9bad0e846564f49396bed46.patch':304C '/rails/rails/commit/f2392996be723708271a8d30bfcf0edc221e53ef.patch':308C '/tjvc).':321C '8.0':305C '8.1':301C 'abstractsecurestor':115C 'abstractstor':114C 'action':96C,177C 'actiondispatch':102C 'affect':195C 'api':190C 'api-on':189C 'appli':140C 'applic':192C,193C 'attribut':127C,154C,228C 'authent':183C 'avail':288C 'browser':145C 'built':112C 'cach':278C 'cachestor':105C 'cannot':297C 'carri':164C 'config.action_dispatch.cookies':130C 'config.session':212C,276C 'configur':142C,270C 'cooki':123C,151C,167C,225C,230C 'cookiestor':104C,139C,204C 'could':163C 'credit':309C 'cross':160C,172C 'cross-sit':159C,171C 'default':135C,260C 'detail':214C 'everi':219C 'exampl':275C 'explicit':243C 'fix':217C,285C 'forgeri':175C 'github.com':303C,307C 'github.com/rails/rails/commit/2d9f502df941e31ce9bad0e846564f49396bed46.patch':302C 'github.com/rails/rails/commit/f2392996be723708271a8d30bfcf0edc221e53ef.patch':306C 'hackeron':316C 'hackerone.com':320C 'hackerone.com/tjvc).':319C 'impact':95C 'includ':247C 'issu':311C 'key':241C 'lax':137C,157C,282C 'lead':169C 'locat':292C 'memcachestor':106C 'mixin':119C 'nil':250C 'normal':291C 'option':236C,246C,261C 'pack':97C 'parti':110C 'pass':208C,266C 'patch':293C 'polici':143C 'possibl':168C 'preced':264C 'protect':133C,233C 'regardless':128C 'releas':218C,283C,286C 'report':314C 'request':162C,174C 'research':317C 'respons':313C 'samesit':126C,156C,227C 'session':98C,103C,118C,122C,166C,200C,220C,224C,272C 'set':222C 'site':132C,161C,173C,210C,232C,240C,245C,249C,254C,268C,281C 'still':262C 'store':99C,111C,201C,213C,221C,258C,273C,277C,279C 'take':263C 'third':109C 'third-parti':108C 'tjvc':318C 'token':184C 'treat':149C 'upgrad':298C 'use':198C 'valu':255C 'verifi':181C 'without':124C,152C 'workaround':265C 'write':120C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-04T03:02:05+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-gmj8-hvj3-49mw","url":"https://github.com/rails/rails/security/advisories/GHSA-gmj8-hvj3-49mw","severity":"low","published_at":"2026-11-04T03:02:05+00:00","modified_at":"2026-11-04T03:02:05+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","fetched_at":"2026-11-09T22:53:29+00:00","note":null}],"documents":[{"id":110673,"url":"https://github.com/rails/rails/security/advisories/GHSA-gmj8-hvj3-49mw","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: 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"}