changeset 14152:fed0dd8dda09 0.12

mod_c2s,mod_s2s: Introduce separate pre-authentication stanza size limit This should prevent unauthenticated resource use via the XML parser.
author Kim Alvefur <zash@zash.se>
date Tue, 07 Apr 2026 20:35:41 +0200
parents 1ef39ce837be
children aa29d5144c20
files plugins/mod_c2s.lua plugins/mod_s2s.lua
diffstat 2 files changed, 20 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_c2s.lua	Sun Dec 29 12:13:29 2024 +0000
+++ b/plugins/mod_c2s.lua	Tue Apr 07 20:35:41 2026 +0200
@@ -28,7 +28,8 @@
 local c2s_timeout = module:get_option_number("c2s_timeout", 300);
 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
 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"});
 
@@ -312,7 +313,9 @@
 
 	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;
 
@@ -420,6 +423,13 @@
 
 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);
--- a/plugins/mod_s2s.lua	Sun Dec 29 12:13:29 2024 +0000
+++ b/plugins/mod_s2s.lua	Tue Apr 07 20:35:41 2026 +0200
@@ -41,7 +41,8 @@
 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 @@
 	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)} };
@@ -373,6 +376,9 @@
 		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;
@@ -730,7 +736,7 @@
 
 -- 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