mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-21 05:36:30 +09:00
Serve uploads that aren't media as downloads
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.
This commit is contained in:
1 parent
821ff92dda
commit
cad2d7211d
2 files changed
+68
No files matched your search
@@ -0,0 +1,37 @@
|
||||
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
|
||||
Reference in new issue
Block a user