Version in base suite: 0.12.3-1 Base version: prosody_0.12.3-1 Target version: prosody_0.12.3-1+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/p/prosody/prosody_0.12.3-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/p/prosody/prosody_0.12.3-1+deb12u1.dsc changelog | 9 patches/0005-CVE-2026-43504.patch | 68 ++++++ patches/0006-CVE-2026-43505.patch | 35 +++ patches/0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch | 54 +++++ patches/0008-net.server_epoll-Clean-up-timers-after-disconnection.patch | 45 ++++ patches/0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch | 38 +++ patches/0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch | 92 +++++++++ patches/0011-util.xmppstream-Support-limiting-total-number-of-des.patch | 101 ++++++++++ patches/0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch | 56 +++++ patches/series | 8 10 files changed, 506 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpqp5uu7wu/prosody_0.12.3-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpqp5uu7wu/prosody_0.12.3-1+deb12u1.dsc: no acceptable signature found diff -Nru prosody-0.12.3/debian/changelog prosody-0.12.3/debian/changelog --- prosody-0.12.3/debian/changelog 2023-02-22 08:56:38.000000000 +0000 +++ prosody-0.12.3/debian/changelog 2026-05-05 06:50:43.000000000 +0000 @@ -1,3 +1,12 @@ +prosody (0.12.3-1+deb12u1) bookworm-security; urgency=medium + + * CVE-2026-43504 fix + * CVE-2026-43505 fix + * CVE-2026-43506 fix + * CVE-2026-43507 fix + + -- Victor Seva Tue, 05 May 2026 08:50:43 +0200 + prosody (0.12.3-1) unstable; urgency=medium * New upstream version 0.12.3 diff -Nru prosody-0.12.3/debian/patches/0005-CVE-2026-43504.patch prosody-0.12.3/debian/patches/0005-CVE-2026-43504.patch --- prosody-0.12.3/debian/patches/0005-CVE-2026-43504.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0005-CVE-2026-43504.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,68 @@ +From: Matthew Wild +Date: Mon, 4 May 2026 19:16:12 +0200 +Subject: mod_proxy65: Consistently apply authorization checks + +The module checked for authorization when a client asked for the address:port +of the proxy service. It did not check for authorization when processing a +request to activate a bytestream. This meant that any unauthenticated party +able to guess the IP/port and XMPP domain of a proxy65 service (generally low +difficulty) would be able to use the proxy to relay traffic between two +connections. + +This factors out the permission check, and applies it to every request type. +--- + plugins/mod_proxy65.lua | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/plugins/mod_proxy65.lua b/plugins/mod_proxy65.lua +index 069ce0a..e912e2d 100644 +--- a/plugins/mod_proxy65.lua ++++ b/plugins/mod_proxy65.lua +@@ -105,25 +105,24 @@ function module.add_host(module) + module:add_identity("proxy", "bytestreams", name); + module:add_feature("http://jabber.org/protocol/bytestreams"); + +- module:hook("iq-get/host/http://jabber.org/protocol/bytestreams:query", function(event) +- local origin, stanza = event.origin, event.stanza; +- +- -- check ACL +- -- using 'while' instead of 'if' so we can break out of it +- local allow; ++ local function is_permitted(origin, stanza) + if proxy_acl and #proxy_acl > 0 then + local jid = stanza.attr.from; + for _, acl in ipairs(proxy_acl) do + if jid_compare(jid, acl) then +- allow = true; +- break; ++ return true; + end + end + elseif proxy_open_access or origin.type == "c2s" then +- allow = true; ++ return true; + end ++ return false; ++ end + +- if not allow then ++ module:hook("iq-get/host/http://jabber.org/protocol/bytestreams:query", function(event) ++ local origin, stanza = event.origin, event.stanza; ++ ++ if not is_permitted(origin, stanza) then + module:log("warn", "Denying use of proxy for %s", stanza.attr.from); + origin.send(st.error_reply(stanza, "auth", "forbidden")); + return true; +@@ -145,6 +144,12 @@ function module.add_host(module) + module:hook("iq-set/host/http://jabber.org/protocol/bytestreams:query", function(event) + local origin, stanza = event.origin, event.stanza; + ++ if not is_permitted(origin, stanza) then ++ module:log("warn", "Denying use of proxy for %s", stanza.attr.from); ++ origin.send(st.error_reply(stanza, "auth", "forbidden")); ++ return true; ++ end ++ + local query = stanza.tags[1]; + local sid = query.attr.sid; + local from = stanza.attr.from; diff -Nru prosody-0.12.3/debian/patches/0006-CVE-2026-43505.patch prosody-0.12.3/debian/patches/0006-CVE-2026-43505.patch --- prosody-0.12.3/debian/patches/0006-CVE-2026-43505.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0006-CVE-2026-43505.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,35 @@ +From: Matthew Wild +Date: Mon, 4 May 2026 19:21:58 +0200 +Subject: mod_proxy65: Don't link connections until after activation + +Although the module pauses the connections, in some cases server.link() (at +least with the epoll backend) will have the effect of unpausing the connection +(because it sets new read handlers). + +Many thanks to Max Hearnden for discovering and reporting this issue. +--- + plugins/mod_proxy65.lua | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/mod_proxy65.lua b/plugins/mod_proxy65.lua +index e912e2d..756e6e2 100644 +--- a/plugins/mod_proxy65.lua ++++ b/plugins/mod_proxy65.lua +@@ -60,8 +60,6 @@ function listener.onincoming(conn, data) + transfers[sha].initiator = conn; + session.sha = sha; + module:log("debug", "SOCKS5 initiator connected for session %s", sha); +- server.link(conn, transfers[sha].target, max_buffer_size); +- server.link(transfers[sha].target, conn, max_buffer_size); + end + else -- error, unexpected input + conn:write("\5\1\0\3\0\0\0"); -- VER, REP, RSV, ATYP, BND.ADDR (sha), BND.PORT (2 Byte) +@@ -171,6 +169,8 @@ function module.add_host(module) + else -- if transfers[sha].initiator ~= nil and transfers[sha].target ~= nil then + module:log("debug", "Transfer activated (%s)", info); + transfers[sha].activated = true; ++ server.link(transfers[sha].initiator, transfers[sha].target, max_buffer_size); ++ server.link(transfers[sha].target, transfers[sha].initiator, max_buffer_size); + transfers[sha].target:resume(); + transfers[sha].initiator:resume(); + origin.send(st.reply(stanza)); diff -Nru prosody-0.12.3/debian/patches/0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch prosody-0.12.3/debian/patches/0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch --- prosody-0.12.3/debian/patches/0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,54 @@ +From: Waqas Hussain +Date: Mon, 4 May 2026 19:38:41 +0200 +Subject: mod_c2s: Remove timers immediately on disconnection + +--- + plugins/mod_c2s.lua | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua +index c8f54fa..e948db5 100644 +--- a/plugins/mod_c2s.lua ++++ b/plugins/mod_c2s.lua +@@ -8,7 +8,9 @@ + + module:set_global(); + +-local add_task = require "util.timer".add_task; ++local timer = require "util.timer"; ++local add_task = timer.add_task; ++local stop_task = timer.stop; + local new_xmpp_stream = require "util.xmppstream".new; + local nameprep = require "util.encodings".stringprep.nameprep; + local sessionmanager = require "core.sessionmanager"; +@@ -27,6 +29,14 @@ local log = module._log; + + local c2s_timeout = module:get_option_number("c2s_timeout", 300); + local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); ++ ++local function stop_session_timers(session) ++ if session.c2s_timeout then ++ stop_task(session.c2s_timeout); ++ session.c2s_timeout = nil; ++ end ++end ++ + local opt_keepalives = module:get_option_boolean("c2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true)); + local stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 1024*256); + +@@ -190,6 +200,7 @@ local function session_close(session, reason) + local close_event_payload = { session = session, reason = reason }; + module:context(session.host):fire_event("pre-session-close", close_event_payload); + reason = close_event_payload.reason; ++ stop_session_timers(session); + if session.conn then + if session.notopen then + session:open_stream(); +@@ -379,6 +390,7 @@ function listener.ondisconnect(conn, err) + local session = sessions[conn]; + if session then + (session.log or log)("info", "Client disconnected: %s", err or "connection closed"); ++ stop_session_timers(session); + sm_destroy_session(session, err); + session.conn = nil; + sessions[conn] = nil; diff -Nru prosody-0.12.3/debian/patches/0008-net.server_epoll-Clean-up-timers-after-disconnection.patch prosody-0.12.3/debian/patches/0008-net.server_epoll-Clean-up-timers-after-disconnection.patch --- prosody-0.12.3/debian/patches/0008-net.server_epoll-Clean-up-timers-after-disconnection.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0008-net.server_epoll-Clean-up-timers-after-disconnection.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,45 @@ +From: Waqas Hussain +Date: Mon, 4 May 2026 19:47:55 +0200 +Subject: net.server_epoll: Clean up timers after disconnection + +--- + net/server_epoll.lua | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/net/server_epoll.lua b/net/server_epoll.lua +index fa275d7..e7e4557 100644 +--- a/net/server_epoll.lua ++++ b/net/server_epoll.lua +@@ -106,9 +106,8 @@ local function noop() end + local closedtimers = {}; + + local function closetimer(id) +- if timers:remove(id) then +- closedtimers[id] = true; +- end ++ closedtimers[id] = true; ++ timers:remove(id); + end + + local function reschedule(id, time) +@@ -595,6 +594,10 @@ end + + function interface:destroy() + self:del(); ++ if self._pausefor then ++ closetimer(self._pausefor); ++ self._pausefor = nil; ++ end + self:setwritetimeout(false); + self:setreadtimeout(false); + self.onreadable = noop; +@@ -822,6 +825,9 @@ function interface:pausefor(t) + self:set(false); + self._pausefor = addtimer(t, function () + self._pausefor = nil; ++ if not self.conn then ++ return; ++ end + self:set(true); + self:noise("Resuming after pause"); + if self.conn and self.conn:dirty() then diff -Nru prosody-0.12.3/debian/patches/0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch prosody-0.12.3/debian/patches/0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch --- prosody-0.12.3/debian/patches/0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,38 @@ +From: Matthew Wild +Date: Mon, 4 May 2026 19:50:28 +0200 +Subject: moduleapi: Use multitable add/remove instead of set + +multitable:set() does not clear intermediate keys when setting the last one to +nil. This meant that the event_handlers multitable for every module was not +properly cleaning up the object and event name from the table when calling +:unhook_object_event(). + +This combined badly with e.g. mod_bookmarks, which uses this extensively to +add/remove hooks dynamically for mod_pep services. The multitable kept a +reference to every mod_pep service object ever created, causing a memory leak. + +The multitable:remove() function clears intermediate keys when they are empty, +so we've switched to using that now. +--- + core/moduleapi.lua | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/core/moduleapi.lua b/core/moduleapi.lua +index 870a6a5..dc326f5 100644 +--- a/core/moduleapi.lua ++++ b/core/moduleapi.lua +@@ -81,12 +81,12 @@ function api:fire_event(...) + end + + function api:hook_object_event(object, event, handler, priority) +- self.event_handlers:set(object, event, handler, true); ++ self.event_handlers:add(object, event, handler, true); + return object.add_handler(event, handler, priority); + end + + function api:unhook_object_event(object, event, handler) +- self.event_handlers:set(object, event, handler, nil); ++ self.event_handlers:remove(object, event, handler); + return object.remove_handler(event, handler); + end + diff -Nru prosody-0.12.3/debian/patches/0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch prosody-0.12.3/debian/patches/0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch --- prosody-0.12.3/debian/patches/0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,92 @@ +From: Kim Alvefur +Date: Mon, 4 May 2026 19:59:42 +0200 +Subject: mod_c2s,mod_s2s: Introduce separate pre-authentication stanza size + limit + +This should prevent unauthenticated resource use via the XML parser. +--- + plugins/mod_c2s.lua | 14 ++++++++++++-- + plugins/mod_s2s.lua | 10 ++++++++-- + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua +index e948db5..791d1e0 100644 +--- a/plugins/mod_c2s.lua ++++ b/plugins/mod_c2s.lua +@@ -38,7 +38,8 @@ local function stop_session_timers(session) + end + + local opt_keepalives = module:get_option_boolean("c2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true)); +-local stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 1024*256); ++local unauthed_stanza_size_limit = module:get_option_number("c2s_unauthed_stanza_size_limit", 10000,1000); ++local authed_stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 1024*256,10000); + + local measure_connections = module:metric("gauge", "connections", "", "Established c2s connections", {"host", "type", "ip_family"}); + +@@ -323,7 +324,9 @@ function listener.onconnect(conn) + + session.close = session_close; + +- local stream = new_xmpp_stream(session, stream_callbacks, stanza_size_limit); ++ session.stanza_size_limit = unauthed_stanza_size_limit; ++ ++ local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit); + session.stream = stream; + session.notopen = true; + +@@ -432,6 +435,13 @@ end + + function module.add_host(module) + module:hook("c2s-read-timeout", keepalive, -1); ++ module:hook("authentication-success", function(event) ++ local session = event.session; ++ if session.stream then ++ session.stanza_size_limit = authed_stanza_size_limit; ++ session.stream:set_stanza_size_limit(session.stanza_size_limit); ++ end ++ end); + end + + module:hook("c2s-read-timeout", keepalive, -1); +diff --git a/plugins/mod_s2s.lua b/plugins/mod_s2s.lua +index 300a747..0fd0f96 100644 +--- a/plugins/mod_s2s.lua ++++ b/plugins/mod_s2s.lua +@@ -41,7 +41,8 @@ local secure_auth = module:get_option_boolean("s2s_secure_auth", false); -- One + local secure_domains, insecure_domains = + module:get_option_set("s2s_secure_domains", {})._items, module:get_option_set("s2s_insecure_domains", {})._items; + local require_encryption = module:get_option_boolean("s2s_require_encryption", true); +-local stanza_size_limit = module:get_option_number("s2s_stanza_size_limit", 1024*512); ++local unauthed_stanza_size_limit = module:get_option_number("s2s_unauthed_stanza_size_limit", 10000, 1000); ++local authed_stanza_size_limit = module:get_option_number("s2s_stanza_size_limit", 1024*512, 10000); + + local measure_connections_inbound = module:metric( + "gauge", "connections_inbound", "", +@@ -213,6 +214,8 @@ function route_to_new_session(event) + local host_session = s2s_new_outgoing(from_host, to_host); + host_session.version = 1; + ++ host_session.stanza_size_limit = unauthed_stanza_size_limit; ++ + -- Store in buffer + host_session.bounce_sendq = bounce_sendq; + host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; +@@ -369,6 +372,9 @@ function make_authenticated(event) + return false; + end + ++ session.stanza_size_limit = authed_stanza_size_limit; ++ session.stream:set_stanza_size_limit(session.stanza_size_limit); ++ + if session.incoming and host then + if not session.hosts[host] then session.hosts[host] = {}; end + session.hosts[host].authed = true; +@@ -726,7 +732,7 @@ end + + -- Session initialization logic shared by incoming and outgoing + local function initialize_session(session) +- local stream = new_xmpp_stream(session, stream_callbacks, stanza_size_limit); ++ local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit or unauthed_stanza_size_limit); + + session.thread = runner(function (stanza) + if st.is_stanza(stanza) then diff -Nru prosody-0.12.3/debian/patches/0011-util.xmppstream-Support-limiting-total-number-of-des.patch prosody-0.12.3/debian/patches/0011-util.xmppstream-Support-limiting-total-number-of-des.patch --- prosody-0.12.3/debian/patches/0011-util.xmppstream-Support-limiting-total-number-of-des.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0011-util.xmppstream-Support-limiting-total-number-of-des.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,101 @@ +From: Matthew Wild +Date: Mon, 4 May 2026 20:00:54 +0200 +Subject: util.xmppstream: Support limiting total number of descendent + elements in a stanza + +--- + util/xmppstream.lua | 35 ++++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +diff --git a/util/xmppstream.lua b/util/xmppstream.lua +index be11339..348bc6f 100644 +--- a/util/xmppstream.lua ++++ b/util/xmppstream.lua +@@ -43,7 +43,7 @@ local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$"; + + local function dummy_cb() end + +-local function new_sax_handlers(session, stream_callbacks, cb_handleprogress) ++local function new_sax_handlers(session, stream_callbacks, cb_handleprogress, max_elements) + local xml_handlers = {}; + + local cb_streamopened = stream_callbacks.streamopened; +@@ -69,6 +69,7 @@ local function new_sax_handlers(session, stream_callbacks, cb_handleprogress) + local stack = {}; + local chardata, stanza = {}; + local stanza_size = 0; ++ local child_quota = 0; + local non_streamns_depth = 0; + function xml_handlers:StartElement(tagname, attr) + if stanza and #chardata > 0 then +@@ -86,6 +87,18 @@ local function new_sax_handlers(session, stream_callbacks, cb_handleprogress) + non_streamns_depth = non_streamns_depth + 1; + end + ++ if stanza and child_quota then ++ -- Check stanza complexity limits ++ child_quota = child_quota - 1; ++ if child_quota <= 0 then ++ cb_error(session, "parse-error", "resource-constraint", "Stanza exceeds permitted children"); ++ if not self.stop or not self:stop() then ++ error("Failed to abort parsing"); ++ end ++ return; ++ end ++ end ++ + for i=1,#attr do + local k = attr[i]; + attr[i] = nil; +@@ -122,6 +135,7 @@ local function new_sax_handlers(session, stream_callbacks, cb_handleprogress) + end + + stanza = setmetatable({ name = name, attr = attr, tags = {} }, stanza_mt); ++ child_quota = max_elements; + else -- we are inside a stanza, so add a tag + if lxp_supports_bytecount then + stanza_size = stanza_size + self:getcurrentbytecount(); +@@ -237,10 +251,18 @@ local function new_sax_handlers(session, stream_callbacks, cb_handleprogress) + session = new_session; + end + +- return xml_handlers, { reset = reset, set_session = set_session }; ++ local function set_max_elements(new_max_elements) ++ max_elements = new_max_elements; ++ end ++ ++ return xml_handlers, { ++ reset = reset; ++ set_session = set_session; ++ set_max_elements = set_max_elements; ++ }; + end + +-local function new(session, stream_callbacks, stanza_size_limit) ++local function new(session, stream_callbacks, stanza_size_limit, ex) + -- Used to track parser progress (e.g. to enforce size limits) + local n_outstanding_bytes = 0; + local handle_progress; +@@ -253,8 +275,10 @@ local function new(session, stream_callbacks, stanza_size_limit) + error("Stanza size limits are not supported on this version of LuaExpat") + end + ++ local max_elements = ex and ex.max_elements; ++ + local handlers, meta = new_sax_handlers(session, stream_callbacks, handle_progress); +- local parser = new_parser(handlers, ns_separator, false); ++ local parser = new_parser(handlers, ns_separator, false, max_elements); + local parse = parser.parse; + + function session.open_stream(session, from, to) -- luacheck: ignore 432/session +@@ -298,8 +322,9 @@ local function new(session, stream_callbacks, stanza_size_limit) + return ok, err; + end, + set_session = meta.set_session; +- set_stanza_size_limit = function (_, new_stanza_size_limit) ++ set_stanza_size_limit = function (_, new_stanza_size_limit, new_max_elements) + stanza_size_limit = new_stanza_size_limit; ++ meta.set_max_elements(new_max_elements); + end; + }; + end diff -Nru prosody-0.12.3/debian/patches/0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch prosody-0.12.3/debian/patches/0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch --- prosody-0.12.3/debian/patches/0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch 1970-01-01 00:00:00.000000000 +0000 +++ prosody-0.12.3/debian/patches/0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch 2026-05-05 06:50:43.000000000 +0000 @@ -0,0 +1,56 @@ +From: Matthew Wild +Date: Mon, 4 May 2026 20:02:58 +0200 +Subject: mod_c2s, + mod_s2s: Add configurable limit for stanza max child elements + +--- + plugins/mod_c2s.lua | 5 ++++- + plugins/mod_s2s.lua | 5 ++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua +index 791d1e0..d277e47 100644 +--- a/plugins/mod_c2s.lua ++++ b/plugins/mod_c2s.lua +@@ -40,6 +40,7 @@ end + local opt_keepalives = module:get_option_boolean("c2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true)); + local unauthed_stanza_size_limit = module:get_option_number("c2s_unauthed_stanza_size_limit", 10000,1000); + local authed_stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 1024*256,10000); ++local max_child_elements = module:get_option_number("c2s_max_child_elements", 25000, 0); + + local measure_connections = module:metric("gauge", "connections", "", "Established c2s connections", {"host", "type", "ip_family"}); + +@@ -326,7 +327,9 @@ function listener.onconnect(conn) + + session.stanza_size_limit = unauthed_stanza_size_limit; + +- local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit); ++ local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit, { ++ max_elements = max_child_elements; ++ }); + session.stream = stream; + session.notopen = true; + +diff --git a/plugins/mod_s2s.lua b/plugins/mod_s2s.lua +index 0fd0f96..ae09195 100644 +--- a/plugins/mod_s2s.lua ++++ b/plugins/mod_s2s.lua +@@ -43,6 +43,7 @@ local secure_domains, insecure_domains = + local require_encryption = module:get_option_boolean("s2s_require_encryption", true); + local unauthed_stanza_size_limit = module:get_option_number("s2s_unauthed_stanza_size_limit", 10000, 1000); + local authed_stanza_size_limit = module:get_option_number("s2s_stanza_size_limit", 1024*512, 10000); ++local max_child_elements = module:get_option_number("s2s_max_child_elements", 25000, 0); + + local measure_connections_inbound = module:metric( + "gauge", "connections_inbound", "", +@@ -732,7 +733,9 @@ end + + -- Session initialization logic shared by incoming and outgoing + local function initialize_session(session) +- local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit or unauthed_stanza_size_limit); ++ local stream = new_xmpp_stream(session, stream_callbacks, session.stanza_size_limit, { ++ max_elements = max_child_elements; ++ }); + + session.thread = runner(function (stanza) + if st.is_stanza(stanza) then diff -Nru prosody-0.12.3/debian/patches/series prosody-0.12.3/debian/patches/series --- prosody-0.12.3/debian/patches/series 2023-02-22 08:56:38.000000000 +0000 +++ prosody-0.12.3/debian/patches/series 2026-05-05 06:50:43.000000000 +0000 @@ -1,3 +1,11 @@ 0001-conf.patch 0002-upstream-conf.patch 0004-fix-package.path-of-ejabberd2prosody.patch +0005-CVE-2026-43504.patch +0006-CVE-2026-43505.patch +0007-mod_c2s-Remove-timers-immediately-on-disconnection.patch +0008-net.server_epoll-Clean-up-timers-after-disconnection.patch +0009-moduleapi-Use-multitable-add-remove-instead-of-set.patch +0010-mod_c2s-mod_s2s-Introduce-separate-pre-authenticatio.patch +0011-util.xmppstream-Support-limiting-total-number-of-des.patch +0012-mod_c2s-mod_s2s-Add-configurable-limit-for-stanza-ma.patch