diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9afec6b03..8f6faeb53 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base before_action :set_variant before_action :add_headers before_action :cause_error + after_action :skip_session_if_publicly_cached after_action :reset_current_user layout "default" @@ -148,6 +149,14 @@ class ApplicationController < ActionController::Base CurrentUser.root_url = root_url.chomp("/") end + # Skip setting the session cookie if the response is being publicly cached to + # prevent the user's session cookie from being leaked to other users. + def skip_session_if_publicly_cached + if response.cache_control[:public] == true + request.session_options[:skip] = true + end + end + def set_variant request.variant = params[:variant].try(:to_sym) end diff --git a/test/functional/autocomplete_controller_test.rb b/test/functional/autocomplete_controller_test.rb index 4dd62ee1a..ae372ab1f 100644 --- a/test/functional/autocomplete_controller_test.rb +++ b/test/functional/autocomplete_controller_test.rb @@ -34,6 +34,14 @@ class AutocompleteControllerTest < ActionDispatch::IntegrationTest assert_autocomplete_equals(["rating:safe"], "rating:s", "tag_query") assert_autocomplete_equals(["rating:safe"], "-rating:s", "tag_query") end + + should "not set session cookies when the response is publicly cached" do + get autocomplete_index_path(search: { query: "azur", type: "tag_query" }), as: :json + + assert_response :success + assert_equal(true, response.cache_control[:public]) + assert_equal({}, response.cookies) + end end end end