In most banks the mobile app is now the customer's strongest authenticator and their most valuable target, because whoever controls an enrolled app can approve payments, raise limits and push cards into a phone wallet. Generic mobile application security covers storage, networking and code hardening; this guide covers the identity decisions specific to a banking app: how a device becomes bound to a customer, how the app approves payments with dynamic linking, how in-app wallet provisioning is protected, and how device trust signals feed a fraud decision. It is written for bank and fintech security architects, fraud teams and mobile engineering leads. For the AppSec baseline see the Mobile App Security Guide, and for malware-driven fraud the Android Banking Trojans Guide.
Key takeaways
- Enrolment is the real perimeter. Hardware-bound keys make an enrolled device hard to clone, so attackers aim to enrol a new device instead; treat new-device binding as a high-risk event with its own step-up.
- An installed app is not a possession factor on its own. The EBA Opinion EBA-Op-2019-06 says an app only evidences possession when there is a device-binding process that ensures a unique connection with the device.
- Sign what the customer sees. Under the PSD2 RTS, the authentication code must be specific to the amount and payee, and any change must invalidate it; build the in-app approval as a signature over that data.
- Wallet provisioning is a payment credential issuance. Pushing a card into a phone wallet from the app should demand the same assurance as a high-value payment, plus customer notification.
- Device signals inform, the server decides. Attestation, binding age, SIM change and malware indicators feed a server-side risk decision, never a client-side allow or block.
What a banking app has to prove
A banking session combines several identities, each with its own failure mode. Keeping them separate in the design makes it clear which control answers which question.
| Question | Evidence | Typical attack | Primary control |
|---|---|---|---|
| Is this the customer? | Knowledge (PIN, passcode) or inherence (biometric) checked against a device-held key | Social engineering, shoulder surfing, coerced approval | Local user verification gating a hardware key; behavioural signals |
| Is this the customer's enrolled device? | Signature from a non-exportable key created at enrolment | Enrolling an attacker device after phishing credentials or a SIM swap | Device binding with strong step-up at enrolment |
| Is this our genuine, unmodified app? | Platform attestation (Apple App Attest, Google Play Integrity) | Repackaged or instrumented apps, emulators, bots | Server-verified attestation; see the Mobile App Attestation Guide |
| Is the device environment trustworthy now? | Integrity verdicts, malware indicators, accessibility and overlay signals | Banking trojans using accessibility services and overlays (ATT&CK for Mobile T1516 Input Injection, T1417 Input Capture) | Risk engine, sensitive screen protections |
| Did the customer approve this exact payment? | Signature over amount and payee shown on screen | Manipulated payment details, authorised push payment scams | Dynamic linking and payee confirmation |
Device binding and enrolment
Device binding creates a key pair inside the device's secure hardware, registers the public key with the bank against the customer, and from then on proves the device by signing server challenges with the private key. Because the key cannot be exported, copying app data to another phone does not copy the binding. Article 7 of Commission Delegated Regulation (EU) 2018/389 (the PSD2 RTS on strong customer authentication) requires measures designed to prevent replication of possession elements, and device-bound keys are the usual answer.
Building the binding
- Android: generate the key in the Android Keystore with an attestation challenge from your server, and request StrongBox where the device has it. Verify the attestation certificate chain on the server, never on the device: Google's key attestation documentation warns that a compromised Android system could vouch for itself, requires checking the chain to a Google root and the revocation list at
android.googleapis.com/attestation/status, and says only the first attestation extension in the chain is trustworthy. Note that Google lists a new attestation root that began signing chains on 1 February 2026; include it as a trust anchor. - Security level: accept
attestationSecurityLevelvalues of TrustedEnvironment or StrongBox as hardware-backed; record the value so the risk engine can treat software-only keys differently. - iOS: create the key in the Secure Enclave and protect it with an access control that requires user presence; pair it with App Attest so the backend knows the key was created by your genuine app.
- User verification: require biometric or device passcode for every signing operation on payment keys, and set the key to be invalidated when biometric enrolment changes (on Android,
setInvalidatedByBiometricEnrollment; on iOS, thebiometryCurrentSetaccess control). A newly added fingerprint or face should force re-binding, not silently approve payments.
Enrolment and re-binding
Every account takeover path that defeats a well-built binding goes through enrolling a new device. The NHI Mgmt Group recommendation is to treat enrolment as a privileged operation with its own controls:
- Do not rely on SMS alone: the EBA notes that with SMS OTP the possession element is the SIM card, not the message, so a SIM swap transfers it. Combine with a second factor the attacker is unlikely to hold, such as an existing bound device approving the new one, a card and PIN check, or identity verification with liveness. See the SIM Swap Fraud Guide.
- Cooling-off period: on a new binding, restrict high-risk actions (new payees, limit increases, wallet provisioning) for a defined period, and say so in the app.
- Notify on every other channel: alert the customer through email, existing bound devices and previously registered contact details when a device is added, with a one-tap "this was not me" that freezes the new binding.
- Cap bound devices: limit the number of active bindings per customer and show them in the app with last-used dates so customers can remove old phones.
- Re-bind on reinstall: app reinstall, OS restore or a key invalidation event should lead to fresh enrolment, not a quiet recovery of the old identity.
In-app step-up and transaction signing
Article 5 of the RTS sets the dynamic linking rule for remote electronic payments: the payer is made aware of the amount and payee, the authentication code is specific to that amount and payee, the provider accepts only a code that matches the original amount and payee, and any change invalidates the code. Article 9 adds that where a multi-purpose device such as a phone is used, providers must mitigate the risk of that device being compromised, including separated secure execution environments and mechanisms to check that software or the device has not been altered.
- Server builds the approval request: amount, currency, payee name and account identifier, a transaction identifier and a fresh nonce.
- App displays exactly those values on a protected screen (overlay and screenshot protections as described in MASVS-PLATFORM), with the payee name returned by confirmation of payee where available.
- Customer verifies locally: biometric or passcode unlocks the device-bound signing key.
- App signs a canonical encoding of the displayed fields and the nonce.
- Server verifies the signature with the bound public key, checks the nonce is unused and that the signed amount and payee match the payment to be executed, then executes.
Two design points matter most. First, sign structured fields, not a display string the server cannot recompute. Second, keep the approval inside the app rather than an SMS link, which removes the one-time code that trojans read from notifications. Where the payment was started in a browser, the app approval should repeat the payee and amount in full; it is the customer's last chance to spot an authorised push payment scam. See the PSD2/PSD3 Strong Customer Authentication Guide and the Authorised Push Payment (APP) Fraud Guide.
What should trigger step-up
| Action | Suggested assurance (ours) | Extra controls |
|---|---|---|
| View balances and statements | Bound device plus local unlock | Session timeout, screenshot protection on sensitive screens |
| Payment to an existing payee within normal pattern | Signed approval with biometric or passcode | Transaction monitoring per RTS Article 2 |
| New payee or first payment to a payee | Signed approval, payee confirmation result shown | Scam warnings tuned to the payment purpose, delay for high-risk patterns |
| Limit increase, contact detail change, password reset | Signed approval plus a second check (card and PIN, or call-back) | Notification to all channels, cooling-off |
| New device binding | Strongest available step-up, never SMS alone | Cooling-off, notification, binding cap |
| Wallet push provisioning | Signed approval on a binding older than the cooling-off period | Notification, token monitoring |
Protecting in-app wallet provisioning
Issuer apps can add a customer's card to a phone wallet without the customer typing the card number: Apple documents this through PassKit's PKAddPaymentPassViewController, and Google offers a push provisioning API for Android to approved issuers. The resulting device token is an EMV payment token, which EMVCo describes as constrained in how it can be used, for example to a specific device. Because a provisioned token can be spent in shops immediately, attackers who take over an app often go straight to this feature. The issuer-side controls are the same whichever wallet is used:
- Treat the app as a transport: generate the encrypted provisioning payload on the issuer backend, only after the server has verified a fresh signed approval from a bound device. Follow each wallet's current issuer documentation for payload format; Google's is available to approved issuers only.
- Apply binding age and risk: block or defer provisioning from a binding inside its cooling-off period or with a weak integrity verdict.
- Tell the customer: notify on every provisioning event, naming the wallet and device, through a channel other than the app.
- Watch the token lifecycle: monitor the number of active tokens per card, provisioning velocity across customers, and tokens added shortly before unusual spending; suspend tokens through your token service provider when a binding is revoked.
See the Network Tokenisation for Payments Guide for how tokens, cryptograms and domain restrictions work.
Device trust signals and the risk decision
RTS Article 2 requires transaction monitoring that considers, at minimum, lists of compromised authentication elements, the amount, known fraud scenarios, signs of malware infection in the authentication session, and abnormal use logs where the provider supplies the software. In an app, that translates into signals sent with each sensitive request:
- Binding facts: binding age, key security level, number of bindings, recent re-binding.
- Integrity: App Attest or Play Integrity verdicts verified server-side, bound to the request with a nonce or request hash. Google recommends measuring before enforcing; see the Mobile App Attestation Guide.
- Malware indicators: enabled accessibility services, screen sharing or remote access during a payment, overlay detection.
- Telecom signals: recent SIM change where your market offers it; see the Mobile Network Identity APIs Guide.
- Behaviour: payee novelty, amount against history, time since login, typing and navigation patterns.
Use tiered outcomes (allow, allow with lower limits, step up, hold for review, decline) and keep thresholds in server-side configuration so they can be tuned or rolled back without an app release.
Implementing it: a phased approach
- Baseline (month 1): map every sensitive action in the app to the assurance table above, and list where SMS OTP is still used. Log binding events, integrity verdicts and approvals centrally.
- Binding (months 1 to 3): introduce hardware-bound keys with server-side attestation verification for new enrolments in a pilot ring, then migrate existing customers at next login. Keep the legacy path behind a server flag as rollback.
- Signing (months 2 to 4): move payment approval to signed dynamic linking, starting with new payees and high values; measure abandonment and support calls.
- Enrolment controls (months 3 to 5): add enrolment step-up, cooling-off and multi-channel notifications; tune with fraud and customer service teams.
- Provisioning and risk (months 4 to 6): gate wallet provisioning on binding age and signed approval, then move integrity signals from measure to enforce for the riskiest actions.
Detection and measurement
- Events to log: device binding created, revoked and invalidated; enrolment step-up outcome; signed approvals with verification result; wallet provisioning requests and outcomes; integrity verdict per sensitive request; customer "not me" reports.
- Correlations to alert on: new binding followed within hours by new payee, limit change or wallet provisioning; many bindings created from one device fingerprint; SIM change followed by enrolment.
| Metric | Why it matters |
|---|---|
| Share of payments approved by signed in-app approval rather than SMS | Tracks removal of interceptable codes |
| Fraud losses where the first sign was a new device binding | Shows whether enrolment controls work |
| Share of bindings with hardware-backed attested keys | Coverage of the strongest possession evidence |
| Wallet tokens provisioned within the cooling-off window | Should be zero once gating is live |
| Step-up abandonment rate by action | Keeps friction where it earns its cost |
Framework mapping
| Control | PSD2 RTS (EU) 2018/389 | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | OWASP MASVS |
|---|---|---|---|---|
| Device binding with hardware keys | Article 7 | IA-3 Device Identification and Authentication | PR.AA-03 | MASVS-AUTH |
| Signed approval of amount and payee | Article 5 | IA-11 Re-authentication | PR.AA-03 | MASVS-AUTH |
| Integrity and tamper checks | Article 9 | SI-4 System Monitoring | DE.CM-09 | MASVS-RESILIENCE |
| Transaction and session risk monitoring | Article 2 | SI-4 System Monitoring | DE.AE-02 | MASVS-PLATFORM (sensitive screens) |
Common failure patterns
- Strong binding, weak enrolment: a hardware-bound key that any SMS code can re-create on another phone.
- Attestation checked on the device: a modified app or OS simply reports success; verification belongs on the server.
- Signing a session, not a transaction: a biometric unlock that authorises whatever the app sends next does not meet dynamic linking and lets malware change the payee.
- Biometric changes ignored: keys left valid after a new fingerprint or face is enrolled let anyone with the passcode add their own biometric.
- Wallet provisioning outside the risk engine: a takeover becomes card-present spending within minutes.
- Client-side blocking: hard-coded root or emulator checks in the app that block customers but are easily bypassed, instead of server-side tiered decisions.
Practitioner checklist
- Map each app action to a required assurance level and step-up method.
- Bind devices with non-exportable hardware keys and verify Android key attestation and App Attest on the server, with current roots and revocation checks.
- Require user verification for payment keys and invalidate them when biometric enrolment changes.
- Treat new-device enrolment as high risk: no SMS-only path, cooling-off, multi-channel notification, binding cap.
- Sign amount, payee and nonce for every payment approval and verify the match server-side.
- Gate wallet push provisioning on a signed approval from a mature binding and notify the customer.
- Feed binding, integrity, malware and SIM signals into a server-side risk engine with tiered outcomes.
- Alert on new binding followed by payee, limit or provisioning changes.
Standards and references
- EUR-Lex: Commission Delegated Regulation (EU) 2018/389, RTS on strong customer authentication and secure communication
- EBA: Opinion on the elements of strong customer authentication under PSD2 (EBA-Op-2019-06)
- Android Developers: Verify hardware-backed key pairs with key attestation
- Apple Developer: PKAddPaymentPassViewController
- Apple Developer: biometryCurrentSet
- EMVCo: EMV Payment Tokenisation
- OWASP: Mobile Application Security Verification Standard (MASVS)
Related NHI Mgmt Group resources: Mobile App Security Guide · Mobile App Attestation Guide · PSD2/PSD3 Strong Customer Authentication Guide · Android Banking Trojans Guide