Skip to content

fix: use timing-safe comparison for OTP verification (WAPI-1128)#74

Merged
chakra-guy merged 1 commit intomainfrom
cyfrin/wapi-1128
Feb 27, 2026
Merged

fix: use timing-safe comparison for OTP verification (WAPI-1128)#74
chakra-guy merged 1 commit intomainfrom
cyfrin/wapi-1128

Conversation

@chakra-guy
Copy link
Collaborator

@chakra-guy chakra-guy commented Feb 25, 2026

Summary

  • Adds a cross-platform timingSafeEqual() utility to @metamask/mobile-wallet-protocol-core
  • Replaces direct === OTP comparison in the dapp-client's untrusted connection handler with constant-time comparison

Background

The Cyfrin audit identified that the OTP comparison in the dApp's untrusted connection handler uses direct string equality (===), which is vulnerable to timing side-channel attacks. An attacker could theoretically measure response time differences to infer which characters of the OTP are correct.

The fix uses a constant-time XOR-based comparison that always processes every character, preventing timing leakage. The implementation is cross-platform (no Node-specific crypto.timingSafeEqual dependency) and works in Node, browsers, and React Native.

Changes

  • packages/core/src/utils/timing-safe-equal.ts: New utility
  • packages/core/src/utils/timing-safe-equal.test.ts: 6 unit tests
  • packages/core/src/index.ts: Export timingSafeEqual
  • packages/dapp-client/src/handlers/untrusted-connection-handler.ts: Use timingSafeEqual for OTP comparison
  • packages/dapp-client/CHANGELOG.md: Document the fix

Test plan

  • yarn build passes
  • yarn test:unit passes (68/68 tests, including 6 new)

Note

Medium Risk
Changes OTP verification logic in the untrusted handshake path; while behavior should be equivalent for correct/incorrect OTPs, any mismatch in edge cases (e.g., non-string inputs or length handling) could affect connection UX/security.

Overview
Mitigates OTP timing side-channel risk by introducing a cross-platform timingSafeEqual() utility in @metamask/mobile-wallet-protocol-core (with new unit tests) and exporting it from packages/core/src/index.ts.

Updates the dapp-client untrusted connection flow to use timingSafeEqual instead of direct string equality for OTP verification, and documents the fix in the dapp-client changelog.

Written by Cursor Bugbot for commit b458794. This will update automatically on new commits. Configure here.

adonesky1
adonesky1 previously approved these changes Feb 25, 2026
Copy link

@adonesky1 adonesky1 left a comment

Choose a reason for hiding this comment

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

LGTM

@chakra-guy chakra-guy force-pushed the cyfrin/wapi-1127 branch 3 times, most recently from b13cab4 to 3c1336b Compare February 27, 2026 10:47
Base automatically changed from cyfrin/wapi-1127 to main February 27, 2026 10:50
@chakra-guy chakra-guy dismissed adonesky1’s stale review February 27, 2026 10:50

The base branch was changed.

The direct string comparison (===) for OTP verification is vulnerable
to timing side-channel attacks. Replace with a constant-time XOR-based
comparison that processes every character regardless of where a mismatch
occurs. The utility is cross-platform (no Node-specific crypto dependency).
@chakra-guy chakra-guy merged commit 7bbacf3 into main Feb 27, 2026
12 checks passed
@chakra-guy chakra-guy deleted the cyfrin/wapi-1128 branch February 27, 2026 11:26
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