From 628571fc799b05712204d681549a6b42e009a01a Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 26 Mar 2026 14:58:06 -0400 Subject: [PATCH] Don't set public Cache-Control on proxied non-public blobs Rails' ActiveStorage proxy controllers hardcode `http_cache_forever public: true`, which sets `Cache-Control: public, immutable`. For non-public blobs behind auth, this allows CDN caching that serves responses without authorization checks. Override `http_cache_forever` in the Authorize concern to downgrade `public` to `false` for non-public blobs. See https://github.com/basecamp/fizzy/pull/2251 for context --- lib/rails_ext/active_storage_authorization.rb | 4 ++++ test/integration/active_storage_authorization_test.rb | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/rails_ext/active_storage_authorization.rb b/lib/rails_ext/active_storage_authorization.rb index 55d0de3bc..7d6fa8510 100644 --- a/lib/rails_ext/active_storage_authorization.rb +++ b/lib/rails_ext/active_storage_authorization.rb @@ -40,6 +40,10 @@ Rails.application.config.to_prepare do head :forbidden end end + + def http_cache_forever(public: false, &block) + super(public: public && publicly_accessible_blob?, &block) + end end ActiveStorage::Blobs::RedirectController.include ActiveStorage::Authorize diff --git a/test/integration/active_storage_authorization_test.rb b/test/integration/active_storage_authorization_test.rb index 1ebb35feb..3394a9990 100644 --- a/test/integration/active_storage_authorization_test.rb +++ b/test/integration/active_storage_authorization_test.rb @@ -150,6 +150,14 @@ class ActiveStorageAuthorizationTest < ActionDispatch::IntegrationTest assert_match %r{rails/active_storage}, response.location end + test "proxy for non-public blob does not set public Cache-Control" do + sign_in_as :david + + get rails_storage_proxy_path(@blob) + assert_response :success + assert_not_includes response.headers["Cache-Control"], "public" + end + # Account exports test "export owner can download their export" do