Skip to content

Incomplete Session Invalidation - Client-Side Logout Bypasses Server-Side Token Revocation #152

@360AlphaLab

Description

@360AlphaLab

Summary

The frontend logout implementation in the admin panel suffers from incomplete session invalidation. When an administrator clicks logout in the UI, the frontend only clears the token from localStorage and redirects, without calling the server-side /api/admin/logout API. This leaves tokens permanently valid in the server's active_admin_tokens set, allowing attackers who obtain a leaked token to maintain indefinite admin session hijacking even after the administrator believes they have logged out.

Details

Affected Endpoints and Files

  • Frontend logout logic: static/manage.html, around line 916
  • Server-side logout endpoint: src/api/admin.py, line 36 (active_admin_tokens management)
  • Server-side token validation: src/api/admin.py, lines 563–571

Root Cause
The frontend logout function currently only performs:

logout=()=>{
    localStorage.removeItem('adminToken');
    window.location.href='/login.html'
}

It makes no call to the server-side /api/admin/logout API. The server has correctly implemented token destruction logic that removes the token from the active_admin_tokens set, but since the frontend never invokes it, the server-side token reference persists indefinitely until natural expiration or service restart.

Verification
The PoC sent a login request to http://<server>:38000/api/admin/login using default admin credentials and successfully obtained a token. It then accessed a protected endpoint /api/captcha/config with the token, receiving HTTP 200. After simulating frontend logout (no server-side API call), the same token was used again to access the protected endpoint and still returned HTTP 200, confirming the token remains valid. Full output:

[*] Step 1: Sending login request to http://<server>:38000/api/admin/login
[*] Login response status: 200
[+] Successfully obtained token: admin-Uurv...
[*] Step 2: Accessing protected endpoint http://<server>:38000/api/captcha/config
[*] Protected endpoint response status: 200
[*] Step 3: Simulating frontend logout (no server-side API call made)
[*] Re-accessing protected endpoint http://<server>:38000/api/captcha/config with the same token
[*] Protected endpoint response status after simulated frontend logout: 200
[+] Vulnerability verified: Token remains valid because the server-side logout was not invoked by the client-side flow.

Suggested Fix
Modify the frontend logout function to call the server-side logout API before clearing the local token:

logout=async ()=>{
    try {
        await apiRequest('/api/admin/logout', { method: 'POST' });
    } catch (e) {
        console.error('Server-side logout failed:', e);
    }
    localStorage.removeItem('adminToken');
    window.location.href='/login.html'
}

Impact

  • Admin Session Hijacking: An attacker who obtains an unexpired admin token—through XSS, man-in-the-middle attacks, log leakage, or physical access—can maintain full administrative access long after the administrator has "logged out."
  • Complete System Control: Admin tokens grant access to all management interfaces, including model management, user management, and system configuration modification, potentially leading to data breaches, service tampering, or malicious model deployment.
  • Audit Failure: The server cannot distinguish between legitimate administrators and attackers using leaked tokens, rendering security audit logs ineffective for tracing malicious actions.
  • Long-lived Credentials: If tokens lack a short expiration time, stolen tokens may remain valid for days or weeks, significantly extending the attack window.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions