Skip to content

Commit ef65eee

Browse files
authored
Merge pull request rails#42960 from FestaLab/activestorage/unsafe-redirect
Fix open redirects in active storage
2 parents 7faf8a0 + 77f2af3 commit ef65eee

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

activestorage/app/controllers/active_storage/blobs/redirect_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
1111

1212
def show
1313
expires_in ActiveStorage.service_urls_expire_in
14-
redirect_to @blob.url(disposition: params[:disposition])
14+
redirect_to @blob.url(disposition: params[:disposition]), allow_other_host: true
1515
end
1616
end

activestorage/app/controllers/active_storage/representations/redirect_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
class ActiveStorage::Representations::RedirectController < ActiveStorage::Representations::BaseController
1010
def show
1111
expires_in ActiveStorage.service_urls_expire_in
12-
redirect_to @representation.url(disposition: params[:disposition])
12+
redirect_to @representation.url(disposition: params[:disposition]), allow_other_host: true
1313
end
1414
end

activestorage/test/controllers/blobs/redirect_controller_test.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,38 @@ class ActiveStorage::Blobs::ExpiringRedirectControllerTest < ActionDispatch::Int
5555
assert_response :not_found
5656
end
5757
end
58+
59+
class ActiveStorage::Blobs::RedirectControllerWithOpenRedirectTest < ActionDispatch::IntegrationTest
60+
if SERVICE_CONFIGURATIONS[:s3]
61+
test "showing existing blob stored in s3" do
62+
with_raise_on_open_redirects(:s3) do
63+
blob = create_file_blob filename: "racecar.jpg", service_name: :s3
64+
65+
get rails_storage_redirect_url(blob)
66+
assert_redirected_to(/racecar\.jpg/)
67+
end
68+
end
69+
end
70+
71+
if SERVICE_CONFIGURATIONS[:azure]
72+
test "showing existing blob stored in azure" do
73+
with_raise_on_open_redirects(:azure) do
74+
blob = create_file_blob filename: "racecar.jpg", service_name: :azure
75+
76+
get rails_storage_redirect_url(blob)
77+
assert_redirected_to(/racecar\.jpg/)
78+
end
79+
end
80+
end
81+
82+
if SERVICE_CONFIGURATIONS[:gcs]
83+
test "showing existing blob stored in gcs" do
84+
with_raise_on_open_redirects(:gcs) do
85+
blob = create_file_blob filename: "racecar.jpg", service_name: :gcs
86+
87+
get rails_storage_redirect_url(blob)
88+
assert_redirected_to(/racecar\.jpg/)
89+
end
90+
end
91+
end
92+
end

activestorage/test/controllers/representations/redirect_controller_test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,50 @@ class ActiveStorage::Representations::RedirectControllerWithPreviewsWithStrictLo
132132
assert_equal 100, image.height
133133
end
134134
end
135+
136+
class ActiveStorage::Representations::RedirectControllerWithOpenRedirectTest < ActionDispatch::IntegrationTest
137+
if SERVICE_CONFIGURATIONS[:s3]
138+
test "showing existing variant stored in s3" do
139+
with_raise_on_open_redirects(:s3) do
140+
blob = create_file_blob filename: "racecar.jpg", service_name: :s3
141+
142+
get rails_blob_representation_url(
143+
filename: blob.filename,
144+
signed_blob_id: blob.signed_id,
145+
variation_key: ActiveStorage::Variation.encode(resize_to_limit: [100, 100]))
146+
147+
assert_redirected_to(/racecar\.jpg/)
148+
end
149+
end
150+
end
151+
152+
if SERVICE_CONFIGURATIONS[:azure]
153+
test "showing existing variant stored in azure" do
154+
with_raise_on_open_redirects(:azure) do
155+
blob = create_file_blob filename: "racecar.jpg", service_name: :azure
156+
157+
get rails_blob_representation_url(
158+
filename: blob.filename,
159+
signed_blob_id: blob.signed_id,
160+
variation_key: ActiveStorage::Variation.encode(resize_to_limit: [100, 100]))
161+
162+
assert_redirected_to(/racecar\.jpg/)
163+
end
164+
end
165+
end
166+
167+
if SERVICE_CONFIGURATIONS[:gcs]
168+
test "showing existing variant stored in gcs" do
169+
with_raise_on_open_redirects(:gcs) do
170+
blob = create_file_blob filename: "racecar.jpg", service_name: :gcs
171+
172+
get rails_blob_representation_url(
173+
filename: blob.filename,
174+
signed_blob_id: blob.signed_id,
175+
variation_key: ActiveStorage::Variation.encode(resize_to_limit: [100, 100]))
176+
177+
assert_redirected_to(/racecar\.jpg/)
178+
end
179+
end
180+
end
181+
end

activestorage/test/test_helper.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ def without_variant_tracking(&block)
139139
yield
140140
ActiveStorage.track_variants = variant_tracking_was
141141
end
142+
143+
def with_raise_on_open_redirects(service)
144+
old_raise_on_open_redirects = ActionController::Base.raise_on_open_redirects
145+
old_service = ActiveStorage::Blob.service
146+
147+
ActionController::Base.raise_on_open_redirects = true
148+
ActiveStorage::Blob.service = ActiveStorage::Service.configure(service, SERVICE_CONFIGURATIONS)
149+
yield
150+
ensure
151+
ActionController::Base.raise_on_open_redirects = old_raise_on_open_redirects
152+
ActiveStorage::Blob.service = old_service
153+
end
142154
end
143155

144156
require "global_id"

0 commit comments

Comments
 (0)