changeset 14150:2a66728d9e29 13.0 13.0.5

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.
author Matthew Wild <mwild1@gmail.com>
date Wed, 29 Apr 2026 11:40:43 +0100
parents 9c98cc9d9588
children 4985de195749
files plugins/mod_proxy65.lua
diffstat 1 files changed, 15 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_proxy65.lua	Wed Apr 29 11:37:21 2026 +0100
+++ b/plugins/mod_proxy65.lua	Wed Apr 29 11:40:43 2026 +0100
@@ -103,25 +103,24 @@
 	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;
@@ -143,6 +142,12 @@
 	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;