chore: Add security flags to session cookie configuration (#14248)

## Summary
- Adds `httponly` and `secure` flags to session cookie configuration
- Adds RSpec tests for session configuration

## Changes
- `config/initializers/session_store.rb`: add `httponly: true`, `secure:
FORCE_SSL`
- `spec/config/session_store_spec.rb`: tests for all session store
options

Ref #2683 (hardens the session cookie but does not remove it, sessions
are still needed for super_admin dashboard)

---------

Co-authored-by: Adam-Relay <adam@userelay.ai>
Co-authored-by: Adam Berger <adam@adam-berger.com>
Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
This commit is contained in:
Adam Berger
2026-06-11 16:13:57 +05:30
committed by GitHub
co-authored by Adam-Relay Adam Berger Vishnu Narayanan
parent a901c87ab4
commit 95d6aecb51
2 changed files with 37 additions and 1 deletions
+8 -1
View File
@@ -1,3 +1,10 @@
# Be sure to restart your server when you modify this file.
# Sessions are used only for the super_admin dashboard (flash/CSRF), not for API auth.
Rails.application.config.session_store :cookie_store, key: '_chatwoot_session', same_site: :lax
secure_cookies = ActiveModel::Type::Boolean.new.cast(ENV.fetch('FORCE_SSL', false))
Rails.application.config.session_store :cookie_store,
key: '_chatwoot_session',
same_site: :lax,
secure: secure_cookies,
httponly: true
+29
View File
@@ -0,0 +1,29 @@
require 'rails_helper'
# rubocop:disable RSpec/DescribeClass
describe 'Session Store Configuration' do
# rubocop:enable RSpec/DescribeClass
let(:session_options) { Rails.application.config.session_options }
it 'uses cookie_store as the session store' do
expect(Rails.application.config.session_store).to eq(ActionDispatch::Session::CookieStore)
end
it 'sets the session key' do
expect(session_options[:key]).to eq('_chatwoot_session')
end
it 'sets same_site to lax' do
expect(session_options[:same_site]).to eq(:lax)
end
it 'sets httponly to true' do
expect(session_options[:httponly]).to be(true)
end
it 'sets secure flag based on FORCE_SSL' do
expected_secure = ActiveModel::Type::Boolean.new.cast(ENV.fetch('FORCE_SSL', false))
expect(session_options[:secure]).to eq(expected_secure)
end
end