Skip to content

Commit

Permalink
Merge pull request ipython#4845 from rgbkrk/origin_host
Browse files Browse the repository at this point in the history
Add Origin checking for websockets.
  • Loading branch information
minrk committed Jan 31, 2014
2 parents 78e4627 + d3281c8 commit dd4135d
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions IPython/html/base/zmqhandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
# Imports
#-----------------------------------------------------------------------------

try:
from urllib.parse import urlparse # Py 3
except ImportError:
from urlparse import urlparse # Py 2

try:
from http.cookies import SimpleCookie # Py 3
except ImportError:
Expand All @@ -37,7 +42,30 @@
#-----------------------------------------------------------------------------

class ZMQStreamHandler(websocket.WebSocketHandler):


def same_origin(self):
"""Check to see that origin and host match in the headers."""

# The difference between version 8 and 13 is that in 8 the
# client sends a "Sec-Websocket-Origin" header and in 13 it's
# simply "Origin".
if self.request.headers.get("Sec-WebSocket-Version") in ("7", "8"):
origin_header = self.request.headers.get("Sec-Websocket-Origin")
else:
origin_header = self.request.headers.get("Origin")

host = self.request.headers.get("Host")

# If no header is provided, assume we can't verify origin
if(origin_header is None or host is None):
return False

parsed_origin = urlparse(origin_header)
origin = parsed_origin.netloc

# Check to see that origin matches host directly, including ports
return origin == host

def clear_cookie(self, *args, **kwargs):
"""meaningless for websockets"""
pass
Expand Down Expand Up @@ -86,6 +114,11 @@ def allow_draft76(self):
class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):

def open(self, kernel_id):
# Check to see that origin matches host directly, including ports
if not self.same_origin():
self.log.warn("Cross Origin WebSocket Attempt.")
raise web.HTTPError(404)

self.kernel_id = cast_unicode(kernel_id, 'ascii')
self.session = Session(config=self.config)
self.save_on_message = self.on_message
Expand Down Expand Up @@ -114,4 +147,4 @@ def on_first_message(self, msg):
if self.get_current_user() is None:
self.log.warn("Couldn't authenticate WebSocket connection")
raise web.HTTPError(403)
self.on_message = self.save_on_message
self.on_message = self.save_on_message

0 comments on commit dd4135d

Please sign in to comment.