Skip to content

OAuth Authentication Decisions Not Logged #91

Open

Description

@andrewmusselman

Issue: FINDING-135 - OAuth Authentication Decisions Not Logged

Labels: bug, security, priority:medium, asvs-level:L1

ASVS Level(s): [L1]

Description:

Summary

The OAuth authentication callback handler (/auth endpoint) makes critical authentication decisions but does not log any of them. Both successful logins and failures (invalid/expired state, OAuth provider rejection) occur silently. OAuth is the primary web authentication mechanism, making this a significant gap. The code validates state tokens, calls OAuth providers, and creates sessions without any audit trail, preventing detection of state token brute-force, replay attacks, or compromised accounts.

Details

Affected locations:

  • src/asfquart/generics.py lines 83-109: OAuth callback without logging
  • src/asfquart/generics.py lines 52-115: Authentication flow without audit

The OAuth callback performs authentication but never logs success or failure, creating complete gap in audit trail for primary web authentication mechanism.

Recommended Remediation

Implement an after_request hook to capture OAuth authentication decisions. In atr/server.py, add @app.after_request handler that checks if request.path == '/auth' and logs oauth_login_success (status 200 with uid) or oauth_login_failure (status 403):

@app.after_request
async def log_oauth_decisions(response: quart.Response) -> quart.Response:
    """Log OAuth authentication decisions for audit trail."""
    if quart.request.path == '/auth':
        if response.status_code == 200:
            # Successful login - extract uid from session
            session_data = await asfquart.session.read()
            log.info('oauth_login_success', extra={
                'asf_uid': session_data.get('uid'),
                'remote_addr': quart.request.remote_addr
            })
        elif response.status_code in (403, 401):
            # Failed login
            log.warning('oauth_login_failure', extra={
                'state_token': quart.request.args.get('state', '')[:8] + '...',  # Truncated
                'remote_addr': quart.request.remote_addr,
                'status': response.status_code
            })
    return response

Include asf_uid for success cases and failure reason for rejection cases.

Acceptance Criteria

  • OAuth authentication success is logged
  • OAuth authentication failure is logged
  • Log entries include user identity and remote address
  • Audit trail is complete for OAuth flow
  • Test cases verify OAuth logging
  • Unit test verifying the fix

References

  • Source reports: L1:7.2.2.md
  • Related findings: FINDING-134, FINDING-136, FINDING-250
  • ASVS sections: 7.2.2

Priority

Medium

Activity

  1. dave2wave commented on Apr 24, 2026

    @dave2wave
    Member

    This should be the responsibility of the application code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

ASVSASVS LLM driven auditdocumentationImprovements or additions to documentation

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions