diff options
author | Kim Alvefur <zash@zash.se> | 2016-01-08 16:16:08 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2016-01-08 16:16:08 +0100 |
commit | 6b1e54864c661211366d22a41435e5e3d07e71ac (patch) | |
tree | fa735fdc4d7fd7f7b8f14ea5dc1e5a86a0ca5dde /plugins/mod_http_files.lua | |
parent | 7baeaaa363aca2190c22f1bd4463ac52ab83bb99 (diff) | |
parent | f9a3ca3602c72f24edecc95a886eace4edd42c5d (diff) | |
download | prosody-6b1e54864c661211366d22a41435e5e3d07e71ac.tar.gz prosody-6b1e54864c661211366d22a41435e5e3d07e71ac.zip |
Merge 0.9->0.10
Diffstat (limited to 'plugins/mod_http_files.lua')
-rw-r--r-- | plugins/mod_http_files.lua | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 7c503c82..0c542714 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -49,6 +49,34 @@ if not mime_map then end end +local forbidden_chars_pattern = "[/%z]"; +if prosody.platform == "windows" then + forbidden_chars_pattern = "[/%z\001-\031\127\"*:<>?|]" +end + +local urldecode = require "util.http".urldecode; +function sanitize_path(path) + local out = {}; + + local c = 0; + for component in path:gmatch("([^/]+)") do + component = urldecode(component); + if component:find(forbidden_chars_pattern) then + return nil; + elseif component == ".." then + if c <= 0 then + return nil; + end + out[c] = nil; + c = c - 1; + elseif component ~= "." then + c = c + 1; + out[c] = component; + end + end + return "/"..table.concat(out, "/"); +end + local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to. function serve(opts) @@ -60,7 +88,11 @@ function serve(opts) local directory_index = opts.directory_index; local function serve_file(event, path) local request, response = event.request, event.response; - local orig_path = request.path; + path = sanitize_path(path); + if not path then + return 400; + end + local orig_path = sanitize_path(request.path); local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then |