Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b885130

Browse files
Prevent cross-origin webagg connections
1 parent a01f57d commit b885130

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

lib/matplotlib/backends/backend_webagg.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import json
1616
import mimetypes
1717
from pathlib import Path
18+
from urllib.parse import urlparse
1819
import random
1920
import sys
2021
import signal
@@ -128,6 +129,17 @@ def get(self, fignum, fmt):
128129
class WebSocket(tornado.websocket.WebSocketHandler):
129130
supports_binary = True
130131

132+
def check_origin(self, origin):
133+
parsed = urlparse(origin)
134+
# Allow connections where the origin host matches the request
135+
# host. This blocks cross-origin WebSocket connections (e.g.
136+
# a malicious webpage connecting to the local WebAgg server)
137+
# while allowing legitimate same-origin connections. Overrides
138+
# Tornado's default method
139+
request_host = self.request.host.split(':')[0]
140+
origin_host = parsed.hostname
141+
return origin_host == request_host
142+
131143
def open(self, fignum):
132144
self.fignum = int(fignum)
133145
self.manager = Gcf.get_fig_manager(self.fignum)

lib/matplotlib/tests/test_backend_webagg.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import sys
3+
from unittest.mock import MagicMock
34
import pytest
45

56
import matplotlib.backends.backend_webagg_core
@@ -30,3 +31,22 @@ def test_webagg_fallback(backend):
3031
def test_webagg_core_no_toolbar():
3132
fm = matplotlib.backends.backend_webagg_core.FigureManagerWebAgg
3233
assert fm._toolbar2_class is None
34+
35+
36+
def test_websocket_check_origin():
37+
"""WebSocket should reject cross-origin connections."""
38+
pytest.importorskip("tornado")
39+
from matplotlib.backends.backend_webagg import WebAggApplication
40+
41+
ws_cls = WebAggApplication.WebSocket
42+
43+
ws = ws_cls.__new__(ws_cls)
44+
ws.request = MagicMock()
45+
ws.request.host = 'localhost:8988'
46+
47+
# Same origin should be accepted.
48+
assert ws.check_origin('http://localhost:8988') is True
49+
50+
# Cross-origin should be rejected.
51+
assert ws.check_origin('http://evil.com') is False
52+
assert ws.check_origin('http://127.0.0.1:8988') is False

0 commit comments

Comments
 (0)