feat(asr-pipeline): merge PR #1 webauth/CSRF/locking hardening and web_password fallback
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""Browser session helpers shared by the new workbench and the legacy control UI.
|
||||
|
||||
An empty ``ASR_WEB_PASSWORD`` closes the UI. Set ``ASR_WEB_ALLOW_ANON=1`` only
|
||||
for a local process that is not reachable from the network.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
from http import cookies
|
||||
|
||||
|
||||
from .config import get_setting
|
||||
|
||||
|
||||
def allow_anon() -> bool:
|
||||
return os.getenv("ASR_WEB_ALLOW_ANON", "").strip().lower() in {
|
||||
"1", "true", "yes", "on",
|
||||
}
|
||||
|
||||
|
||||
def password() -> str:
|
||||
env_pw = os.getenv("ASR_WEB_PASSWORD")
|
||||
if env_pw not in (None, ""):
|
||||
return env_pw
|
||||
return get_setting("web_password", "")
|
||||
|
||||
|
||||
def _secret() -> bytes:
|
||||
return (password() or os.getenv("ASR_AGENT_TOKEN", "") or "asr-web-unset").encode("utf-8")
|
||||
|
||||
|
||||
def session_token() -> str:
|
||||
return hmac.new(_secret(), b"asr-web-session-v1", hashlib.sha256).hexdigest()
|
||||
|
||||
|
||||
def csrf_token() -> str:
|
||||
return hmac.new(_secret(), b"asr-web-csrf-v1", hashlib.sha256).hexdigest()
|
||||
|
||||
|
||||
def cookie_matches(header: str) -> bool:
|
||||
if not password():
|
||||
return False
|
||||
jar = cookies.SimpleCookie()
|
||||
try:
|
||||
jar.load(header or "")
|
||||
except Exception:
|
||||
return False
|
||||
morsel = jar.get("asr_session")
|
||||
return bool(morsel and hmac.compare_digest(morsel.value, session_token()))
|
||||
|
||||
|
||||
def csrf_matches(supplied: str) -> bool:
|
||||
if not supplied:
|
||||
return False
|
||||
return hmac.compare_digest(supplied, csrf_token())
|
||||
Reference in New Issue
Block a user