diff --git a/frigate/api/auth.py b/frigate/api/auth.py index c712ec925e..2fb14badcc 100644 --- a/frigate/api/auth.py +++ b/frigate/api/auth.py @@ -739,6 +739,13 @@ def auth(request: Request): int(request.headers.get("x-server-port", default=0)) == request.app.auth_internal_port ): + # go2rtc runs the producer an unknown src describes for any caller + deny_status = deny_response_for_go2rtc_stream( + request.headers.get("x-original-url"), None, request + ) + if deny_status is not None: + return Response("", status_code=deny_status) + success_response.headers["remote-user"] = "anonymous" success_response.headers["remote-role"] = "admin" return success_response diff --git a/frigate/test/http_api/test_http_auth_internal_port.py b/frigate/test/http_api/test_http_auth_internal_port.py index bbb28c82b7..1f2d820635 100644 --- a/frigate/test/http_api/test_http_auth_internal_port.py +++ b/frigate/test/http_api/test_http_auth_internal_port.py @@ -5,6 +5,7 @@ import tempfile import unittest from unittest.mock import MagicMock, Mock, patch +import requests import ruamel.yaml from fastapi import Request @@ -234,6 +235,51 @@ class TestAuthInternalPort(BaseTestHttp): finally: os.unlink(config_path) + @patch( + "frigate.api.auth.requests.get", + side_effect=requests.ConnectionError("go2rtc unavailable"), + ) + def test_internal_port_rejects_unknown_go2rtc_src(self, _mock_get): + app = self._create_app() + + with AuthTestClient(app) as client: + for url in ( + "/live/mse/api/ws?src=exec:id", + "/live/webrtc/api/ws?src=ffmpeg:x%23raw=-f", + "/api/go2rtc/webrtc?src=front_door&src=unknown", + ): + resp = client.get( + "/auth", + headers={"x-server-port": "5000", "x-original-url": url}, + ) + self.assertEqual(resp.status_code, 403, url) + + def test_internal_port_allows_existing_go2rtc_stream(self): + app = self._create_app() + + with AuthTestClient(app) as client: + resp = client.get( + "/auth", + headers={ + "x-server-port": "5000", + "x-original-url": "/live/mse/api/ws?src=front_door", + }, + ) + + self.assertEqual(resp.status_code, 202) + self.assertEqual(resp.headers["remote-role"], "admin") + + def test_internal_port_skips_go2rtc_check_for_other_paths(self): + app = self._create_app() + + with AuthTestClient(app) as client: + for url in ("/api/stats", "/api/go2rtc/streams?src=unknown"): + resp = client.get( + "/auth", + headers={"x-server-port": "5000", "x-original-url": url}, + ) + self.assertEqual(resp.status_code, 202, url) + if __name__ == "__main__": unittest.main(verbosity=2)