mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2026-03-17 14:26:18 +00:00
refactor login flow to use context path for redirects and enhance path normalization to prevent traversal bypasses
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import posixpath
|
||||
from dataclasses import dataclass
|
||||
from urllib.parse import unquote, urlsplit
|
||||
|
||||
@@ -22,7 +23,9 @@ def normalize_host(raw_host: str) -> str:
|
||||
def normalize_path(raw_uri: str) -> str:
|
||||
parsed = urlsplit(raw_uri or "/")
|
||||
path = unquote(parsed.path or "/")
|
||||
return path if path.startswith("/") else f"/{path}"
|
||||
path = path if path.startswith("/") else f"/{path}"
|
||||
# Resolve any .. or . segments to prevent path traversal bypasses
|
||||
return posixpath.normpath(path)
|
||||
|
||||
|
||||
def _path_matches(path: str, prefix: str) -> bool:
|
||||
|
||||
@@ -152,9 +152,9 @@ async def login_password_submit(request: Request, next: str = Form("/"), usernam
|
||||
|
||||
if effective_policy.totp_method_names:
|
||||
logger.info("AUTH password ok for '%s' → totp required (policy: %s)", username, context.policy_name)
|
||||
return _redirect_with_cookie(request, build_external_url(request, "/login/totp", next=next), session)
|
||||
return _redirect_with_cookie(request, build_external_url(request, "/login/totp", next=context.path), session)
|
||||
logger.info("AUTH login ok for '%s' (policy: %s)", username, context.policy_name)
|
||||
return _redirect_with_cookie(request, next, session)
|
||||
return _redirect_with_cookie(request, context.path, session)
|
||||
|
||||
|
||||
@router.get("/login/totp", response_class=HTMLResponse)
|
||||
@@ -205,7 +205,7 @@ async def login_totp_submit(request: Request, next: str = Form("/"), token: str
|
||||
expires_in_minutes=get_effective_expiration(request, effective_policy, ["totp"]),
|
||||
)
|
||||
logger.info("AUTH login ok for '%s' via password+totp (policy: %s)", refreshed_session.username, context.policy_name)
|
||||
return _redirect_with_cookie(request, next, refreshed_session)
|
||||
return _redirect_with_cookie(request, context.path, refreshed_session)
|
||||
|
||||
|
||||
@router.get("/login/oidc/start")
|
||||
@@ -218,7 +218,7 @@ async def login_oidc_start(request: Request, next: str = "/"):
|
||||
if not method_name or not method:
|
||||
return _render(request, "error.html", status_code=400, title="OIDC unavailable", message="The selected policy does not require OIDC.")
|
||||
|
||||
session_state = request.app.state.session_service.create_oidc_state(method_name, normalize_host(request.headers.get("host", "")), next)
|
||||
session_state = request.app.state.session_service.create_oidc_state(method_name, normalize_host(request.headers.get("host", "")), context.path)
|
||||
redirect_uri = build_external_url(request, "/login/oidc/callback")
|
||||
return await request.app.state.oidc_service.build_authorization_redirect(
|
||||
request,
|
||||
|
||||
Reference in New Issue
Block a user