# HG changeset patch # User Kim Alvefur # Date 1492107797 -7200 # Node ID 96bf67f1f9609d205631b0f36eaae55026b4996b # Parent 5f60dd12dbb82f53ef134ed4ee13e028fd9bbf1c mod_http_upload: Validate that file extension (used by mod_http_files) matches mime type given by client diff -r 5f60dd12dbb8 -r 96bf67f1f960 mod_http_upload/mod_http_upload.lua --- a/mod_http_upload/mod_http_upload.lua Thu Apr 13 16:36:25 2017 +0200 +++ b/mod_http_upload/mod_http_upload.lua Thu Apr 13 20:23:17 2017 +0200 @@ -44,6 +44,9 @@ module:depends("http"); module:depends("disco"); +local http_files = module:depends("http_files"); +local mime_map = module:shared("/*/http_files/mime").types; + -- namespaces local namespace = "urn:xmpp:http:upload:0"; local legacy_namespace = "urn:xmpp:http:upload"; @@ -100,7 +103,7 @@ return sum < quota; end -local function handle_request(origin, stanza, xmlns, filename, filesize) +local function handle_request(origin, stanza, xmlns, filename, filesize, mimetype) -- local clients only if origin.type ~= "c2s" then module:log("debug", "Request for upload slot from a %s", origin.type); @@ -129,6 +132,15 @@ origin.send(st.error_reply(stanza, "wait", "resource-constraint", "Quota reached")); return true; end + + if mime_map then + local file_ext = filename:match("%.([^.]+)$"); + if (not file_ext and mimetype ~= "application/octet-stream") or (file_ext and mime_map[file_ext] ~= mimetype) then + origin.send(st.error_reply(stanza, "modify", "bad-request", "MIME type does not match file extension")); + return true; + end + end + local reply = st.reply(stanza); reply:tag("slot", { xmlns = xmlns }); @@ -162,7 +174,8 @@ local request = stanza.tags[1]; local filename = request.attr.filename; local filesize = tonumber(request.attr.size); - return handle_request(origin, stanza, namespace, filename, filesize); + local mimetype = request.attr["content-type"]; + return handle_request(origin, stanza, namespace, filename, filesize, mimetype); end); module:hook("iq/host/"..legacy_namespace..":request", function (event) @@ -170,7 +183,8 @@ local request = stanza.tags[1]; local filename = request:get_child_text("filename"); local filesize = tonumber(request:get_child_text("size")); - return handle_request(origin, stanza, legacy_namespace, filename, filesize); + local mimetype = request:get_child_text("content-type"); + return handle_request(origin, stanza, legacy_namespace, filename, filesize, mimetype); end); -- http service @@ -256,7 +270,7 @@ end end -local serve_uploaded_files = module:depends("http_files").serve(storage_path); +local serve_uploaded_files = http_files.serve(storage_path); local function serve_head(event, path) event.response.send = send_response_sans_body;