Skip to content

[Bug]: OIDC login events log the reverse-proxy IP instead of the real client IP (logout logs it correctly) #465

Description

@djanzin

Bug Description

Auth: OIDC enabled, external IdP (Authentik)
Reverse proxy: Caddy, sets X-Forwarded-For and X-Real-IP to the real client IP
App reached only via the proxy (ASPNETCORE_URLS=http://+:5000)
Summary
In the activity log, OIDC login events record the reverse proxy's internal IP (e.g. ::ffff:10.0.0.2), while logout events and failed-login events record the correct real client IP. So the client IP is captured inconsistently depending on the code path.

Evidence (activity log, IPs anonymized)
timestamp user type information
21:34 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:33 Logout IP: <- correct
21:33 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:24 Logout IP: <- correct
Failed local logins also log the correct real client IP.

Analysis
The application already uses UseForwardedHeaders and clearly trusts the proxy (KnownProxies/KnownNetworks), because logout and failed-login events resolve to the real client IP. If the proxy were not trusted, every event would show the proxy IP, which is not the case.

The login path is the outlier. This strongly suggests a middleware ordering issue: the OIDC callback / authentication middleware captures and logs the client IP before UseForwardedHeaders has rewritten HttpContext.Connection.RemoteIpAddress. Regular requests (logout) pass through the full pipeline first, so they see the corrected IP.

Expected behavior
OIDC login events should log the real client IP, consistent with logout and failed-login events.

Suggested fix
Ensure app.UseForwardedHeaders(...) runs before the authentication middleware (and before any OIDC sign-in event logging) in the pipeline, so the corrected RemoteIpAddress is available when the login event is recorded.

Note: cause inferred from behavior plus a symbol scan of MailArchiver.dll, not from source, so the exact call site may differ.

Steps to Reproduce

Run Mail-Archiver behind a reverse proxy that sets X-Forwarded-For / X-Real-IP to the real client IP (here: Caddy), with the app only reachable through the proxy.
Enable OIDC with an external IdP and log in via the OIDC button.
Open the activity log and look at the Login entry: the IP shown is the reverse proxy's internal IP (::ffff:10.0.0.2), not the client's.
Log out, then look at the Logout entry: the IP shown is the real client IP.
Compare both entries for the same session, the IPs are inconsistent.

Application Version

2607.2

Installation Type

Standalone

Management Tools

No response

Host System

No response

Mail Provider

No response

Relevant Log Output

Evidence (activity log, IPs anonymized)
timestamp   user      type       information
21:34       <user>    Login      IP: ::ffff:10.0.0.2      <- reverse proxy IP
21:33       <user>    Logout     IP: <real client IP>     <- correct
21:33       <user>    Login      IP: ::ffff:10.0.0.2      <- reverse proxy IP
21:24       <user>    Logout     IP: <real client IP>     <- correct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions