Software /
code /
prosody
Comparison
plugins/mod_websocket.lua @ 7762:2208e6cd0d9f
mod_websocket: Verify that the client-sent Origin header matches cross_domain_websocket (fixes #652)
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 05 Dec 2016 12:22:41 +0100 |
parent | 7761:e0e1f6d6fb4f |
child | 7763:c5ce14539fc4 |
comparison
equal
deleted
inserted
replaced
7761:e0e1f6d6fb4f | 7762:2208e6cd0d9f |
---|---|
27 | 27 |
28 local t_concat = table.concat; | 28 local t_concat = table.concat; |
29 | 29 |
30 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); | 30 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); |
31 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); | 31 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); |
32 local cross_domain = module:get_option("cross_domain_websocket"); | 32 local cross_domain = module:get_option_set("cross_domain_websocket", {}); |
33 if cross_domain then | 33 if cross_domain:contains("*") or cross_domain:contains(true) then |
34 cross_domain = true; | |
35 end | |
36 | |
37 local function check_origin(origin) | |
34 if cross_domain == true then | 38 if cross_domain == true then |
35 cross_domain = "*"; | 39 return true; |
36 elseif type(cross_domain) == "table" then | 40 end |
37 cross_domain = t_concat(cross_domain, ", "); | 41 return cross_domain:contains(origin); |
38 end | |
39 if type(cross_domain) ~= "string" then | |
40 cross_domain = nil; | |
41 end | |
42 end | 42 end |
43 | 43 |
44 local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; | 44 local xmlns_framing = "urn:ietf:params:xml:ns:xmpp-framing"; |
45 local xmlns_streams = "http://etherx.jabber.org/streams"; | 45 local xmlns_streams = "http://etherx.jabber.org/streams"; |
46 local xmlns_client = "jabber:client"; | 46 local xmlns_client = "jabber:client"; |
146 local wants_xmpp = contains_token(request.headers.sec_websocket_protocol or "", "xmpp"); | 146 local wants_xmpp = contains_token(request.headers.sec_websocket_protocol or "", "xmpp"); |
147 | 147 |
148 if not wants_xmpp then | 148 if not wants_xmpp then |
149 module:log("debug", "Client didn't want to talk XMPP, list of protocols was %s", request.headers.sec_websocket_protocol or "(empty)"); | 149 module:log("debug", "Client didn't want to talk XMPP, list of protocols was %s", request.headers.sec_websocket_protocol or "(empty)"); |
150 return 501; | 150 return 501; |
151 end | |
152 | |
153 if not check_origin(request.headers.origin or "") then | |
154 module:log("debug", "Origin %s is not allowed by 'cross_domain_websocket'", request.headers.origin or "(missing header)"); | |
155 return 403; | |
151 end | 156 end |
152 | 157 |
153 local function websocket_close(code, message) | 158 local function websocket_close(code, message) |
154 conn:write(build_close(code, message)); | 159 conn:write(build_close(code, message)); |
155 conn:close(); | 160 conn:close(); |
282 response.status_code = 101; | 287 response.status_code = 101; |
283 response.headers.upgrade = "websocket"; | 288 response.headers.upgrade = "websocket"; |
284 response.headers.connection = "Upgrade"; | 289 response.headers.connection = "Upgrade"; |
285 response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); | 290 response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); |
286 response.headers.sec_webSocket_protocol = "xmpp"; | 291 response.headers.sec_webSocket_protocol = "xmpp"; |
287 response.headers.access_control_allow_origin = cross_domain; | |
288 | 292 |
289 session.log("debug", "Sending WebSocket handshake"); | 293 session.log("debug", "Sending WebSocket handshake"); |
290 | 294 |
291 return ""; | 295 return ""; |
292 end | 296 end |