Skip to content

Commit

Permalink
Protect against CSRF by checking origin of POST request (#313)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwillchen authored May 28, 2024
1 parent abf2646 commit cb9d9d1
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions mesop/server/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import base64
import time
import urllib.parse as urlparse
from typing import Generator, Sequence

from flask import Flask, Response, abort, request, stream_with_context
Expand Down Expand Up @@ -156,6 +157,10 @@ def generate_data(ui_request: pb.UiRequest) -> Generator[str, None, None]:

@flask_app.route("/ui", methods=["POST"])
def ui_stream() -> Response:
# Prevent CSRF by checking the request origin matches the origin
# of the URL root (where the Flask app is being served from)
if not is_same_origin(request.headers.get("Origin"), request.url_root):
abort(403, "Rejecting cross-site POST request to /ui")
data = request.data
if not data:
raise Exception("Missing request payload")
Expand Down Expand Up @@ -192,3 +197,22 @@ def hot_reload() -> Response:
return response

return flask_app


def is_same_origin(url1: str | None, url2: str | None):
"""
Determine if two URLs share the same origin.
"""
# If either URL is false-y, they are not the same origin
# (because we need a real URL to have an actual origin)
if not url1:
return False
if not url2:
return False
try:
p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2)
origin1 = p1.scheme, p1.hostname, p1.port
origin2 = p2.scheme, p2.hostname, p2.port
return origin1 == origin2
except ValueError:
return False

0 comments on commit cb9d9d1

Please sign in to comment.