Security Advanced

Monetizing Web App Compromise — From SQLi to Wire Fraud

How attackers turn a web app breach into euros — credential resale, payment data, account takeover, fraudulent transactions. The economics that drive defenses.

DjangoZen Team May 10, 2026 12 min read 1 views

Why economics matter in defense

Attackers optimize for profit per hour. Defenses that don't change attacker economics don't reduce risk — they just shuffle which doors get opened. To build defenses that actually deter attacks, you need to understand what makes a compromise profitable and what makes it not.

This tutorial walks through the main monetization patterns for web app compromise and the specific defenses that disrupt each.

Pattern 1 — Credential resale at scale

The most common monetization route, requires the least skill from the buyer.

The flow

  1. Attacker scrapes login forms from thousands of websites
  2. Runs credential-stuffing botnet against each, using stolen credential dumps
  3. Successful logins compiled into "combolists" — sold on dark forums
  4. Buyers use them for higher-value attacks: SaaS account takeover, banking fraud, identity theft

The economics

  • Generic SaaS credentials: €0.10-€1.00 per working combo
  • Streaming/media credentials: €2-€20
  • Banking credentials: €50-€500 (US/EU)
  • Corporate credentials at known companies: €200-€10,000 (resold to IABs)

A successful stuffing campaign returns 0.1%-1% of attempted credentials. The math works because compute is cheap and attempts are unlimited.

Defenses that change the economics

  • MFA — single biggest disruption. Combos without working MFA codes are nearly worthless.
  • Rate limiting per IP and per account — botnets need clean IPs, which cost money. Forcing them to rotate slows attacks dramatically.
  • Block known breached passwords on login — pwndpwd k-anonymity lookup, fail if hit. Defeats stuffing because the breached creds being stuffed are the exact ones being blocked.
  • Account lockout with timing-safe messaging — "username/password incorrect or too many attempts, try again later" — same response regardless of which condition, so enumeration is harder.
  • CAPTCHA on suspicious patterns — not on every login (terrible UX), only when risk signals fire (new IP, new device, fast retries).
  • Device fingerprinting — even when the password is right, an unrecognized device triggers step-up auth.
# Django example: enforce breached-password check on login
import hashlib
import requests

def is_breached(password: str) -> bool:
    sha1 = hashlib.sha1(password.encode()).hexdigest().upper()
    prefix, suffix = sha1[:5], sha1[5:]
    r = requests.get(f"https://api.pwnedpasswords.com/range/{prefix}", timeout=2)
    if r.status_code != 200:
        return False  # Fail open — don't lock users out on API issues
    return any(line.startswith(suffix) for line in r.text.splitlines())

def login_view(request):
    if request.method == 'POST':
        password = request.POST['password']
        if is_breached(password):
            messages.error(request, 'This password appears in known breaches. Please use a different password.')
            return redirect('password_reset')
        # ...regular auth flow

Pattern 2 — Payment data theft

The classic and still highly profitable. Attackers compromise either:

  • The site's card storage (PCI breach — disastrous, regulated, fineable)
  • The checkout flow (Magecart-style JavaScript injection that exfiltrates cards as customers type)
  • The payment processor integration (stolen Stripe API keys = fraudulent charges)

Magecart in detail

Attackers compromise either the host directly or a CDN/script you load. Inject JavaScript into the checkout page that copies form data and POSTs it to attacker-controlled infrastructure. The page works normally — customer pays, gets product. But their card is now stolen.

Famous victims: British Airways, Ticketmaster, Newegg. Losses in the hundreds of millions, plus regulatory fines.

Defenses

  • Don't store card data — let Stripe / your PSP handle storage. Tokenization moves PCI scope off your servers.
  • Content Security Policy (CSP) — strict CSP prevents arbitrary script injection. script-src 'self' plus explicit allowlist for CDNs.
  • Subresource Integrity (SRI) on every external script — <script src="..." integrity="sha384-..."> ensures the loaded content matches the expected hash.
  • CSP report-uri — get notified when CSP violations occur, often the first sign of injection attempts.
  • Stripe API key restriction — restrict by IP (covered in earlier Stripe series), use restricted keys for production not full secret keys.
  • Webhook signature verification — never trust unsigned webhook calls. Stripe-Signature header check on every event.
# CSP middleware in Django settings
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'", "https://js.stripe.com", "https://cdn.jsdelivr.net")
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net")
CSP_FRAME_SRC = ("https://js.stripe.com",)
CSP_CONNECT_SRC = ("'self'", "https://api.stripe.com")
CSP_REPORT_URI = "/csp-report/"

Pattern 3 — Account takeover for high-value users

The economics shift when the target is a specific account, not a bulk credential. Attackers take over:

  • Influencer / executive accounts — used for blackmail, brand damage, or to send messages to their network
  • Customer support / staff accounts — to access customer data without raising flags
  • Developer accounts — to push malicious code through CI/CD, leak source, plant backdoors
  • Finance / AP accounts — to authorize fraudulent transfers

The attack: targeted phishing, SIM swap to bypass SMS-MFA, OAuth consent phishing, or session token theft.

Specific defenses

  • Phishing-resistant MFA for high-value roles (WebAuthn / FIDO2, not SMS or TOTP)
  • Approval workflows for high-impact actions even within an authenticated session
  • Session reauthentication — "this action requires re-entering your password"
  • Anomaly detection — alerts when an admin logs in from a new location/device
  • Audit logs that can be reviewed after a suspected incident
  • OAuth scope minimization — apps should never grant broader scopes than needed

Pattern 4 — Cryptominer drop and infrastructure abuse

Attacker doesn't want your data. They want your CPU.

The flow

  1. Exploit any RCE vulnerability in the web stack
  2. Drop a miner pointed at attacker's pool
  3. Sometimes drop a reverse shell as a backup persistence mechanism
  4. Stay quiet — mining is more profitable when not detected

Why it's persistent

The miner often doesn't even need root — runs as the application user, indistinguishable from a busy worker process. Easy to miss until the cloud bill arrives.

Defenses

  • Patch promptly — CVE-to-exploit is now hours, not weeks
  • Egress firewall — miners need to connect to pools. Block outbound to anywhere other than known endpoints
  • CPU/memory anomaly alerting — sustained 100% CPU outside known job windows is suspicious
  • Cloud bill alerting — set a daily threshold; sudden 5x spike means something
  • Container hardening — read-only filesystems, no shell, drop unnecessary capabilities
  • Runtime detection — Falco, Wazuh, or commercial EDR will catch most miner deployments

Pattern 5 — Business Email Compromise via the web app

Less obvious than the others but extremely lucrative.

Many web apps integrate with email — sending invoices, password resets, notifications, customer communications. Compromise of the app may give attackers:

  • The ability to send email from your domain (passes SPF/DKIM)
  • Access to email templates that look legitimate
  • Customer data to craft personalized pretexts

The attacker uses this to send convincing emails to your customers' AP departments, requesting that future invoices be paid to an attacker-controlled bank account.

Defenses

  • DMARC enforcementp=reject with monitoring
  • Restrict who can send email from your domain — application servers via authenticated SMTP, no other source
  • Output sanitization in admin tools — preventing internal staff from accidentally including customer-controlled content in outgoing communications
  • Audit logging of all transactional emails sent — anomalies show up here
  • Vendor banking change verification — your own customers should refuse to update banking info via email alone

Pattern 6 — Supply chain via your web app

A specific and growing pattern: your web app loads JS/CSS from a third-party CDN or package manager. The third party gets compromised. Your users get malicious code.

Recent examples:

  • eslint-scope (2018) — npm package compromised, malicious code shipped to thousands of CI systems
  • CodeCov (2021) — bash uploader modified to exfiltrate env vars, including AWS keys
  • xz Utils (2024) — multi-year supply chain attack into a core OS library

Defenses

  • Pin dependency versions with integrity hashes (package-lock.json, poetry.lock with hashes)
  • SRI on every external script load
  • Mirror critical dependencies internally
  • Periodic audit of dependencies — what loaded, what version, when last updated
  • Egress filtering on build systems — supply chain malware often phones home with secrets

The defense-economics summary

Mapping defense priorities to threat types:

Defense Disrupts
MFA (phishing-resistant) Credential stuffing, account takeover, BEC
Rate limiting on auth Credential stuffing
Breached password blocking Credential stuffing
CSP + SRI Magecart, supply chain JS injection
DMARC Email spoofing, BEC
Egress filtering Cryptominer C2, data exfiltration
Dependency pinning + scanning Supply chain
Audit logging + anomaly alerting All categories — your detection layer

The combination is multiplicative. Each defense alone deters some attackers; the stack deters the ones who'd otherwise persist.

Where SMEs typically fail

Patterns in real-world Dutch SME web app breaches:

  1. No MFA on a single forgotten staff account — the rest of the security was solid, but one admin account without MFA was enough
  2. Outdated framework with public CVE — patched four hours after disclosure, but breached three hours after disclosure
  3. Phishing → OAuth consent — sophisticated phishing led to an OAuth grant that bypassed all the password-focused defenses
  4. CMS plugin with leaked DB credentials — third-party plugin had a hardcoded API endpoint; that endpoint was misconfigured and leaked the connection string
  5. Default admin URL with weak password and brute force — the WAF didn't see /admin/ as needing special protection

Each is preventable with the basics from tutorial 1 plus the disruptions in this tutorial. None require nation-state-tier defenses — just consistent execution of fundamentals.

Closing thought

Attackers will always find the cheapest path to monetization. Your job is to make every path expensive enough that they move to another target. Perfect security is impossible. Sufficient deterrent is achievable.

Build defenses that change the economic calculation. Track them. Test them. The next eight tutorials show you how at the technical level.