Skip to content

caddyauth: set user placeholders before auth rejection#7685

Merged
steadytao merged 2 commits intocaddyserver:masterfrom
cyphercodes:fix/auth-placeholders-unauthorized
May 3, 2026
Merged

caddyauth: set user placeholders before auth rejection#7685
steadytao merged 2 commits intocaddyserver:masterfrom
cyphercodes:fix/auth-placeholders-unauthorized

Conversation

@cyphercodes
Copy link
Copy Markdown
Contributor

Summary

  • make the authentication handler publish http.auth.user.* placeholders as soon as a provider returns user information, even when the request is rejected as unauthenticated
  • keep skipping user placeholders for provider errors and add regression coverage for unauthorized requests that still carry user metadata

Fixes #7684

Testing

  • go test ./modules/caddyhttp/caddyauth -run TestAuthenticationSetsUserPlaceholdersOnUnauthorized -count=1
  • go test ./modules/caddyhttp/caddyauth -count=1
  • go test -race ./modules/caddyhttp/caddyauth -count=1
  • go test ./modules/caddyhttp/caddyauth ./modules/caddyhttp -count=1
  • git diff --check

Assistance Disclosure

AI assistance used: Hermes Agent (OpenAI GPT-5.5 via Nous Research) helped draft and verify this focused change. I reviewed the diff and test output for correctness.

@steadytao
Copy link
Copy Markdown
Member

I pushed a tiny follow-up to keep the package comment aligned with the new behaviour. Once CI is green this is good to merge.

Copy link
Copy Markdown
Member

@steadytao steadytao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyphercodes Thank you.

LGTM. I confirmed the patch covers the bug, only touches the caddyauth change and includes regression coverage for the unauthorised placeholder case.

@steadytao
Copy link
Copy Markdown
Member

Lint failure is not caused by this PR;

  • caused by an action update to v2.12.1 of golangci-lint.

Will be handled separately.

@steadytao steadytao added the bug 🐞 Something isn't working label May 3, 2026
@steadytao steadytao added this to the v2.11.3 milestone May 3, 2026
@steadytao steadytao merged commit 7e77eec into caddyserver:master May 3, 2026
26 of 29 checks passed
@steffenbusch
Copy link
Copy Markdown
Contributor

Let’s hope this does not introduce unintended side effects.

Exposing http.auth.user.* placeholders before authentication has actually succeeded changes their semantics quite significantly. Until now, these placeholders implicitly represented an authenticated principal. With this change, they may represent a merely resolved or identified principal, even if authentication is rejected.

This creates a few concerns:

  1. Side-channel leakage / user enumeration
    If error handlers, templates, logs, or upstream headers consume these placeholders on authentication failure, they may unintentionally expose whether a user exists or which metadata could be resolved. Depending on configuration, this could create user-enumeration vectors or other information disclosure side channels.

  2. Trust boundary ambiguity
    Downstream handlers or upstream services may implicitly treat http.auth.user.* as verified identity, because that has been the effective contract so far. Changing this behaviour risks breaking that assumption and could lead to incorrect trust decisions.

Would it make sense to keep http.auth.user.* strictly for successfully authenticated principals and introduce a separate placeholder namespace for pre-auth resolved identities (for example http.auth.candidate.* or similar)? That would preserve the existing security semantics while still making unresolved identity metadata available where needed.

@steadytao
Copy link
Copy Markdown
Member

I agree with your concerns.

I was already thinking of a part of your concerns but thank you for helping expand my thoughts. I still think the merge was reasonable for the reported issue because it fixed the unauthorised error-handler use case and the normal handler chain is still not reached when authentication fails. That said, I agree the boundaries are worth tightening before release.

http.auth.user.* has effectively meant authenticated principal and using it for provider-returned-but-rejected identity data can make that boundary a bit less clear especially so for third-party auth providers.

I think the clean follow-up may indeed be to preserve http.auth.user.* for successfully authenticated users and introduce a separate namespace for rejected-but-identified principals rather than relying on http.auth.user.* for both cases.

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

Labels

bug 🐞 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set http.auth.user variables even on unsuccessful authentication

3 participants