The core of the 2016 Bangladesh Bank incident: a stolen SWIFT credential alone was enough for a transfer instruction to be processed as if the real bank had sent it. I reproduced the same structure (a static credential = permanent authentication) and verified how requiring secondary, out-of-band approval for large or unfamiliar-destination transfers stops an attack built on a stolen credential alone.
A learning resource for backend developers building financial messaging systems that trust a message's entire content just because the sending credential is valid.
A vulnerable messaging API that executes a transfer on a single matching static credential.
// Vulnerable transfer messaging API — modeled on the Bangladesh
// Bank incident. A single static credential is treated as permanent
// proof the message is genuine — steal it once, and it works forever,
// for any amount, to any destination.
class StaticCredentialTransfer {
constructor(validCredential) {
this.validCredential = validCredential;
}
transfer({ credential, amount, destination }) {
if (credential !== this.validCredential) {
return { status: 'invalid_credential' };
}
executeTransfer(amount, destination); // no regard for amount or destination
return { status: 'transfer_executed' };
}
}
module.exports = { StaticCredentialTransfer };
The fix: even a valid credential isn't enough for a large or unfamiliar-destination transfer without secondary approval.
// The fix: the credential becomes necessary but no longer sufficient.
// A large amount or a never-seen-before destination additionally
// requires a one-time approval code delivered out-of-band.
class SecondaryApprovalGuard {
constructor(validCredential, knownDestinations, largeAmountThreshold) {
this.validCredential = validCredential;
this.knownDestinations = knownDestinations; // Set<destination>
this.largeAmountThreshold = largeAmountThreshold;
}
transfer({ credential, amount, destination, approvalCode }) {
if (credential !== this.validCredential) {
return { status: 'invalid_credential' };
}
const isUnusual = amount >= this.largeAmountThreshold || !this.knownDestinations.has(destination);
if (isUnusual && !verifyOutOfBand(approvalCode)) {
return { status: 'secondary_approval_required' }; // credential valid, but not enough
}
executeTransfer(amount, destination);
return { status: 'transfer_executed' };
}
}
module.exports = { SecondaryApprovalGuard };
Questions or feedback about this product? Leave your email if you'd like a reply (optional).