The direct deposit change is the whole attack
Payroll diversion does not require malware, a zero day, or a clever exploit. It requires one form submission in a system the attacker is legitimately logged into. Every control most employers have bought sits in the channel the attacker already owns, which is why the money is gone before anyone knows a control was tested.
The Friday nobody noticed until payday
It is the second Friday of the month and Priya, a research administrator, opens her banking app on the train home. There is no deposit. She refreshes. She checks the date, because everyone checks the date. She calls payroll.
Payroll pulls up her record and finds nothing wrong with it. The salary run completed. The money left the employer's account on schedule, in full, on time, to the bank details on file. That is the entire problem. The bank details on file were changed eleven days earlier, at 10:42 on a Monday morning, through the employee self service portal, from a session that authenticated correctly and passed multi factor authentication. The audit log records a routine profile update. It does not record a break in.
The confirmation email went out, as designed. It arrived in Priya's mailbox, as designed. It was moved to a folder called "RSS Feeds" by an inbox rule created four minutes before the change, and marked as read. Priya never saw it. Nothing on her screen looked different. Nothing in the security stack fired, because from the perspective of every system involved, an authenticated user updated their own banking preferences, which is a thing authenticated users are supposed to be able to do.
By the time anyone learns the word "diverted", the receiving account has been drained and closed. Priya still has to make rent, and the employer, in most jurisdictions, still owes her the wages. So the employer pays twice, opens an investigation, files a report, and adds a line to the risk register about phishing awareness training.
Short answer: You stop payroll diversion by making the bank detail change itself impossible to complete without a fresh cryptographic signature from the employee's enrolled device, covering the exact new routing and account numbers. Email alerts, callback policies and login MFA all operate inside the channel or the session the attacker already controls, so they can only notice the change after it has been accepted.
What is payroll diversion fraud, and what does it actually cost?
Payroll diversion is a subtype of business email compromise. Rather than impersonating an executive to trigger a wire, the attacker impersonates an ordinary employee to redirect that employee's salary. It is quieter, it repeats every pay cycle until someone notices, and it targets a system that most security teams do not think of as a payment system at all.
The category it belongs to is large and getting larger. Business email compromise produced $3.05 billion in reported United States losses across 24,768 complaints during 2025, and 86 percent of those losses moved by wire or ACH, the same rails payroll runs on (FBI IC3 2025 Internet Crime Report). Business email compromise was the second largest reported cyber enabled loss category that year, ahead of ransomware.
Payroll diversion specifically is a high frequency, medium severity loss, which is exactly the profile that escapes board attention. The FBI's 2019 public service announcement on payroll diversion recorded 1,053 complaints between January 2018 and June 2019 with total reported losses of $8,323,354, which works out to an average of $7,904 per complaint (FBI IC3 public service announcements). That is not a headline number. It is a paper cut that recurs.
Why the average loss is the wrong number to plan around
The direct loss is the smallest part of the bill. Work the arithmetic for an employer with 20,000 staff that absorbs a dozen incidents a year. Twelve diverted salaries at roughly $7,900 each is about $95,000 in wages paid a second time. Each incident then consumes payroll, HR, security, internal audit and often legal time, and twelve investigations at forty hours of blended professional time each is another six figures. Add the mandatory notifications, the police reports, the low yield bank recall attempts, the manual off cycle payment runs, and the effect of repeated claims on social engineering insurance pricing.
The organisation is comfortably past a million dollars a year on a control set that does not work, and none of that spend appears on a line item called "payroll diversion".
How does the attack actually work, step by step?
Understanding the fix requires understanding the sequence properly, because each step is designed to be individually unremarkable. There is no moment in this chain where a system is asked to do something it was not built to do.
Step one: the attacker takes the session, not the password
The modern entry point is rarely a stolen password used at a login form. It is adversary in the middle phishing: a reverse proxy relays the genuine login page to the victim, the victim authenticates against the real identity provider with a real password and a real multi factor prompt, and the kit harvests the resulting session token. The victim's credentials were never wrong. Their MFA never failed. Both worked, and the attacker collected what they produce.
This is not artisanal work. Tycoon 2FA, one such phishing as a service platform, was linked to more than 96,000 victims and 330 domains before an international disruption effort reported by Microsoft and Europol in March 2026 (Microsoft Security Blog), and researchers at Sekoia counted eleven distinct commercial adversary in the middle kits operating in the first four months of 2025 alone. Session theft is a subscription product, and we cover the mechanics in the post on adversary in the middle session theft.
Other doors reach the same room: a reused password, a push approved at the twentieth prompt at midnight, or a help desk agent socially engineered into resetting an authenticator, which is the pattern described in the help desk reset post. The entry vector varies. What follows does not.
Step two: the change is made through the front door
With a live session, the attacker opens the HR self service portal and edits the payment method: routing number, account number, sometimes account type. This is a supported feature, because employees change banks, close accounts and split deposits, and the form exists precisely so that can happen without a ticket.
Microsoft tracked a financially motivated actor it designates Storm-2657, described in reporting as "payroll pirate" activity, running this exact pattern against Workday tenants at United States universities in late 2025, working through the victims' own portals rather than deploying malware (Microsoft Security Blog). Universities are a rational target: large hourly and academic workforces, decentralised IT, high staff turnover, and self service portals that are deliberately easy to use.
Note what did not happen. No malicious binary, no exploit, no lateral movement. Endpoint detection has nothing to work with, because the activity is a series of HTTPS requests from an authenticated session doing exactly what that endpoint is documented to do.
Step three: the confirmation is silenced
Nearly every payroll platform emails the employee when payment details change. This is the control most organisations point to when asked how they would notice. It is also the easiest step in the chain to defeat, because the attacker holds the mailbox the alert is sent to.
An inbox rule that moves anything containing "direct deposit", "payment method" or the provider's sender address into an obscure folder, marked read, takes seconds to create through the mail client or the Graph API. In many incidents the rule is created before the change, so the alert never appears even momentarily. The alert was delivered. It was even, technically, read.
This is the load bearing insight of the whole attack. A notification sent into a compromised channel is not a control. It is a courtesy extended to the attacker.
Step four: wait for the pay cycle
The attacker then does nothing. The change sits in the record, indistinguishable from a legitimate one, until the next payroll run executes and the clearing house does exactly what it was told. The gap between change and discovery is not minutes, as in wire fraud. It is the length of a pay period, typically two weeks to a month.
That interval is why recovery rates are poor. The receiving account is a mule account opened in order to be closed. By payday the funds have been forwarded, withdrawn or converted, and the bank recall process begins by pointing at an empty account.
Why do email alerts, callbacks and MFA all fail here?
Look at the four steps together and a pattern appears. Every control the organisation deployed is positioned somewhere the attacker already has authority.
Here is a useful way to hold it. Imagine a bank decides cheques are risky, so before honouring one the teller phones the account holder. Sound? It depends entirely on where the number comes from. If the teller phones the number written on the cheque by whoever wrote it, the control is theatre, because the forger simply writes their own number. The signature was the real control all along, and it worked because producing it required something the forger did not have.
Payroll controls today are the phone number written on the cheque.
| Control | What it actually proves | How it is defeated |
|---|---|---|
| Login MFA | Someone completed an authentication ceremony at session start | The session token is stolen after the ceremony, or the ceremony itself is relayed |
| Email change alert | A message was delivered to a mailbox | The attacker controls the mailbox and creates a rule to hide it |
| Callback to a known number | Someone answered a number in the record | The record is editable by the attacker, and voice can be cloned |
| Waiting period before first payment | Time passed | Time passes for the attacker too, and the employee has no reason to look |
| Bank account validation API | The account exists and the name plausibly matches | Mule accounts are real accounts, often opened in a matching name |
| Signature over the change payload | This specific human approved these specific account numbers | Requires the enrolled device, which the attacker does not hold |
Read the "what it actually proves" column as a group. Every deployed control proves something about a channel, a timer, or an event. Only the last row proves something about a person and a decision.
What is Session-Inherited Authorization?
This failure has a shape that recurs across many expensive problems, and it deserves a name. We call it Session-Inherited Authorization: every action taken after login carries the authority established at login, without ever being independently authorised itself.
The hotel analogy is close enough to be useful. You show your passport once at the front desk, and you receive a key card. From then on the building does not ask who you are. It asks whether you hold a valid card. Steal the card and you inherit everything the guest could do, for as long as the card is valid, with no further identity check at any door.
Now make the analogy precise, because the precision is where the fix lives. A web session is that key card: once issued it is a bearer token, and whoever presents it is treated as the authenticated user. The payroll change endpoint checks the card. It does not, and under current designs cannot, check whether the human whose salary is about to be redirected intended any of this.
The distinction that matters is between authentication and authorization of an act. Authentication answers "who started this session". Authorization of an act answers "did this human deliberately approve this specific consequence". The identity industry has spent fifteen years improving the first question. The losses live in the second. We map fourteen variants of this gap in the Identity Failure Map.
How does a signature on the change stop it?
The fix is not another detector. It is a change in what the endpoint requires before it will persist the record.
Today the payroll platform asks whether the request carries a valid session. Instead it should ask whether the request carries a fresh cryptographic signature, produced by a key on a device enrolled to this employee, over a payload containing these exact account details.
That second question has a mathematical answer. It cannot be socially engineered, because there is no human in the loop to engineer. It cannot be satisfied by a stolen cookie, because a cookie is not a signing key. It cannot be satisfied by the attacker's own device, because that device is not enrolled to this employee.
What exactly gets signed
The signature must cover the consequential fields, not a random challenge and not a vague description. If the signature covers only "the user approved something", an attacker who can manipulate the request can change what that something was. So the canonical payload is explicit:
{
"action": "payroll.bank_details.update",
"employee_id": "e_88431",
"tenant": "acme-university",
"routing": "021000021",
"account_last4": "4417",
"account_hash": "sha256:9f2b...c41e",
"account_type": "checking",
"effective_date":"2026-09-15",
"prior_account_hash": "sha256:41ac...80d2",
"requested_at": "2026-09-04T10:42:07Z",
"nonce": "8f14e45fceea167a"
}
That object is serialised canonically, so every party computes identical bytes, then hashed. The hash becomes the challenge the employee's authenticator signs, and the device shows them the human readable version of those same fields first. What they see is what they sign. Two fields carry extra weight: prior_account_hash binds the change to the state it replaces, so a captured signature cannot be replayed against a different starting state, and nonce with requested_at make each signature single use and time boxed.
The gate, in about fifteen lines
The integration is a precondition on one endpoint, not architectural surgery:
async function updateBankDetails(req) {
const payload = canonicalize({
action: "payroll.bank_details.update",
employee_id: req.employee.id,
tenant: req.tenant,
routing: req.body.routing,
account_hash: sha256(req.body.account),
account_last4: req.body.account.slice(-4),
effective_date: req.body.effectiveDate,
prior_account_hash: sha256(req.employee.currentAccount),
requested_at: req.now,
nonce: req.nonce
});
const receipt = await manav.verify(req.body.receipt, {
subject: req.employee.manavId, // must be THIS employee
payloadHash: sha256(payload), // must cover THESE numbers
maxAgeSeconds: 300 // must be fresh
});
if (!receipt.valid) return deny("unsigned_change");
await payroll.persist(req.body, { receiptId: receipt.id });
await audit.append(receipt); // offline verifiable evidence
return ok();
}
Three assertions do the work. The receipt must belong to this employee, not any authenticated user. It must cover this payload hash, not a generic approval. It must be recent, not replayed. Fail one and the change is refused, however valid the session looks.
What the receipt is worth afterwards
The output is not just a yes or no at the moment of the change. It is a durable artefact: an Ed25519 signed object that verifies against a published key with no callback to any vendor, so an auditor in three years can confirm that a specific enrolled human approved specific account details at a specific time, without asking permission and without the vendor needing to still exist.
That property matters in three conversations that follow every incident: the audit conversation, where "an authenticated session did it" becomes "here is the employee's signature, or here is the refusal"; the insurance conversation, where a deterministic control on a named loss vector is a priceable fact; and the employment conversation, where a disputed change has cryptographic evidence behind it rather than a swearing contest. The developer docs cover the verification path, and the employee verification lab demonstrates the enrolled employee flow.
What does this feel like for the employee?
This is the question that decides whether the control survives contact with an HR director, so it deserves a straight answer rather than a reassurance.
An employee changing their bank details fills in the form as they always have. Before the save completes, their phone shows a prompt with the new routing number, the last four digits of the account, and the effective date. They confirm with the gesture that unlocks their phone. Total added time is fifteen to twenty seconds, once, on an action most employees perform less than once a year.
Compare that against the controls it replaces. A five day waiting period delays the employee's legitimate change. A callback requires an administrator to play telephone tag and produces a note that proves nothing. Awareness training costs everyone an hour and shifts blame onto a victim whose session was stolen. The friction here lands almost entirely on the attacker, who cannot complete the flow at all, which is the property worth optimising for.
Is an employer liable for a diverted paycheck?
This varies by jurisdiction and by employment agreement, and it is not legal advice, but the practical pattern is consistent enough to plan around. In most United States states, wage payment statutes obligate an employer to pay earned wages to the employee, and a payment sent to a fraudster because the employer's system accepted a fraudulent change is generally not treated as discharging that obligation. The employer usually pays again and pursues recovery separately.
The exposure does not stop at the wages: add the investigation, a possible wage claim if the employee is not made whole promptly, the reputational cost inside a workforce that now doubts its pay is safe, and rising compliance interest. The IRS has flagged payroll and human resources phishing in its Dirty Dozen list of tax scams (IRS Dirty Dozen), and NACHA's account validation rules for certain ACH entries have pushed verification up the agenda for anyone originating payments (NACHA Operating Rules).
The uncomfortable summary for a CFO: your organisation carries an uncapped, repeating liability on a workflow your security programme does not classify as a payment workflow at all.
Why is this getting worse right now?
Three changes are compounding.
First, session theft became cheap and commoditised. When stealing a session required skill, payroll portals were an inefficient target. Phishing as a service changed the economics, and the Tycoon 2FA disruption scattered the model rather than ending it. Second, attackers moved from the mailbox to the portal: rather than emailing HR and hoping a human complies, the attacker performs the change directly through self service, which means every control designed around "verify the request that arrives by email" is aimed at an attack that is no longer the primary one.
Third, and least discussed, human resources platforms are adding assistants that can execute profile changes from natural language instructions. Every such feature widens the set of paths that reach the change endpoint, and none of them changes what that endpoint requires. If the endpoint accepts a valid session as sufficient authority, then every new interface into it is a new way to exercise stolen authority. If the endpoint requires a signature, new interfaces are just new front ends onto the same locked door.
Honest limits
A control worth deploying is one whose weaknesses you can state precisely.
- Enrollment is the trust bottleneck. Someone, once, must bind a device key to the right human. If an attacker controls the onboarding moment, they control the key, and every downstream signature is theirs. Enrollment deserves in person or supervised verification for the first factor, and it is the correct place to concentrate scrutiny.
- It does not cover employees without a usable device. Some hourly and field workforces have low smartphone availability during work hours. Those populations need an alternative path: a supervised kiosk enrollment, a hardware security key issued with the badge, or an in person change process. Any alternative path is also the path an attacker will target, so it must be designed with the same care and used by exception.
- It does not stop a coerced or deceived employee. If someone is manipulated into signing a change to an account the fraudster controls, the signature is valid and the control holds the door open politely.
- It does not cover changes made by administrators on an employee's behalf. Payroll staff make corrections. Those paths need their own treatment, either by requiring the employee's signature regardless of who initiates, or by requiring a second administrator's signature with a recorded reason.
- A compromised enrolled device is still a compromised signer, and native human resources connectors do not exist yet, so integration today is through the API and the embeddable widget at the change endpoint rather than a one click marketplace install.
None of these limits returns you to where you started. The current control set fails against a commodity attack run by a stranger. The signature fails only against enrollment compromise, device compromise, or a complicit employee, which are all harder and rarer.
What to do this week
Concrete steps, in order of effort against payoff:
- Count your protected fields. List every payroll field that redirects money or mail: routing and account, payment method, tax withholding, cheque mailing address, expense reimbursement destination. That list is your real attack surface, and it is usually longer than expected.
- Pull ninety days of change history. Look for changes followed within a day by a mailbox rule creation, changes outside the employee's normal hours or geography, and repeat changes on one record. You are looking for incidents you have not noticed yet, and there is a reasonable chance you find one.
- Check where your confirmation alerts go. If the alert lands only in the mailbox the attacker would compromise, it is not a control. Add a channel the attacker cannot edit from inside the portal.
- Prohibit same session changes to notification targets and payment targets. If an attacker can change the phone number and the bank account in one sitting, every verification path is already theirs. This is a policy change your platform may support today.
- Gate the change endpoint on a signature. Start with a pilot population, typically finance, executives and anyone with elevated pay. Wire the widget into the change flow, store the receipt against the payroll change record, and require a valid receipt before the record persists.
- Replace the waiting period with receipt verification, then take the receipt to your insurer. Social engineering coverage is priced on controls, and a deterministic control on a named loss vector with offline verifiable evidence per change is an underwriting argument rather than a policy statement.
- Fix the administrator path last, but fix it. Every exception you leave open becomes the path of choice once the main door is locked.
Frequently asked questions
What is payroll diversion fraud? It is a form of business email compromise in which an attacker gains access to an employee's account or mailbox and changes the direct deposit details in the payroll system, redirecting that employee's salary to an account they control. The change is made through the normal self service interface, so it looks like ordinary activity and is typically discovered only when the employee is not paid.
Can multi factor authentication stop direct deposit fraud? Not on its own. Login MFA proves that an authentication ceremony was completed at the start of a session. Adversary in the middle phishing kits relay that ceremony and steal the resulting session token, so the attacker inherits the authenticated session without ever needing to defeat MFA. The change endpoint then sees a fully authenticated request. What is needed is a separate signature over the change itself.
Is an employer liable for a diverted paycheck? In most United States jurisdictions, wage payment statutes require the employer to pay earned wages to the employee, and a payment routed to a fraudster by the employer's own system is generally not treated as satisfying that obligation. Employers typically pay the employee again and pursue recovery separately, though specifics vary by state and by employment agreement. Take legal advice on your own situation.
What is Storm-2657? Storm-2657 is Microsoft's designation for a financially motivated threat actor associated with what has been described as payroll pirate activity, observed in late 2025 targeting human resources platforms including Workday tenants at United States universities. The notable feature is that the actor operated through victims' own self service portals using stolen sessions rather than deploying malware.
Do change confirmation emails and callbacks work? They work against a careless attacker and fail against a competent one. The confirmation email arrives in a mailbox the attacker controls and can be hidden with an inbox rule created in seconds. The callback often reaches a phone number stored in the same profile the attacker just edited. Both controls sit inside the channel the attacker owns.
Sources
- FBI Internet Crime Complaint Center, 2025 Internet Crime Report: business email compromise losses of $3.05 billion across 24,768 complaints, with 86 percent of losses moving by wire or ACH.
- FBI IC3 public service announcements: the 2019 payroll diversion announcement recording 1,053 complaints and $8,323,354 in reported losses between January 2018 and June 2019.
- Microsoft Security Blog: reporting on Storm-2657 payroll pirate activity against human resources platforms, and on the Tycoon 2FA adversary in the middle phishing service and its disruption.
- Internal Revenue Service, Dirty Dozen: the annual list of prominent tax related scams, including payroll and human resources phishing.
- NACHA Operating Rules: account validation requirements for certain ACH entries.
- NIST Special Publication 800-63B, Digital Identity Guidelines: authenticator and session management guidance, including the treatment of restricted authenticators such as SMS.
A notification sent into a compromised mailbox is not a control. It is a courtesy extended to the attacker.
This lesson is part of Proof of human intent, the guide to the whole problem area.