mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-28 00:16:48 +09:00
Uploaded files come from this origin, so one served with a JavaScript
type could run as one of the app's own scripts. Browsers accept sixteen
spellings of that type, and Disk URLs sign the type they were minted
with, so refusing a list of types at upload can't cover links already
out there. Instead, a middleware rewrites the type of anything Active
Storage reads out that isn't plainly media, a PDF or plain text to
application/octet-stream, whatever the URL says.
(cherry picked from commit cad2d7211d)
38 lines
1.7 KiB
Ruby
38 lines
1.7 KiB
Ruby
require "test_helper"
|
|
|
|
class UploadedScriptGuardTest < ActiveSupport::TestCase
|
|
# Every JavaScript MIME type essence in the MIME Sniffing Standard, plus
|
|
# parameters and casing a signed Disk URL might carry.
|
|
SCRIPT_TYPES = %w[
|
|
application/ecmascript application/javascript application/x-ecmascript application/x-javascript
|
|
text/ecmascript text/javascript text/javascript1.0 text/javascript1.1 text/javascript1.2 text/javascript1.3
|
|
text/javascript1.4 text/javascript1.5 text/jscript text/livescript text/x-ecmascript text/x-javascript
|
|
] + [ "Text/JavaScript; charset=utf-8" ]
|
|
|
|
test "uploads never leave with a script type, whatever the URL says" do
|
|
SCRIPT_TYPES.each do |type|
|
|
assert_equal ActiveStorage.binary_content_type, served_type(type, "#{ActiveStorage.routes_prefix}/disk/key/probe.js"), type
|
|
end
|
|
end
|
|
|
|
test "media and downloads keep their type" do
|
|
%w[ image/png video/mp4 audio/mpeg application/pdf text/plain ].each do |type|
|
|
assert_equal type, served_type(type, "#{ActiveStorage.routes_prefix}/disk/key/file"), type
|
|
end
|
|
end
|
|
|
|
test "direct upload responses keep their JSON type" do
|
|
assert_equal "application/json", served_type("application/json", "#{ActiveStorage.routes_prefix}/direct_uploads", method: "POST")
|
|
end
|
|
|
|
test "application responses outside uploads are untouched" do
|
|
assert_equal "text/javascript", served_type("text/javascript", "/assets/application-abc123.js")
|
|
end
|
|
|
|
private
|
|
def served_type(type, path, method: "GET")
|
|
app = ->(env) { [ 200, { "content-type" => type }, [ "" ] ] }
|
|
UploadedScriptGuard.new(app).call(Rack::MockRequest.env_for(path, method: method))[1]["content-type"]
|
|
end
|
|
end
|