mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix(dashboard): relax frame security headers when running under launcher (#8554)
* fix(dashboard): relax frame security headers when running under launcher
When AstrBot is launched by the AstrBot Launcher, the dashboard is
embedded in a cross-origin iframe (the Tauri webview). The plugin page
responses set X-Frame-Options: SAMEORIGIN and CSP frame-ancestors
'self', both of which inspect the *entire* ancestor chain — not just the
immediate parent. Because the top-level Tauri webview has a different
origin, these headers block the plugin page from loading inside the
nested iframe, resulting in 'localhost refused to connect'.
Fix: skip the restrictive frame headers when ASTRBOT_LAUNCHER=1 is set,
which the launcher already injects as an environment variable. Other
security measures (iframe sandbox, JWT asset_token, postMessage bridge)
remain in place.
* fix(dashboard): preserve object-src and base-uri CSP directives under launcher
Keep object-src 'none' and base-uri 'self' in the CSP header even when
ASTRBOT_LAUNCHER is set. Only frame-ancestors and X-Frame-Options need
to be relaxed because the Tauri webview is a cross-origin ancestor.
* fix(dashboard): tighten ASTRBOT_LAUNCHER check and always emit CSP
Use explicit value check ('1' / 'true') instead of truthiness for the
ASTRBOT_LAUNCHER env var. Always emit a Content-Security-Policy header
and only conditionally prepend frame-ancestors 'self' — this keeps
object-src 'none' and base-uri 'self' active under the launcher.
This commit is contained in:
@@ -789,14 +789,21 @@ class PluginRoute(Route):
|
||||
response.headers["Cache-Control"] = "no-store"
|
||||
response.headers["Referrer-Policy"] = "no-referrer"
|
||||
response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||
response.headers["Cross-Origin-Resource-Policy"] = "cross-origin"
|
||||
# Sandboxed iframes without allow-same-origin load ES modules with Origin: null.
|
||||
# CORS read access is allowed here; JWT/asset_token still protects the assets.
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
response.headers["Content-Security-Policy"] = (
|
||||
"frame-ancestors 'self'; object-src 'none'; base-uri 'self'"
|
||||
)
|
||||
|
||||
# When running under the AstrBot Launcher the dashboard is embedded in a
|
||||
# cross-origin iframe (the Tauri webview). Since frame-ancestors and
|
||||
# X-Frame-Options inspect the *entire* ancestor chain, enforcing them here
|
||||
# would block plugin pages from loading inside the nested iframe.
|
||||
csp = "object-src 'none'; base-uri 'self'"
|
||||
if os.environ.get("ASTRBOT_LAUNCHER") not in ("1", "true"):
|
||||
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||
csp = f"frame-ancestors 'self'; {csp}"
|
||||
response.headers["Content-Security-Policy"] = csp
|
||||
|
||||
return response
|
||||
|
||||
async def _serve_plugin_page_html_asset(
|
||||
|
||||
Reference in New Issue
Block a user