util/http.lua
author Jonas Schäfer <jonas@wielicki.name>
Mon, 10 Jan 2022 18:23:54 +0100
branch0.11
changeset 12185 783056b4e448
parent 9507 cfbea3064aa9
child 9763 1af5106a2c34
permissions -rw-r--r--
util.xml: Do not allow doctypes, comments or processing instructions Yes. This is as bad as it sounds. CVE pending. In Prosody itself, this only affects mod_websocket, which uses util.xml to parse the <open/> frame, thus allowing unauthenticated remote DoS using Billion Laughs. However, third-party modules using util.xml may also be affected by this. This commit installs handlers which disallow the use of doctype declarations and processing instructions without any escape hatch. It, by default, also introduces such a handler for comments, however, there is a way to enable comments nontheless. This is because util.xml is used to parse human-facing data, where comments are generally a desirable feature, and also because comments are generally harmless.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5299
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     1
-- Prosody IM
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     2
-- Copyright (C) 2013 Florian Zeitz
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     3
--
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     5
-- COPYING file in the source package for more information.
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     6
--
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     7
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
     8
local format, char = string.format, string.char;
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
     9
local pairs, ipairs, tonumber = pairs, ipairs, tonumber;
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    10
local t_insert, t_concat = table.insert, table.concat;
5299
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    11
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    12
local function urlencode(s)
5458
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    13
	return s and (s:gsub("[^a-zA-Z0-9.~_-]", function (c) return format("%%%02x", c:byte()); end));
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    14
end
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    15
local function urldecode(s)
5458
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    16
	return s and (s:gsub("%%(%x%x)", function (c) return char(tonumber(c,16)); end));
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    17
end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    18
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    19
local function _formencodepart(s)
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    20
	return s and (s:gsub("%W", function (c)
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    21
		if c ~= " " then
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    22
			return format("%%%02x", c:byte());
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    23
		else
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    24
			return "+";
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    25
		end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    26
	end));
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    27
end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    28
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    29
local function formencode(form)
5458
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    30
	local result = {};
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    31
	if form[1] then -- Array of ordered { name, value }
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    32
		for _, field in ipairs(form) do
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    33
			t_insert(result, _formencodepart(field.name).."=".._formencodepart(field.value));
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    34
		end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    35
	else -- Unordered map of name -> value
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    36
		for name, value in pairs(form) do
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    37
			t_insert(result, _formencodepart(name).."=".._formencodepart(value));
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    38
		end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    39
	end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    40
	return t_concat(result, "&");
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    41
end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    42
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    43
local function formdecode(s)
5458
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    44
	if not s:match("=") then return urldecode(s); end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    45
	local r = {};
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    46
	for k, v in s:gmatch("([^=&]*)=([^&]*)") do
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    47
		k, v = k:gsub("%+", "%%20"), v:gsub("%+", "%%20");
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    48
		k, v = urldecode(k), urldecode(v);
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    49
		t_insert(r, { name = k, value = v });
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    50
		r[k] = v;
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    51
	end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    52
	return r;
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    53
end
84162b81c863 net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents: 5299
diff changeset
    54
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    55
local function contains_token(field, token)
5299
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    56
	field = ","..field:gsub("[ \t]", ""):lower()..",";
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    57
	return field:find(","..token:lower()..",", 1, true) ~= nil;
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    58
end
cc9d460aa779 util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    59
9507
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    60
local function normalize_path(path, is_dir)
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    61
	if is_dir then
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    62
		if path:sub(-1,-1) ~= "/" then path = path.."/"; end
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    63
	else
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    64
		if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    65
	end
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    66
	if path:sub(1,1) ~= "/" then path = "/"..path; end
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    67
	return path;
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    68
end
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    69
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    70
return {
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    71
	urlencode = urlencode, urldecode = urldecode;
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    72
	formencode = formencode, formdecode = formdecode;
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    73
	contains_token = contains_token;
9507
cfbea3064aa9 mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents: 5471
diff changeset
    74
	normalize_path = normalize_path;
5471
34bfd26525f5 util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents: 5458
diff changeset
    75
};