[auth] need a login interception point for authentication-related plugins #2118

Closed
opened 2026-10-05 01:06:51 +02:00 by adam · 1 comment
Owner

The current pwg_login() workflow always calls log_user() immediately after a successful username/password verification.

This makes it impossible for authentication-related plugins (2FA, rate limiter, IP allow/deny lists, geolocation checks, etc.) to properly intercept or control the login flow.

Today, a plugin must let log_user() happen, then manually block the session and redirect the user (e.g. to a 2FA verification page).
This approach is fragile, creates edge cases, and is not ideal from a security perspective because the session is technically "already logged in" before the plugin can perform its checks.

Proposal:
Introduce a small extension point inside pwg_login(), for example a finalize_login hook, that allows plugins to:

  • decide whether the login can proceed
  • block the login temporarily (e.g. while waiting for a second factor)
  • optionally perform their own log_user() once their checks are completed

The core still handles password verification normally.
Plugins simply get the ability to approve or deny the final authentication step.

The current `pwg_login()` workflow always calls `log_user()` immediately after a successful username/password verification. This makes it impossible for authentication-related plugins (2FA, rate limiter, IP allow/deny lists, geolocation checks, etc.) to properly intercept or control the login flow. Today, a plugin must let `log_user()` happen, then manually block the session and redirect the user (e.g. to a 2FA verification page). This approach is fragile, creates edge cases, and is not ideal from a security perspective because the session is technically "already logged in" before the plugin can perform its checks. Proposal: Introduce a small extension point inside `pwg_login()`, for example a finalize_login hook, that allows plugins to: - decide whether the login can proceed - block the login temporarily (e.g. while waiting for a second factor) - optionally perform their own `log_user()` once their checks are completed The core still handles password verification normally. Plugins simply get the ability to approve or deny the final authentication step. <!-- github-sync-id:3621116655 -->
adam closed this issue 2026-10-05 01:06:52 +02:00
Author
Owner

In addition, the current login workflow makes user enumeration possible through timing differences:

  • when the username exists, password_verify is executed → slower
  • when the username does not exist, the function returns much faster

A simple mitigation is to introduce a fake user with a valid hashed password and always run the password verification step, regardless of whether the user exists.
This keeps authentication time consistent and prevents timing-based user enumeration attempts.

In addition, the current login workflow makes user enumeration possible through timing differences: - when the username exists, `password_verify` is executed → slower - when the username does not exist, the function returns much faster A simple mitigation is to introduce a _**fake user**_ with a valid hashed password and always run the password verification step, regardless of whether the user exists. This keeps authentication time consistent and prevents timing-based user enumeration attempts. <!-- github-comment-id:3527702966 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Piwigo#2118