Series · Hardening before AWS · Part 2 of 3 ← Part 1: Securing the application · Mobile banking app hardening · Part 3: Identity-first migration →
Companion to the AWS-for-banks architecture series and the DSI banking threat picture.
The mobile surface is the bank now
By 2026 the Nigerian Tier 1 banking customer interacts with the bank through a mobile app for over 70% of all transactions. The branch is residual; the internet-banking web channel is a long tail; the agent network is a complementary surface. The app is the bank. The app is also the most-targeted surface — by reverse engineers, SIM-swap rings, store-side repackagers, and the network of fraud operators that the sector has documented in the post-incident reports.
The AWS-for-banks architecture in Part 2 of the architecture series defends the backend the app talks to. The pre-migration application baseline in Part 1 of this series defends the build pipeline that produces the app. This piece documents what hardens the app itself — the artefact that lives on the customer's device, outside the bank's control perimeter, in an environment where root access, modified runtimes, repackaging, and adversarial networks are all operating assumptions.
The threat model specific to Nigerian mobile banking
Generic mobile-security guidance treats the device as a uniform threat surface. The Nigerian banking-app threat model is more specific. Six classes of adversary, ranked by frequency in the 2026 sector picture:
- Modified or repackaged apps distributed via third-party stores. A customer searches for the bank's app, lands on a parallel store, installs a repackaged build with an additional listener that exfiltrates credentials on first login. This is consistently named in customer-help-desk reporting as the single most common vector in the Nigerian retail segment.
- Rooted or jailbroken devices running tampered runtimes. Frida, Xposed, Magisk modules hooking the app's authentication and crypto routines. Frequent enough that "if the device is rooted, refuse" is now an industry-default posture.
- Network interception on public Wi-Fi. Cafés, hotels, NIPOST data points, conference centres. The TLS handshake is the only thing between the customer and the attacker; if the app trusts any certificate the platform trusts, the attacker buys a "wifi-portal-friendly" cert and watches.
- SIM-swap and SS7-class attacks against SMS-based OTP. Nigerian SIM-swap as a service has been a documented criminal economy for years. SS7 abuse is rarer but credible against high-value accounts. SMS OTP is structurally unrecoverable from these.
- Static reverse engineering for credential extraction. Hardcoded API keys, signing keys, encryption keys, debugging tokens — extracted from the APK or IPA, used against the production backend. Often what enables the "modified app" attacks above.
- Memory-resident credential capture. Less common but well-documented in research. Dumping the running app's memory to recover plaintext credentials, session tokens, or PINs that the developer assumed were transient.
The hardening below addresses all six, not as separate features but as a layered programme where each control closes part of the gap and the controls reinforce each other.
Layer 1 — Runtime Application Self-Protection (RASP)
RASP is the umbrella term for protective code embedded inside the app that detects and responds to threats to the app itself while it is running. The category has consolidated around a handful of credible vendors: Appdome, Promon SHIELD, Guardsquare DexGuard / iXGuard, Verimatrix Application Shielding, OneSpan Mobile App Shielding. The choice between them is mostly a procurement question; the controls they deliver are similar.
Six RASP controls we deploy as a minimum on a Nigerian Tier 1 banking app:
- Debugger detection. Refuse to run under JDWP, lldb, or any attached debugger. Frida and Xposed both surface here.
- Emulator detection. Refuse to run on Android emulators (Bluestacks, Genymotion, the official Android Studio emulator) and iOS simulators. Fraud rings emulate at scale to test stolen credentials.
- Hook framework detection. Frida-server, Xposed module presence, Substrate hooks, Magisk modules with suspicious capabilities. Detect, refuse, and report.
- Tamper detection. At runtime, verify the app's own signature, integrity of the DEX or Mach-O sections, integrity of native libraries. A repackaged build fails this check on first launch.
- Memory protection. Anti-debug primitives (ptrace_traceme, exit on PT_DENY_ATTACH), anti-dump, runtime decryption of sensitive constants so they don't sit in memory as plaintext.
- Server attestation. When the app talks to the backend, the backend asks "what kind of device are you on, what version are you, what's your tamper status." The backend refuses high-value operations from devices that fail attestation.
RASP is the layer that converts "device hostile" from a vague worry into a measurable posture. The sector's published incident pattern is consistent on this point: apps that survive sustained attack campaigns have RASP active; apps that contribute to incidents typically do not.
Layer 2 — Certificate pinning, done properly
TLS is necessary and not sufficient. The platform's default trust store contains a few hundred root CAs. An attacker who controls a Wi-Fi network and can persuade the customer to install a portal cert — or who has subverted a non-bank CA — can present a valid-looking certificate to the app, and the app's default behaviour is to trust it.
Certificate pinning closes this. Two variants, and the choice matters:
- Certificate pinning — the app embeds the bank's leaf or intermediate certificate and refuses any TLS connection that doesn't terminate at that exact certificate. Simple, brittle, breaks the day the certificate rotates.
- Subject Public Key Info (SPKI) pinning — the app embeds the SHA-256 hash of the public key. The certificate can be renewed (with the same key) without breaking pinning. This is the option to deploy.
The rotation problem is the second part. Pin one key, the day that key needs to rotate the bank ships an emergency app update — and customers who don't update are locked out. The defensible posture is:
- Pin at least two keys — the current production key and a backup key held offline. When the production key needs to rotate, the backup key takes over; the bank issues an app update that pins a new backup. No customer is ever locked out.
- Pin to an intermediate, not the leaf, where the bank controls its own intermediate. Leaf certificates rotate more often; intermediates last longer.
- Implement pin-failure telemetry. When a pin verification fails, the app reports the event (without the failing certificate) to the backend's security telemetry plane — landing in CloudTrail Lake or Security Lake per the AWS architecture in Part 2. Three thousand failed pins in Lagos on a Tuesday morning is the first sign of an active MITM campaign.
The "if your pinning is too restrictive, just turn it off" temptation has to be resisted at the architecture level. The bank holds two pinned keys, not zero.
Layer 3 — Root and jailbreak detection, and what to do when detected
Detection is the easier half. iOS provides isJailbroken heuristics (presence of /Applications/Cydia.app, /private/var/lib/apt, write access outside the sandbox, suspicious file paths). Android provides root-detection patterns (presence of su, Magisk daemon, suspicious mount points, busybox binaries). RASP vendors bundle hundreds of these checks; do not rely on a single check, because every single check has a known bypass.
The harder half is the response. Three options, in increasing order of severity:
- Monitor. The app continues to run on rooted devices but reports the device's status to the backend. The backend may then apply elevated friction (additional OTP, lower transaction limits, more manual review) to operations originating from those devices. This is the most permissive option and the right one for emerging markets where root and jailbreak are common for legitimate reasons.
- Degrade. The app runs but refuses high-value operations. The customer can check their balance and view their statement; they cannot initiate a transfer above N50,000 from a rooted device.
- Refuse. The app does not run at all on rooted or jailbroken devices. Strongest control, highest customer-support cost. The right option for high-net-worth or corporate-banking apps; usually too strict for retail.
The defensible landing point for a Nigerian Tier 1 in 2026 is Monitor or Degrade for the consumer app and Refuse for the corporate / treasury app. There is no single right answer; there is the answer that fits the customer base and the risk appetite the bank's board has signed off on.
Layer 4 — Move off SMS OTP
The 2025 incident data we have reviewed indicates that SIM-swap-driven fraud against Nigerian banks accounted for somewhere between 12% and 18% of authenticated-session fraud, depending on the bank. SMS OTP is the enabling weakness. Removing it is not an app-hardening control — it is a whole-bank-authentication redesign — but it has to land in this programme because the alternative is to keep funding the SIM-swap criminal economy with one's customers.
The migration path:
- Phase 1 — Push-based OTP. A push notification to the bank's app on the registered device, with the customer approving the transaction in-app. The mobile network operator is no longer in the authentication path.
- Phase 2 — TOTP for opt-in customers. A time-based one-time password seeded into the app at enrolment, displayed in-app, used as the second factor. No network dependency.
- Phase 3 — Biometric or WebAuthn / passkey on supported devices. Face ID, Touch ID, Android Biometric Prompt, hardware-backed key attestation. The strongest option, increasingly available on the device base Nigerian banking customers actually use.
- Phase 4 — Device binding. The customer's app instance is cryptographically bound to a specific device. Authentication on a new device requires step-up verification (branch visit, video KYC, or an existing device's approval). This closes the residual SIM-swap path even when SMS OTP is gone.
The four phases stack. A Tier 1 bank in 2026 is realistically operating Phase 1 for most customers, Phase 2 for digital-savvy customers, Phase 3 for opt-in customers, and Phase 4 as a baseline for new enrolments. SMS OTP gets demoted from "primary second factor" to "rare fallback" over twelve to eighteen months. It does not get eliminated immediately because the customer base will not tolerate it.
Layer 5 — Secure update channels and code signing
The app on the customer's device has to be updatable, and the update channel has to be trustworthy. Play Store and App Store are the trusted channels. Sideloaded updates, "in-app update" downloads from non-store URLs, and any update mechanism that bypasses the platform's signature verification are not.
Two requirements:
- Signing keys held in a Hardware Security Module. Android upload key, Android app-signing key (after Play App Signing migration), iOS code-signing certificate. Not on a build server's filesystem. Not in a CI variable. In an HSM with audit logging, where each release signing is an attested operation.
- Reject sideloaded updates and unsigned plug-ins. The app does not load executable code at runtime that wasn't part of the signed bundle. No remote JavaScript-as-code patterns, no dynamic native-library loading from anywhere except the app's own protected directory.
This connects to the signing chain documented in Part 1 — the in-toto attestation and SLSA 3 provenance that the build pipeline produces is the input to the signing operation. Provenance is verified at sign-time; the published artefact carries verifiable evidence of its build conditions.
OWASP MASVS — the mapping
The Mobile Application Security Verification Standard (MASVS) v2 is the international reference for mobile-app security controls. The seven layers above map cleanly to the MASVS categories that a CBN examiner, NDPA assessor, or counter-party assurance team will recognise:
| Layer | MASVS category |
|---|---|
| RASP — debugger, emulator, hook detection | MASVS-RESILIENCE (R1, R3, R4) — anti-debugging, anti-emulator, anti-hooking |
| RASP — tamper detection, memory protection | MASVS-RESILIENCE (R2) — anti-tampering, integrity verification |
| Certificate pinning | MASVS-NETWORK (N2) — public key pinning |
| Root / jailbreak detection | MASVS-RESILIENCE (R5) — runtime environment verification |
| Move off SMS OTP | MASVS-AUTH (A2, A3) — strong authentication, device-binding |
| Secure update channels, code signing | MASVS-PLATFORM (P1) — secure use of platform features; MASVS-CODE — secure coding and verified build |
We deliver against MASVS Level 2 as a minimum and the MASVS-RESILIENCE profile in full. This is the bar a Tier 1 bank in 2026 is being held to by counter-party assurance teams (international card schemes, correspondent banks) and is the bar that maps cleanly to the CIS Controls v8 mobile-application provisions and the NIST Risk Management Framework application-tier expectations.
The pre-publication checklist
We do not publish a new release of a Nigerian Tier 1 banking app to the Play Store or App Store without the following sixteen items verified, signed off, and archived:
- SAST scan clean, with documented exceptions for any high or critical findings. (From Part 1.)
- SCA scan clean against the dependency tree; no high or critical CVEs in shipped components.
- SBOM generated, signed, archived. (From Part 1.)
- RASP active and verified — debugger, emulator, hook, tamper, memory protections all reporting healthy.
- Certificate pinning verified — pin set includes current production key plus backup key; pin-failure telemetry confirmed reaching backend.
- Root / jailbreak detection verified — at least eight independent detection patterns, all reporting status to the backend.
- Backend device-attestation endpoint accepting and verifying client attestations.
- No hardcoded credentials, API keys, encryption keys, or signing material in the build. (Scanner-verified, manual code-review confirmed.)
- Authentication flow verified — primary factor, secondary factor, step-up flows for high-value transactions, device-binding active for new enrolments.
- TLS configuration verified — TLS 1.2 minimum, TLS 1.3 preferred, modern cipher suites only, HSTS on the backend, OCSP stapling.
- Penetration test report from the most recent quarterly pen-test against the staging build, with all findings remediated or formally accepted.
- DAST scan clean against staging deployment. (From Part 1.)
- Code signing performed in HSM with attested operation; signing logs archived in the audit-evidence vault.
- Provenance attestation (in-toto, SLSA 3) generated and archived alongside the release artefact.
- Release notes, change-log, and security-relevant changes documented; sign-off from Head of Application Security, Head of Mobile Banking, and CISO.
- Pre-release tabletop or wargame for any release that changes authentication, payment, or KYC flows.
A release that misses any of these items is not blocked because of a process rule. It is blocked because the bank does not have evidence to defend the release if it produces an incident. The checklist is the evidence chain.
The CSAT and NDPA mapping
The mobile-hardening layers map to specific obligations:
| Obligation | Where mobile hardening delivers |
|---|---|
| CBN CSAT — Customer-facing application security | Layers 1, 2, 3, 5 collectively. RASP, pinning, root detection, secure code-signing chain. |
| CBN CSAT — Strong customer authentication | Layer 4 — move off SMS OTP, device binding, MFA. |
| CBN CSAT — Application integrity | Tamper detection (Layer 1), signed updates (Layer 5), SBOM verification (Layer 5 + Part 1). |
| NDPA 2023 — Security of processing | Layer 1 RASP + Layer 2 pinning prevent unauthorised processing of personal data on the device or in transit. |
| NDPA 2023 — Breach response | Pin-failure telemetry + device-attestation feedback give the bank early warning of active campaigns, accelerating the 72-hour clock. |
| NCC consumer-protection guidelines | Layer 4 SIM-swap mitigation is explicitly relevant to the consumer-protection posture the NCC is building toward. |
What a Tier 1 bank actually deploys in 2026
The defensible stack picture for 2026:
- RASP: Promon SHIELD or Guardsquare DexGuard / iXGuard, with Appdome as the no-code alternative for banks without a deep mobile-security engineering bench.
- Code obfuscation: ProGuard / R8 (Android), Bitcode + DexGuard equivalents (iOS).
- Certificate pinning: native platform APIs with bank-controlled pin sets; OkHttp CertificatePinner on Android, NSURLSession evaluator on iOS, libsodium- or BoringSSL-backed for cross-platform layers.
- Root / jailbreak detection: RASP-vendor provided plus an in-house augmentation layer that monitors patterns specific to the Nigerian device base (specific OEM modifications, regional jailbreak tools).
- Authentication: push-OTP via the bank's own notification channel, TOTP for opt-in, biometric (Face ID / Android Biometric Prompt / WebAuthn) increasingly default for new devices.
- Device binding: a cryptographic key generated per device, attested via Play Integrity API (Android) or DeviceCheck / App Attest (iOS), bound to the customer's enrolled identity.
- Backend integration: device-attestation endpoint in the AWS landing zone, RASP telemetry into Security Lake, pin-failure events into CloudTrail Lake — the integration points the AWS architecture was designed to receive.
The above is the configuration that survives the threat picture the DSI banking briefing documents. A bank running less than this is operating outside the bar its counter-parties — international card schemes, correspondent banks, international card networks — are increasingly enforcing as a precondition of continued relationship.
What this does not cover
The mobile-banking app is the most-targeted surface but not the only one. The identity perimeter — IAM Identity Center, federated identity, MFA, privileged-access architecture — is its own substantial workstream and lands in Part 3 of this series. The backend the app talks to is hardened under the AWS-for-banks architecture and operational series. The branch and agent-network surfaces are out of scope here and are covered in our forthcoming agent-channel-security piece.
Part 3 — Identity-First Migration covers the IAM architecture that has to land before any AWS workload is provisioned. Part 1 — Securing the Application covers the build-pipeline and SDLC controls that produce the app this piece hardens.
The AWS-for-banks architecture series — the threat picture (DSI ↗), the architecture, the operational implementation — is the substrate this prequel series prepares the application surface for.
