Skip to content

Hash 40-hex usernames in the direct provider instead of passing them through - #324

Merged
umputun merged 2 commits into
masterfrom
direct-hex-userid
Nov 4, 2026
Merged

umputun merged 2 commits into
masterfrom
direct-hex-userid

Conversation

@umputun

@umputun umputun commented Nov 4, 2026

Copy link
Copy Markdown
Member

The direct provider built the user id with token.HashID, which returns any 40-char hex value unchanged. A username equal to the SHA1 of another username got that user's id: 522b276a356bdf39013dfabea2cd43e141ecc9e8 logged in as direct_522b276a..., the same id alice gets. An app that keys records or permissions on User.ID treats the two logins as one account. Exploiting it needs a username policy that accepts 40-char hex names and a known victim username.

The default id is now the plain SHA1 of the username, in both the root and v2 modules. For every other username the id is the same as before.

Behavior change: with the default ID mapping, usernames consisting of exactly 40 hexadecimal characters now receive new IDs; applications may need to migrate associated records. Custom UserIDFunc behavior is unchanged: its result still goes through HashID, and its godoc now says a 40-char hex result is used as-is, so it must be an app-controlled id, never the raw username.

token.HashID itself is unchanged. The verify provider builds its id from the address the same way. It is exploitable only with a sender that accepts 40-hex addresses, since an email address always has an @, so it goes to docs/backlog instead of this PR.

Reported privately by Rathnadeepan (@HotWater-015).

…them through

token.HashID returns a 40-char hex value unchanged, so a direct-provider
username equal to the SHA1 of another username got that user's id. The
default id is now the plain SHA1 of the username in both modules. Every
other username keeps its id; usernames made of exactly 40 hex characters
get new ones. UserIDFunc results still go through HashID, and its godoc
says a 40-char hex result is used as-is.
Copilot AI balanced review requested due to automatic review settings November 4, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@coveralls

coveralls commented Nov 4, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 41923348794

Coverage increased (+0.04%) to 86.917%

Details

  • Coverage increased (+0.04%) from the base build.
  • Patch coverage: 1 of 1 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 3883
Covered Lines: 3375
Line Coverage: 86.92%
Coverage Strength: 10.07 hits per line

💛 - Coveralls

@umputun
umputun merged commit c823129 into master Nov 4, 2026
9 checks passed
@umputun
umputun deleted the direct-hex-userid branch November 4, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants