Case Study — Mobile Banking QRIS Module (Inbound & Outbound)

One static QR print = permanent merchant account hijack. We swapped the NMID before the cashier noticed.

Client Context

State-owned bank — QRIS CPM/MPM in mobile banking (Android/iOS, 4M users) — QR generation, merchant settlement & refund APIs. Pre-launch OJK & BI QRIS audit + app store release in 4 weeks.

Challenge

QRIS flows mix mobile SDK, backend APIs & merchant settlement — attacker window: QR tamper, MITM on public Wi-Fi, and merchant spoof. Prior SAR: hard-coded SDK key in app.

Scope — Snipeyes Mobile + API Pen-Test (CREST, MASVS)

  • iOS/Android static + dynamic analysis: OWASP MASVS L2, hard-coded secrets, SSL pinning, root/jailbreak, intent leakage
  • QR lifecycle: MPM static print, CPM dynamic token (30s), settlement callback & refund — tamper, replay, race condition, amount swap
  • Backend APIs (19 endpoints): BOLA, IDOR on merchantId/NMID, signature bypass, rate-limit on QR gen
  • Settlement & reconciliation: merchant spoof, double-credit, webhook forge

Key Findings (redacted)

  • CRITICAL: Static MPM QR — NMID + merchant PAN not signed → attacker reprinted QR with own NMID, funds diverted (PoC: sticker overlay)
  • HIGH: SDK API_KEY hard-coded + no pinning → MITM on public Wi-Fi allowed QR payload tamper (amount 10k → 1M)
  • HIGH: refund BOLA — any merchant could refund other merchant’s transaction via IDOR
  • 22 findings: 1 Critical, 3 High, 8 Medium, 10 Low — CVSS + MASVS/PCI DSS 4.0 mapping, retest included

Outcome

  • Dynamic QR now signed (HMAC) + short-lived, SDK key moved to vault + cert pinning + RASP — retest 100% critical closed in 5 days
  • Passed BI QRIS & OJK audit first submission, app store approved, fraud rate 0 on launch month
  • Merchant QR re-issuance SOP + settlement anomaly rule (Snipeyes Fraud Detection hook)

Relevance for you: If you run QRIS, wallet or merchant acquiring — we test the print, the app, and the settlement, not just the API.

Request QRIS Proposal → · See Fraud Detection →