mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-09 17:08:29 +00:00
Fix Tailscale Remote Control CSRF origins
Normalize active Remote Control URLs to same-origin values before adding them to CSRF allowlists, so Tailscale Funnel URLs with paths or trailing slashes can bootstrap tokens correctly. Allow WebSocket origin validation to trust only the currently active Remote Control origin, including Docker split-process tunnel service URLs, while preserving rejection for unrelated external origins. Add focused regression coverage for active Tailscale-style origins, tunnel-service origin lookup, and negative cross-origin cases; keep run_ui decorator re-exports compatible with existing CSRF tests.
This commit is contained in:
parent
85e28d0799
commit
ca4efe6e6a
6 changed files with 320 additions and 9 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import secrets
|
||||
from urllib.parse import urlparse
|
||||
from helpers.api import (
|
||||
ApiHandler,
|
||||
Input,
|
||||
|
|
@ -9,6 +8,7 @@ from helpers.api import (
|
|||
session,
|
||||
)
|
||||
from helpers import runtime, dotenv, login
|
||||
from helpers.tunnel_origins import origin_from_url
|
||||
import fnmatch
|
||||
|
||||
ALLOWED_ORIGINS_KEY = "ALLOWED_ORIGINS"
|
||||
|
|
@ -82,11 +82,7 @@ class GetCsrfToken(ApiHandler):
|
|||
)
|
||||
if not r:
|
||||
return None
|
||||
# parse and normalize
|
||||
p = urlparse(r)
|
||||
if not p.scheme or not p.hostname:
|
||||
return None
|
||||
return f"{p.scheme}://{p.hostname}" + (f":{p.port}" if p.port else "")
|
||||
return origin_from_url(r)
|
||||
|
||||
async def get_allowed_origins(self) -> list[str]:
|
||||
# get the allowed origins from the environment
|
||||
|
|
@ -107,8 +103,10 @@ class GetCsrfToken(ApiHandler):
|
|||
from api.tunnel_proxy import process as tunnel_api_process
|
||||
|
||||
tunnel = await tunnel_api_process({"action": "get"})
|
||||
if tunnel and isinstance(tunnel, dict) and tunnel["success"]:
|
||||
allowed_origins.append(tunnel["tunnel_url"])
|
||||
if tunnel and isinstance(tunnel, dict) and tunnel.get("success"):
|
||||
tunnel_origin = origin_from_url(tunnel.get("tunnel_url"))
|
||||
if tunnel_origin:
|
||||
allowed_origins.append(tunnel_origin)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue