Skip to content

Guidepoint: Enhancement - Improve PIN validation with PBKDF2#2039

Merged
JohnathanWhite merged 1 commit intobitpay:masterfrom
cmgustavo:feat/18-pin-policy-01
Mar 4, 2026
Merged

Guidepoint: Enhancement - Improve PIN validation with PBKDF2#2039
JohnathanWhite merged 1 commit intobitpay:masterfrom
cmgustavo:feat/18-pin-policy-01

Conversation

@cmgustavo
Copy link
Copy Markdown
Member

@cmgustavo cmgustavo commented Feb 11, 2026

GP-18

  • Add validation to reject weak PINs (sequential, repeating)
  • Migrate from simple SHA-256 to salted PBKDF2
  • Benefits: protects against rainbow table attacks, unique hash per user
  • Optimized for mobile: 1k iterations for instant verification

@cmgustavo cmgustavo changed the title [Feat GP-18] improve PIN validation with PBKDF2 Guidepoint: Enhancement - Improve PIN validation with PBKDF2 Feb 12, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR strengthens the app’s PIN handling by introducing weak-PIN validation and migrating PIN hashing from legacy SHA-256 to salted PBKDF2, with support for automatic migration on successful unlock.

Changes:

  • Added src/utils/pin.ts with PIN strength checks, PBKDF2 hashing, and legacy-to-PBKDF2 verification/migration logic.
  • Updated PinModal to verify via verifyAndMigratePin, migrate legacy hashes on success, and surface validation errors when setting a PIN.
  • Extended the APP redux state to persist a currentSalt alongside currentPin, and cleared it when removing a PIN.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/utils/pin.ts New PIN validation + PBKDF2 hashing + verification/migration utilities.
src/store/wallet/effects/import/import.ts Uses legacy SHA-256 PIN hashing during config migration.
src/store/app/app.types.ts Adds CURRENT_SALT action type and action union wiring.
src/store/app/app.reducer.ts Adds currentSalt to persisted APP state and reducer handling.
src/store/app/app.actions.ts Adds currentSalt(...) action creator.
src/navigation/tabs/settings/security/screens/SecurityHome.tsx Clears currentSalt when removing PIN lock.
src/components/modal/pin/PinModal.tsx Switches PIN check/set flows to PBKDF2 utilities and stores salt.
Comments suppressed due to low confidence (1)

src/components/modal/pin/PinModal.tsx:247

  • handleCellPress reads pinBannedUntil but it’s not included in the useCallback dependency array. That can leave the callback using a stale pinBannedUntil value, potentially allowing input during a ban (or blocking after a ban clears). Add the missing dependencies (at least pinBannedUntil, and any other referenced values not guaranteed stable).
    const handleCellPress = useCallback(
      (value: string) => {
        if (pinBannedUntil) {
          // banned wait for entering new pin
          return;
        }
        setMessageError(null);
        haptic('soft');
        switch (value) {
          case 'reset':
            reset();
            break;
          case 'backspace':
            setPinStatus(prevValue => {
              const newPin = prevValue.pin.slice();
              newPin.splice(-1);
              return {...prevValue, pin: newPin};
            });
            break;
          default:
            // Adding new PIN
            setPinStatus(prevValue => {
              if (
                Number(value) >= PIN_CONFIG.PIN_MIN_VALUE &&
                Number(value) <= PIN_CONFIG.PIN_MAX_VALUE &&
                prevValue.pin.length < PIN_CONFIG.PIN_LENGTH
              ) {
                const newPin = prevValue.pin.slice();
                newPin[newPin.length] = value;
                return {...prevValue, pin: newPin};
              } else {
                return prevValue;
              }
            });
            break;
        }
      },
      [setPinStatus, reset, pinStatus],
    );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/pin.ts
Comment thread src/utils/pin.ts Outdated
Comment thread src/components/modal/pin/PinModal.tsx
Comment thread src/store/app/app.reducer.ts
Comment thread src/utils/pin.ts
Comment thread src/utils/pin.ts Outdated
Comment thread src/utils/pin.ts Outdated
Comment thread src/utils/pin.ts Outdated
Comment thread src/utils/pin.ts Outdated
@cmgustavo cmgustavo force-pushed the feat/18-pin-policy-01 branch 2 times, most recently from 17a5d38 to dbd6bf1 Compare February 17, 2026 20:12
@cmgustavo cmgustavo force-pushed the feat/18-pin-policy-01 branch from dbd6bf1 to 18ba9e7 Compare February 23, 2026 12:50
Comment thread src/components/modal/pin/PinModal.tsx
Comment thread src/utils/pin.ts Outdated
@gabrielbazan7
Copy link
Copy Markdown
Collaborator

gabrielbazan7 commented Feb 27, 2026

Works as expected. Migration successfully tested on both Android and iOS simulator.

@cmgustavo cmgustavo force-pushed the feat/18-pin-policy-01 branch 2 times, most recently from 94437f8 to 729ce89 Compare March 2, 2026 19:35
@cmgustavo cmgustavo force-pushed the feat/18-pin-policy-01 branch from 729ce89 to 75abeb4 Compare March 2, 2026 20:10
@JohnathanWhite JohnathanWhite merged commit fcefe2d into bitpay:master Mar 4, 2026
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.

4 participants