diff --git a/Gemfile b/Gemfile index 8fd9fb3e2..713e5600e 100644 --- a/Gemfile +++ b/Gemfile @@ -161,5 +161,3 @@ gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' gem 'pluck_each', '~> 0.1.3' - -gem 'secure_headers', '~> 3.5' diff --git a/Gemfile.lock b/Gemfile.lock index 3780e3a29..e508b0b0c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -571,8 +571,6 @@ GEM scenic (1.5.4) activerecord (>= 4.0.0) railties (>= 4.0.0) - secure_headers (3.9.0) - useragent securecompare (1.0.0) semantic_range (2.3.0) sidekiq (6.1.3) @@ -654,7 +652,6 @@ GEM unf_ext (0.0.7.7) unicode-display_width (1.7.0) uniform_notifier (1.13.2) - useragent (0.16.10) warden (1.2.9) rack (>= 2.0.9) webauthn (3.0.0.alpha1) @@ -798,7 +795,6 @@ DEPENDENCIES ruby-progressbar (~> 1.11) sanitize (~> 5.2) scenic (~> 1.5) - secure_headers (~> 3.5) sidekiq (~> 6.1) sidekiq-bulk (~> 0.2.0) sidekiq-scheduler (~> 3.0) diff --git a/config/application.rb b/config/application.rb index a45ac1860..116eaf29d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,6 +25,7 @@ require_relative '../lib/devise/two_factor_pam_authenticatable' require_relative '../lib/chewy/strategy/custom_sidekiq' require_relative '../lib/webpacker/manifest_extensions' require_relative '../lib/webpacker/helper_extensions' +require_relative '../lib/action_dispatch/cookie_jar_extensions' require_relative '../lib/rails/engine_extensions' Dotenv::Railtie.load diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d3757b0d3..ef612e177 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -9,6 +9,7 @@ Warden::Manager.after_set_user except: :fetch do |user, warden| value: session_id, expires: 1.year.from_now, httponly: true, + secure: (Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'), same_site: :lax, } end @@ -19,6 +20,7 @@ Warden::Manager.after_fetch do |user, warden| value: warden.cookies.signed['_session_id'] || warden.raw_session['auth_id'], expires: 1.year.from_now, httponly: true, + secure: (Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'), same_site: :lax, } else @@ -227,6 +229,10 @@ Devise.setup do |config| # If true, extends the user's remember period when remembered via cookie. # config.extend_remember_period = false + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + config.rememberable_options = { secure: true } + # ==> Configuration for :validatable # Range for password length. config.password_length = 8..72 diff --git a/config/initializers/makara.rb b/config/initializers/makara.rb index afd29eda8..dc88fa63c 100644 --- a/config/initializers/makara.rb +++ b/config/initializers/makara.rb @@ -1 +1,2 @@ Makara::Cookie::DEFAULT_OPTIONS[:same_site] = :lax +Makara::Cookie::DEFAULT_OPTIONS[:secure] = Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true' diff --git a/config/initializers/secureheaders.rb b/config/initializers/secureheaders.rb deleted file mode 100644 index 6c8ac7fbe..000000000 --- a/config/initializers/secureheaders.rb +++ /dev/null @@ -1,10 +0,0 @@ -SecureHeaders::Configuration.default do |config| - config.cookies = { - secure: true, - httponly: true, - samesite: { - lax: true - } - } - config.csp = SecureHeaders::OPT_OUT -end diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 7e3471ac4..e5d1be4c6 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -2,5 +2,6 @@ Rails.application.config.session_store :cookie_store, { key: '_mastodon_session', + secure: (Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true'), same_site: :lax, } diff --git a/lib/action_dispatch/cookie_jar_extensions.rb b/lib/action_dispatch/cookie_jar_extensions.rb new file mode 100644 index 000000000..44c39c1f8 --- /dev/null +++ b/lib/action_dispatch/cookie_jar_extensions.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ActionDispatch + module CookieJarExtensions + private + + # Monkey-patch ActionDispatch to serve secure cookies to Tor Hidden Service + # users. Otherwise, ActionDispatch would drop the cookie over HTTP. + def write_cookie?(*) + request.headers['Host'].ends_with?('.onion') || super + end + end +end + +ActionDispatch::Cookies::CookieJar.prepend(ActionDispatch::CookieJarExtensions)