mod_websocket: Verify that the client-sent Origin header matches cross_domain_websocket (fixes #652)
authorKim Alvefur <zash@zash.se>
Mon, 05 Dec 2016 12:22:41 +0100
changeset 7765 2208e6cd0d9f
parent 7764 e0e1f6d6fb4f
child 7766 c5ce14539fc4
mod_websocket: Verify that the client-sent Origin header matches cross_domain_websocket (fixes #652)
plugins/mod_websocket.lua
--- a/plugins/mod_websocket.lua	Sun Dec 04 11:57:26 2016 +0100
+++ b/plugins/mod_websocket.lua	Mon Dec 05 12:22:41 2016 +0100
@@ -29,16 +29,16 @@
 
 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure");
-local cross_domain = module:get_option("cross_domain_websocket");
-if cross_domain then
+local cross_domain = module:get_option_set("cross_domain_websocket", {});
+if cross_domain:contains("*") or cross_domain:contains(true) then
+	cross_domain = true;
+end
+
+local function check_origin(origin)
 	if cross_domain == true then
-		cross_domain = "*";
-	elseif type(cross_domain) == "table" then
-		cross_domain = t_concat(cross_domain, ", ");
+		return true;
 	end
-	if type(cross_domain) ~= "string" then
-		cross_domain = nil;
-	end
+	return cross_domain:contains(origin);
 end
 
 local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing";
@@ -150,6 +150,11 @@
 		return 501;
 	end
 
+	if not check_origin(request.headers.origin or "") then
+		module:log("debug", "Origin %s is not allowed by 'cross_domain_websocket'", request.headers.origin or "(missing header)");
+		return 403;
+	end
+
 	local function websocket_close(code, message)
 		conn:write(build_close(code, message));
 		conn:close();
@@ -284,7 +289,6 @@
 	response.headers.connection = "Upgrade";
 	response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
 	response.headers.sec_webSocket_protocol = "xmpp";
-	response.headers.access_control_allow_origin = cross_domain;
 
 	session.log("debug", "Sending WebSocket handshake");