comparison mod_rest/mod_rest.lua @ 5678:0cffeff2cd1d

mod_rest: Limit payload size (cf stanza size limits) Otherwise the limit would be defined by the HTTP stack.
author Kim Alvefur <zash@zash.se>
date Wed, 25 Oct 2023 15:36:20 +0200
parents 5b316088bef5
children
comparison
equal deleted inserted replaced
5677:a5089978928a 5678:0cffeff2cd1d
17 local have_cbor, cbor = pcall(require, "cbor"); 17 local have_cbor, cbor = pcall(require, "cbor");
18 18
19 local jsonmap = module:require"jsonmap"; 19 local jsonmap = module:require"jsonmap";
20 20
21 local tokens = module:depends("tokenauth"); 21 local tokens = module:depends("tokenauth");
22
23 -- Lower than the default c2s size limit to account for possible JSON->XML size increase
24 local stanza_size_limit = module:get_option_number("rest_stanza_size_limit", 1024 * 192);
22 25
23 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }); 26 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" });
24 27
25 local www_authenticate_header; 28 local www_authenticate_header;
26 do 29 do
275 from = { code = 422; type = "modify"; condition = "invalid-from"; text = "Invalid source JID" }; 278 from = { code = 422; type = "modify"; condition = "invalid-from"; text = "Invalid source JID" };
276 from_auth = { code = 403; type = "auth"; condition = "not-authorized"; text = "Not authorized to send stanza with requested 'from'" }; 279 from_auth = { code = 403; type = "auth"; condition = "not-authorized"; text = "Not authorized to send stanza with requested 'from'" };
277 iq_type = { code = 422; type = "modify"; condition = "invalid-xml"; text = "'iq' stanza must be of type 'get' or 'set'" }; 280 iq_type = { code = 422; type = "modify"; condition = "invalid-xml"; text = "'iq' stanza must be of type 'get' or 'set'" };
278 iq_tags = { code = 422; type = "modify"; condition = "bad-format"; text = "'iq' stanza must have exactly one child tag" }; 281 iq_tags = { code = 422; type = "modify"; condition = "bad-format"; text = "'iq' stanza must have exactly one child tag" };
279 mediatype = { code = 415; type = "cancel"; condition = "bad-format"; text = "Unsupported media type" }; 282 mediatype = { code = 415; type = "cancel"; condition = "bad-format"; text = "Unsupported media type" };
283 size = { code = 413; type = "modify"; condition = "resource-constraint", text = "Payload too large" };
280 }); 284 });
281 285
282 -- GET → iq-get 286 -- GET → iq-get
283 local function parse_request(request, path) 287 local function parse_request(request, path)
284 if path and request.method == "GET" then 288 if path and request.method == "GET" then
310 end 314 end
311 from = jid.join(origin.username, origin.host, origin.resource); 315 from = jid.join(origin.username, origin.host, origin.resource);
312 origin.full_jid = from; 316 origin.full_jid = from;
313 origin.type = "c2s"; 317 origin.type = "c2s";
314 origin.log = log; 318 origin.log = log;
319 end
320 if type(request.body) == "string" and #request.body > stanza_size_limit then
321 return post_errors.new("size", { size = #request.body; limit = stanza_size_limit });
315 end 322 end
316 local payload, err = parse_request(request, path); 323 local payload, err = parse_request(request, path);
317 if not payload then 324 if not payload then
318 -- parse fail 325 -- parse fail
319 local ctx = { error = err, type = request.headers.content_type, data = request.body, }; 326 local ctx = { error = err, type = request.headers.content_type, data = request.body, };