Your firewall has never stopped an account takeover. It cannot. A takeover does not breach the network. It opens a browser, submits valid credentials, and logs in. From the network's point of view, the attack is a successful authentication, which is to say it is indistinguishable from business as usual.

The perimeter model assumes attacks arrive from outside, so the industry spent two decades hardening the edge. Meanwhile, most user-facing breaches in banking now happen at the application layer, inside a session that every network control considers legitimate. The attacker is not exploiting your infrastructure. He is using it exactly as documented, with someone else's identity.

This changes where detection has to live. If the attack arrives with a valid key, the only evidence that it is an attack is behavioral: where the session came from, what device is driving it, and what it does once inside. This post is about how we collect that evidence and act on it before the money moves.

Anatomy of a real takeover

Account takeover is not one event. It is a sequence, and the sequence is remarkably consistent across the incidents we see on our network:

  1. Credential acquisition. Phishing, a breach dump from an unrelated service, SIM-swap-assisted reset, or credential stuffing against reused passwords. This happens entirely outside your visibility.
  2. Validation login. A low-risk session to confirm the credentials work. Often just a balance check. Nothing is taken. This is the attacker's reconnaissance, and it is frequently the first moment we can see him.
  3. Profile change. Password reset, phone number swap, email change, or a new payee added. This step converts access into control. It is the loudest signal in the sequence, and the one most systems log and then ignore.
  4. Cash-out. A transfer to a mule account, often just below a reporting threshold, sometimes split across several transfers. By this point the attacker has a time budget of minutes before someone notices.

The spread matters as much as the steps. We see sequences compressed into four minutes and stretched over nine days. A rule that looks for "password change followed by transfer within one hour" catches the first kind and waves the second through. The attacker only has to be patient to defeat time-window rules.

The four signal families

Everything we collect about a session falls into four families. None is decisive alone. Takeover becomes visible when they stack.

Network context

Where the connection comes from. We resolve every request IP at ingest into its ASN, geolocation, and infrastructure type, and we maintain reputation data on the ASNs themselves. The high-signal findings: the IP belongs to a datacenter rather than a residential or mobile provider, the connection rides a VPN or proxy exit node, or the ASN has a history of abuse traffic. We also compute impossible travel: a session from Lagos at 14:00 and another from a London exit node at 14:20 is not a customer who flies fast.

Device integrity

What is driving the session. Every login and sensitive action carries a device fingerprint built from stable attributes: hardware profile, OS build, TLS stack, rendering characteristics. We track first-seen devices per account, because a customer who has banked from the same two phones for a year does not suddenly bank from a third at 3am. We also flag emulator and tamper indicators: instrumentation frameworks, hooked system calls, sensor data that never varies. Real phones jitter. Emulators are unnaturally still.

Session behavior

What the session does and when. Night-time requests against an account whose history is strictly daytime. Velocity anomalies: navigation ten times faster than the account's norm, or a session that goes straight from login to the payee page in eleven seconds without a single misstep. Legitimate users wander. They mistype, they back out, they check the balance twice. Scripted sessions execute.

Account changes

Mutations to the account itself. A password reset is routine. A new payee is routine. A password reset and a new payee in the same session, from a first-seen device, is the takeover sequence collapsing into one observable moment. We treat compound changes as a signal class of their own, because the composition is the evidence even when each part is innocent.

Event-driven collection, enrichment at ingest

Institutions stream events to us as they happen, through a small REST API or SDKs that wrap it. The contract is deliberately boring: one call per event, a few required fields, everything else optional. A login looks like this:

{
  "event_type": "LOGIN",
  "account_id": "acct_9f3k2",
  "ts":         "2026-09-14T03:12:41+01:00",
  "ip":         "102.89.34.117",
  "channel":    "mobile_web",
  "device": {
    "fingerprint": "d8f2c91a...",
    "os":         "Android 14"
  }
}

// what we add at ingest, before scoring:
{
  "ip": {
    "asn":           "AS29073",
    "is_datacenter": true,   // hosting provider, not a phone
    "is_vpn":        true,
    "geo":           "NL"      // account history: NG only
  },
  "device": {
    "first_seen_for_account": true,
    "emulator_indicators":    false
  },
  "context": {
    "local_hour_at_account": 3,
    "impossible_travel":     false
  }
}

The architectural decision that makes this cheap: enrichment happens once, at ingest, never at query time. When the event arrives we resolve the IP against our ASN and geolocation tables, run the device history lookup, and write the enriched record. Scoring and investigation then read flat fields instead of fanning out to external lookups. The expensive work is paid on the write path, where milliseconds are free, not on the read path. That discipline is part of how verdicts stay at 142ms p50.

Design rule: enrichment is append-only and versioned. If our ASN data improves next month, historical events keep the enrichment they were scored with. A case officer reconstructing a March decision must see what we knew in March, not what we know now.

Score the session before the payment

Most fraud stacks wake up when a payment instruction arrives. By then the takeover is three steps deep and the only remaining option is blunt: block or allow the transfer, with the customer experience riding on a single decision. We score earlier, at three checkpoints, and each checkpoint is cheaper than the one after it:

  1. At login. Network context plus device integrity produce a session risk score in the same request that authenticates the user. A bad score here does not block anyone. It raises the sensitivity of everything that follows and can force a step-up before the session does anything sensitive.
  2. At profile change. Password resets, phone swaps, and new payees re-score the session with the account-change signals added. This is where step-up verification earns its keep: an OTP to a number that has been on file for a year costs the customer eight seconds and costs the attacker the entire operation.
  3. At transfer. The full six-engine pipeline decides, with the session's entire history as input. Blocking here works, and in the incident below it did. But it is the most expensive place to learn you have a problem: the customer is already alarmed, and the money was one approval away from leaving.

Catching takeover earlier costs less at every step. A step-up at profile change is a customer-security moment. A blocked transfer is a fraud incident. Same attacker, same signals, very different morning for the operations team.

When one account becomes twenty

Single-account takeover is a crime. Coordinated takeover is an industry. When a crew works through a breach dump, the accounts they touch look unrelated: different customers, different institutions, different cities. What they share is infrastructure. The same emulator farm drives forty logins. The same two datacenter ASNs carry every validation session.

This is why we persist identity edges, the graph concept from Part 1: every login writes LOGGED_IN_WITH and CONNECTED_FROM relationships alongside the session record. One flagged account then becomes a query, not a dead end. Which other accounts touched this device in the last thirty days? Which accounts validated from this ASN this week? The fraud-ring signature is not any single session. It is the overlap, and overlap only exists if you recorded it before you knew you needed it.

03:12 WAT, walked through

The incident we keep returning to in this series started exactly this way. At 03:12 WAT, a login event arrived for an account at one of the institutions on our network. The credentials were correct. Everything the network layer could check said allow.

The session scored differently. The IP resolved to a datacenter ASN with recent abuse history, riding a VPN exit in a country the account had never touched. The device fingerprint was first-seen for the account. The local hour was 3am against a strictly daytime history. Three families stacked before the session did anything at all. The trust score, the running 0-to-100 measure we maintain per account, collapsed to 18, below our auto-interdiction threshold of 20.

Eight minutes later the session pushed a TRANSFER of ₦4,250,000 to a new payee added that same night. The screening pipeline returned BLOCK in 155ms, and because the session was already flagged, the tracer had a head start: ₦4.1 million was frozen at the third hop before it could cash out. The takeover attempt never became a loss. It became a case file.

Behavior is the evidence

Rules catch what fraud looked like yesterday. The attacker who changes his tooling defeats the rule that described it, and the rule never notices. Behavior is harder to change, because behavior is the cost of doing the crime: the attacker must log in from somewhere, drive the session with something, and convert access into control before he can cash out. Each necessity leaves a trace at the application layer, the one layer he cannot avoid crossing.

Everything in this post depends on a number we have mentioned but not explained: the trust score that dropped to 18 and triggered the freeze. How that score is computed, how it decays and recovers, and why we let it freeze accounts without a human in the loop is the subject of the final post in this series.


Next in the series: trust scores that freeze accounts themselves, the continuous scoring system behind the automatic interdiction in this incident. Read part 4.

Watch a takeover get stopped live

We'll replay a full ATO sequence against a demo environment in 30 minutes: validation login, profile change, step-up challenge, blocked cash-out, frozen destination.