Skip to content

Conversation

@lingcoder
Copy link

@lingcoder lingcoder commented Nov 21, 2025

fix(web3): normalize Ethereum addresses to lowercase to prevent case-sensitivity issues #2264

What kind of change does this PR introduce?

Bug fix - Resolves case-sensitivity issues with Ethereum addresses in SIWE (Sign-In with Ethereum) implementation.

What is the current behavior?

Ethereum addresses are stored with their original case (EIP-55 checksum format uses mixed case). This causes lookup failures when users sign in with a different case representation of the same address, as provider_id matching is case-sensitive.

What is the new behavior?

Ethereum addresses are now normalized to lowercase at parse time in parser.go. This ensures consistent storage and lookup regardless of the case used during sign-in.

Changes:

  • internal/utilities/siwe/parser.go - Normalize address to lowercase
  • internal/utilities/siwe/parser_test.go - Update test expectations

Migration Notes

This fix applies to new signups only. Existing users with checksummed Ethereum addresses in provider_id may need manual migration.

For existing deployments with web3 users:

-- Check affected rows first
SELECT COUNT(*) FROM auth.identities 
WHERE provider = 'web3' 
  AND provider_id LIKE 'web3:ethereum:0x%'
  AND provider_id != LOWER(provider_id);

-- Normalize addresses to lowercase
UPDATE auth.identities
SET provider_id = LOWER(provider_id)
WHERE provider = 'web3'
  AND provider_id LIKE 'web3:ethereum:0x%';

Note: For large tables, consider running in batches to avoid long locks.

Additional context

  • Ethereum addresses are case-insensitive by design (EIP-55 uses mixed case only for checksum verification)
  • The bulk migration was intentionally omitted per reviewer feedback to avoid performance issues on large auth.identities tables

@lingcoder lingcoder requested a review from a team as a code owner November 21, 2025 07:58
@cemalkilic
Copy link
Contributor

Thanks for spotting the issue & contributing the fix @lingcoder !

Can you please also update the test?

require.Equal(t, "0x196a28d05bA75C8dC35B0F6e71DD622D1aC82b7E", parsed.Address)

@cemalkilic
Copy link
Contributor

Hello! I reviewed this PR again and a quick note on the migration.

auth.identities can be massive on some projects, and the backfill UPDATE worries me (long run time, locks). We do have an index from UNIQUE (provider_id, provider), but since provider isn’t indexed on its own, WHERE provider = 'web3' can still end up doing a big scan.

What about skipping the bulk backfill and whoever needs backfilling can run manual queries?

@lingcoder
Copy link
Author

Thanks for the feedback @cemalkilic! I've removed the bulk backfill migration as suggested. The code change will handle new signups automatically, and I've added migration notes in the PR description for existing deployments that may need to run manual queries.

Remove the bulk UPDATE migration for normalizing Ethereum addresses as
suggested by @cemalkilic. The auth.identities table can be massive on
some projects, and the backfill UPDATE could cause long run times and
locks.

The code change in parser.go will handle new signups automatically.
Existing deployments with web3 users can run manual migration queries
if needed (see PR description for migration notes).
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.

2 participants