How Nigerian Tier 1 wallet onboarding works
The CBN's tiered KYC framework assigns limits to accounts based on the identity documentation provided at onboarding. Tier 1 — the lowest tier — permits a ₦50,000 single-transaction limit and ₦300,000 maximum cumulative balance. It requires a Bank Verification Number (BVN) or National Identification Number (NIN) as the sole identity anchor.
In practice, most Nigerian fintechs integrating Tier 1 onboarding use Smile Identity or Dojah as their KYC middleware. The flow looks like this:
- The user submits their BVN during account creation. The app calls the KYC provider's API, which validates the BVN against the NIBSS (Nigeria Inter-Bank Settlement System) database and returns the registered name and date of birth.
- The KYC provider initiates a liveness check — the user takes a selfie, and the provider compares it biometrically against the photo held by NIMC (National Identity Management Commission) against the BVN record.
- If both steps return a pass result, the account is opened. BVN ownership is confirmed; the person holding the phone is confirmed to be that BVN's owner.
That two-step gate — BVN validation plus liveness match — is the intended security model. The vulnerability lives not in the gate itself, but in what happens when the gate is temporarily unavailable.
The timeout problem
NIBSS and NIMC APIs are government infrastructure. They are not built to the same reliability standards as a commercial SaaS platform. Documented outages, degraded performance windows, and burst-related slowdowns are a routine operational reality for every fintech operating in Nigeria.
Smile Identity and Dojah both carry their own SLAs — but those SLAs cover the
middleware layer, not the underlying government data sources they query. When
NIMC degrades, a liveness verification call that normally resolves in two to
four seconds will timeout after 15 to 30 seconds. The KYC provider returns an
error code — typically something like PROVIDER_TIMEOUT or
VERIFICATION_UNAVAILABLE — and your application has to decide what
to do next.
Most engineering teams building onboarding flows design around the happy path. The timeout handling is often added later, under pressure, with the primary goal of reducing drop-off. That is where the exposure is introduced.
Fallback patterns and their risks
Three common fallback patterns appear across Nigerian fintech onboarding implementations. Each one creates a different attack surface.
Pattern A: Fail open
If the liveness check times out, the account is created anyway. The engineering rationale is straightforward: a timeout is not a failure — the system simply could not reach the provider. Blocking the user for a government API issue feels punitive.
The attack is equally straightforward. An attacker sources a valid BVN from a data leak (covered below), submits it with any photograph — their own face, a stock image, anything — and deliberately triggers or waits for a timeout. The liveness step never completes. The account opens. The BVN is now attached to an account the rightful BVN owner never created.
The attacker's server-side call looks like any other legitimate timeout:
POST /v1/onboarding/verify-identity
{
"bvn": "22198765432",
"selfie_image_base64": "...",
"full_name": "ADEYEMI JOHN BABATUNDE",
"dob": "1990-04-12"
}
// KYC provider response after 28s:
{
"status": "error",
"code": "PROVIDER_TIMEOUT",
"message": "Liveness check provider did not respond in time.",
"bvn_validated": true
}
// Application fallback logic (vulnerable):
if (response.code === 'PROVIDER_TIMEOUT' && response.bvn_validated) {
await createAccount({ bvn, userId, tier: 1 }); // ← account opens
}
The bvn_validated: true flag in the timeout response is the
dangerous signal. The BVN check passed against NIBSS before the liveness
provider degraded. Application code that reads this flag and proceeds treats a
partial verification as a complete one.
Pattern B: Retry then pass
The flow retries the liveness check up to three times. If all three attempts fail
or timeout, the account is created with a KYC status of PENDING_REVIEW
and limited access is granted. A human reviewer will check the case within the
defined SLA — commonly 24 to 72 hours.
The account has inbound and outbound capability during the review window, subject to Tier 1 limits. An attacker creates the account, completes inbound and outbound transactions within Tier 1 limits, and exits the platform before the manual review occurs. The review, when it eventually happens, finds a suspicious account that has already moved funds.
Pattern C: Skip liveness, require on first withdrawal
The account opens without liveness. Liveness is enforced as a gate on the first withdrawal attempt. The premise: the user can receive money immediately; they must verify before spending it.
This pattern is actively exploited in money laundering chains. The synthetic account functions as an inbound hop — it receives funds from other accounts in the chain, and the balance is then moved out through a separate account (or a different platform entirely) that has already passed liveness. The account that accepted the inbound funds never needs to withdraw anything, so liveness is never triggered. It exists purely as an anonymised collection point.
How attackers source BVNs at scale
A valid BVN is the only input required to trigger a Tier 1 onboarding flow. Getting one is not a technical challenge in 2026.
Data breaches from Nigerian financial institutions, government service portals, and third-party KYC integrations have collectively exposed tens of millions of BVN records over the past several years. Several active Telegram channels and dark web forums sell curated, validated BVN datasets — bundled with the registered name, date of birth, and sometimes the linked phone number. Prices range from ₦500 to ₦2,000 per verified record depending on freshness.
The attacker does not need to crack anything. They purchase a spreadsheet. They run a script. The onboarding flow does the rest — especially if it fails open.
What makes this scalable is that BVN validation against NIBSS is designed to be fast and available. The attacker can test hundreds of BVNs against your onboarding endpoint in hours, probing for which ones pass the BVN check before deliberately engineering timeouts on the liveness step.
Business impact
Synthetic identity accounts opened at scale are an Anti-Money Laundering (AML) liability, not just a fraud problem. The CBN holds the licensed fintech responsible for KYC failures — not the KYC provider, not NIMC, and not NIBSS.
- CBN AML/CFT sanctions: KYC failures under the CBN's AML/CFT framework carry penalties of up to ₦50 million per infraction, plus potential suspension of the relevant product or operating licence.
- NDPA exposure: The Nigeria Data Protection Act requires notification when personal identity data is misused on your platform. If BVN records were used to open fraudulent accounts, the legitimate BVN holders are data subjects whose information has been processed without their consent. Failure to notify carries its own regulatory consequences.
- Investor risk: Due diligence on a fintech preparing for a Series A or seeking a CBN licence extension will surface unusual KYC pending queue sizes, high manual review backlogs, and transaction patterns inconsistent with the declared customer base. AML findings at this stage have killed term sheets.
- Correspondent banking relationships: If your platform is used as a laundering hop, your partner banks — who have their own AML obligations — will de-risk you. Losing a correspondent banking relationship mid-scale is an existential event.
The fix
None of the following recommendations are vague. Each is an implementable architectural or code-level change.
1. Never fail open on identity verification
If the third-party KYC provider returns a timeout on the liveness check, account creation must pause — not proceed. The correct server-side logic:
// Correct timeout handling
if (response.code === 'PROVIDER_TIMEOUT') {
await saveOnboardingSession({
userId,
bvn,
status: 'KYC_INCOMPLETE',
reason: 'liveness_provider_timeout',
retryEligibleAfter: Date.now() + 1000 * 60 * 30, // 30 min
});
return res.status(202).json({
message: 'We could not complete identity verification right now. ' +
'We will send you a link to continue within 30 minutes.',
});
// Account is NOT created at this point.
} Queue the user for a retry. Send them an SMS or email with a time-bound continuation link. The 24-hour retry window is acceptable for Tier 1 onboarding — the urgency of "open an account right now" should not override the integrity of the identity gate.
2. If you must grant limited access before verification, enforce zero outbound
If your product genuinely requires the account to exist before liveness completes (for example, to issue a virtual account number for inbound funding during onboarding), enforce these constraints at the database/ledger layer — not just in the UI:
-- Enforce at the transaction processing layer
-- before any debit is posted
SELECT kyc_status, kyc_liveness_passed
FROM accounts
WHERE id = $accountId
FOR UPDATE; -- pessimistic lock on the row
-- If kyc_liveness_passed IS FALSE, reject the debit:
-- RAISE EXCEPTION 'Account not eligible for outbound transactions pending liveness verification.'; Do not rely on application-layer checks that can be bypassed through direct API calls. The guard must live in the transaction processing path, not the frontend.
3. Implement server-side BVN deduplication
Each BVN should map to exactly one active account on your platform. Store a hashed representation of the BVN (never plaintext) and enforce uniqueness at account creation:
-- Schema constraint
CREATE UNIQUE INDEX idx_accounts_bvn_hash
ON accounts (bvn_hash)
WHERE status != 'CLOSED';
-- Application layer
const bvnHash = crypto
.createHmac('sha256', process.env.BVN_HMAC_SECRET)
.update(bvn)
.digest('hex');
const existing = await db.account.findFirst({
where: { bvnHash, status: { not: 'CLOSED' } },
});
if (existing) {
await flagForManualReview({ bvn: bvnHash, reason: 'duplicate_bvn_submission' });
return res.status(409).json({
error: 'An account with this BVN already exists.',
});
} 4. Monitor for timeout spikes as a probe signal
A sudden cluster of liveness timeout events — especially outside business hours and across different submitted BVNs — is not a NIMC infrastructure event. It is an attacker probing your fallback behaviour. Set up an alert:
// Pseudocode — adapt to your monitoring stack (Datadog, Grafana, CloudWatch)
if (
liveness_timeout_count_last_15min > THRESHOLD &&
hour_of_day BETWEEN 0 AND 5 // off-hours window
) {
trigger_alert({
severity: 'HIGH',
message: 'Unusual liveness timeout cluster — possible fallback probe',
metadata: { bvns_submitted, source_ips, user_agents },
});
} Correlate timeout events with the source IPs and device fingerprints. A single IP submitting 40 different BVNs across 40 account creation attempts in two hours is not a NIMC outage. It is reconnaissance.
Tier 1 onboarding fallback used as a laundering hop
During a penetration test engagement, we found a fintech platform whose
onboarding flow fell back to a PENDING_REVIEW KYC status after
three consecutive liveness check failures. The manual review queue carried a
72-hour SLA. During that window, the account had a ₦50,000 per day inbound
limit — consistent with Tier 1 — but outbound transactions were not blocked.
An attacker could create an account using a purchased BVN, receive ₦50,000
from a money mule account, and withdraw below the daily limit before the
manual reviewer ever opened the case. The platform's transaction history
showed a pattern of recently created accounts receiving a single inbound
transfer and immediately withdrawing before completing KYC. Fix priority:
Critical. Remediation: hard-block outbound transactions on
all accounts with kyc_liveness_passed = false, enforced at the
ledger layer, regardless of review queue status.
What automated scanners miss
Automated scanners do not model third-party API timeouts as test scenarios.
A DAST tool scanning your onboarding endpoint will test for injection,
authentication bypass, and rate limiting — it will not simulate a 30-second
NIMC timeout and then observe the resulting account state machine. Finding
this class of vulnerability requires manually manipulating network conditions
to simulate provider failures (using tools like tc netem on
Linux or proxy-level latency injection), submitting crafted requests during
the degraded state, and verifying what account state the server has recorded
as a result. That is a manual, context-aware test — which is exactly why
it consistently appears in engagement findings across platforms that have
already run automated scans.
Does your onboarding flow have a documented, tested response to a Smile Identity or Dojah timeout — one that your security team has verified produces the correct account state?
Get a security reviewFrequently asked questions
Can we use BVN validation without a liveness check for Tier 1?
CBN guidelines technically allow BVN-only verification for Tier 1 account opening, but liveness adds a meaningful barrier to synthetic identity fraud. The critical question is whether your fallback behaviour on a liveness failure allows that step to be bypassed entirely — because if it does, the BVN check alone is insufficient.
What if our KYC provider's uptime is the bottleneck?
Require contractual SLA guarantees from your KYC provider. Smile Identity and Dojah both offer enterprise SLA options with defined uptime commitments. If they cannot provide the reliability your onboarding flow requires, your fallback logic becomes a product-level risk that regulators will hold you accountable for — not the vendor.
How do we detect synthetic identity accounts post-creation?
Monitor for these signals: the same BVN submitted across multiple account creation attempts, device fingerprint or IP reuse across different BVNs, transaction patterns inconsistent with the stated income or employment category, and inbound-only transaction behaviour during the pending-verification window.
Related reading
Blog: KYC and BVN data security in Nigerian fintech · Biometric spoofing and liveness detection gaps
Services: Authentication security testing · Penetration testing
Guides: CBN compliance and security requirements · NDPA compliance guide