new: secured the web ui with CORS
This commit is contained in:
parent
539df810ed
commit
d45e8c7ba0
@ -175,6 +175,7 @@ ui:
|
|||||||
video:
|
video:
|
||||||
enabled: true
|
enabled: true
|
||||||
address: '0.0.0.0'
|
address: '0.0.0.0'
|
||||||
|
origin: '*'
|
||||||
port: 8080
|
port: 8080
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,13 +73,30 @@ SHUTDOWN = """<html>
|
|||||||
|
|
||||||
|
|
||||||
class Handler(BaseHTTPRequestHandler):
|
class Handler(BaseHTTPRequestHandler):
|
||||||
|
AllowedOrigin = '*'
|
||||||
|
|
||||||
# suppress internal logging
|
# suppress internal logging
|
||||||
def log_message(self, format, *args):
|
def log_message(self, format, *args):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _send_cors_headers(self):
|
||||||
|
# misc security
|
||||||
|
self.send_header("X-Frame-Options", "DENY")
|
||||||
|
self.send_header("X-Content-Type-Options", "nosniff")
|
||||||
|
self.send_header("X-XSS-Protection", "1; mode=block")
|
||||||
|
self.send_header("Referrer-Policy", "same-origin")
|
||||||
|
# cors
|
||||||
|
self.send_header("Access-Control-Allow-Origin", Handler.AllowedOrigin)
|
||||||
|
self.send_header('Access-Control-Allow-Credentials', 'true')
|
||||||
|
self.send_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||||
|
self.send_header("Access-Control-Allow-Headers",
|
||||||
|
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
||||||
|
self.send_header("Vary", "Origin")
|
||||||
|
|
||||||
# just render some html in a 200 response
|
# just render some html in a 200 response
|
||||||
def _html(self, html):
|
def _html(self, html):
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
|
self._send_cors_headers()
|
||||||
self.send_header('Content-type', 'text/html')
|
self.send_header('Content-type', 'text/html')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
try:
|
try:
|
||||||
@ -98,10 +115,11 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
# serve the PNG file with the display image
|
# serve the PNG file with the display image
|
||||||
def _image(self):
|
def _image(self):
|
||||||
global frame_path, frame_ctype
|
global frame_lock, frame_path, frame_ctype
|
||||||
|
|
||||||
with frame_lock:
|
with frame_lock:
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
|
self._send_cors_headers()
|
||||||
self.send_header('Content-type', frame_ctype)
|
self.send_header('Content-type', frame_ctype)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
try:
|
try:
|
||||||
@ -110,13 +128,32 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def do_OPTIONS(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self._send_cors_headers()
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
# check the Origin header vs CORS
|
||||||
|
def _is_allowed(self):
|
||||||
|
origin = self.headers.get('origin')
|
||||||
|
if origin == "":
|
||||||
|
logging.warning("request with no Origin header from %s" % self.address_string())
|
||||||
|
return False
|
||||||
|
|
||||||
|
if Handler.AllowedOrigin != '*':
|
||||||
|
if origin != Handler.AllowedOrigin and not origin.starts_with(Handler.AllowedOrigin):
|
||||||
|
logging.warning("request with blocked Origin from %s: %s" % (self.address_string(), origin))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
# main entry point of the http server
|
# main entry point of the http server
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
global frame_lock
|
if not self._is_allowed():
|
||||||
|
return
|
||||||
|
|
||||||
if self.path == '/':
|
if self.path == '/':
|
||||||
self._index()
|
self._index()
|
||||||
|
|
||||||
elif self.path.startswith('/shutdown'):
|
elif self.path.startswith('/shutdown'):
|
||||||
self._shutdown()
|
self._shutdown()
|
||||||
|
|
||||||
@ -133,6 +170,12 @@ class Server(object):
|
|||||||
self._address = config['video']['address']
|
self._address = config['video']['address']
|
||||||
self._httpd = None
|
self._httpd = None
|
||||||
|
|
||||||
|
if 'origin' in config['video'] and config['video']['origin'] != '*':
|
||||||
|
Handler.AllowedOrigin = config['video']['origin']
|
||||||
|
else:
|
||||||
|
logging.warning("THE WEB UI IS RUNNING WITH ALLOWED ORIGIN SET TO *, READ WHY YOU SHOULD CHANGE IT HERE \
|
||||||
|
https://developer.mozilla.org/it/docs/Web/HTTP/CORS")
|
||||||
|
|
||||||
if self._enabled:
|
if self._enabled:
|
||||||
_thread.start_new_thread(self._http_serve, ())
|
_thread.start_new_thread(self._http_serve, ())
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user