security: reject file uploads exceeding 10 MB

Add a MAX_UPLOAD_BYTES constant (10 MB) to Server and check the
uploaded tempfile size before writing it to disk. Exceeding the limit
returns HTTP 413 with a structured JSON error. Includes a test.
This commit is contained in:
2026-06-26 20:35:23 +02:00
parent 4abb5585df
commit 25ebf691f7
3 changed files with 18 additions and 0 deletions
+4
View File
@@ -88,6 +88,10 @@ module Volumen
upload = params["file"] upload = params["file"]
halt(400, json("error" => "no_file")) unless upload.is_a?(Hash) && upload[:tempfile] halt(400, json("error" => "no_file")) unless upload.is_a?(Hash) && upload[:tempfile]
if upload[:tempfile].size > Server::MAX_UPLOAD_BYTES
halt(413, json("error" => "file_too_large", "max_bytes" => Server::MAX_UPLOAD_BYTES))
end
json("url" => store.store_upload(upload[:filename], upload[:tempfile])) json("url" => store.store_upload(upload[:filename], upload[:tempfile]))
end end
+1
View File
@@ -17,6 +17,7 @@ module Volumen
class Server < Sinatra::Base class Server < Sinatra::Base
MAX_LOGIN_ATTEMPTS = 10 MAX_LOGIN_ATTEMPTS = 10
LOGIN_WINDOW = 60 # seconds LOGIN_WINDOW = 60 # seconds
MAX_UPLOAD_BYTES = 10 * 1024 * 1024 # 10 MB
SLUG_REGEX = /\A[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?\z/ SLUG_REGEX = /\A[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?\z/
register ApiRoutes register ApiRoutes
+13
View File
@@ -124,6 +124,19 @@ class AdminTest < Minitest::Test
assert_equal 403, last_response.status assert_equal 403, last_response.status
end end
def test_upload_rejects_file_too_large
login
get "/admin/posts/new"
token = csrf(last_response.body)
big_path = File.join(@dir, "big.png")
File.binwrite(big_path, "X" * (Volumen::Server::MAX_UPLOAD_BYTES + 1))
post "/admin/uploads",
"_csrf" => token,
"file" => Rack::Test::UploadedFile.new(big_path, "image/png")
assert_equal 413, last_response.status
assert_equal "file_too_large", JSON.parse(last_response.body)["error"]
end
def test_image_upload_and_serving def test_image_upload_and_serving
login login
get "/admin/posts/new" get "/admin/posts/new"