{
 "slug": "payroll-diversion-crisis-infostealer-malware-submits-unauthorized",
 "topic_id": "TOPIC-009",
 "cluster": "B2B Wire, AP & Treasury Payment Release",
 "tier": "Tier B",
 "title": "Payroll diversion: when the session is stolen, the HR portal cannot tell",
 "summary": "Infostealers harvest employee SSO sessions and change direct deposit details in the HR system. Detection sees a legitimate session from a plausible location and allows the edit.",
 "lede": "An employee's entire monthly income can be redirected by editing one field in a self-service portal, and the FBI has warned about this pattern for years. What changed is that the attacker no longer needs to phish the employee — they buy the session.",
 "date": "2024-09-25",
 "category": "Compliance",
 "author_id": "nadia-ferreira-strand",
 "tags": [
  "payroll diversion",
  "direct deposit fraud",
  "infostealer",
  "HRIS",
  "session theft",
  "employee self-service"
 ],
 "image_title": "Payroll Diversion Crisis",
 "schema": "Article",
 "key_takeaways": [
  "The FBI and state agencies have issued repeated advisories on payroll diversion. The mechanism has shifted from phishing the employee to replaying a stolen session.",
  "Detection based on IP, device and behaviour fails against a replayed session from residential egress, because every signal is the employee's own.",
  "Gate the direct deposit field specifically — one field, one gesture, applied at the point where the money moves."
 ],
 "body": [
  {
   "type": "h2",
   "text": "Prerequisites"
  },
  {
   "type": "diagram",
   "kind": "flow",
   "alt": "A stolen session changes the deposit account before payday",
   "caption": "No login occurs, so nothing in the authentication stack fires.",
   "nodes": [
    {
     "label": "Infostealer on the endpoint",
     "note": "commodity malware",
     "bad": true
    },
    {
     "label": "Session cookie exfiltrated",
     "note": "sold in bulk",
     "bad": true
    },
    {
     "label": "Replayed against the HR portal",
     "note": "no login, no MFA",
     "bad": true
    },
    {
     "label": "Deposit account changed",
     "note": "one field",
     "bad": true
    },
    {
     "label": "Discovered on payday",
     "note": "a full cycle later",
     "bad": true
    }
   ]
  },
  {
   "type": "ul",
   "items": [
    "Export of direct deposit changes from your HRIS for the last twelve months, with timestamp and initiating session.",
    "Your payroll calendar — specifically the cutoff date relative to payroll run.",
    "Whether your HRIS notifies on direct deposit change, to which address, and whether that address is also editable in self-service."
   ]
  },
  {
   "type": "h2",
   "text": "Step 1 — Map the window"
  },
  {
   "type": "p",
   "html": "The exposure is the interval between a change taking effect and someone noticing. Compute it from your own calendar."
  },
  {
   "type": "code",
   "text": "change made        →  day 0\npayroll cutoff     →  day 3    (change is picked up)\npayroll run        →  day 10\npay date           →  day 15\nemployee notices   →  day 15-17  (pay did not arrive)\n\nexposure window = 15-17 days, one full pay cycle"
  },
  {
   "type": "p",
   "html": "An attacker who times the change just before cutoff maximises the window and gets one full cycle. In organisations paying semi-monthly the window is shorter; monthly payrolls are the worst case."
  },
  {
   "type": "h2",
   "text": "Step 2 — Understand why detection fails here"
  },
  {
   "type": "p",
   "html": "The relevant advisories describe two variants. In the older one, the employee is phished and the attacker logs in with harvested credentials. In the current one, the attacker replays a session token taken by infostealer malware from the employee's device."
  },
  {
   "type": "p",
   "html": "The second defeats the detection stack completely."
  },
  {
   "type": "table",
   "head": [
    "Signal",
    "What it sees with a replayed session"
   ],
   "rows": [
    [
     "Authentication",
     "No login occurred; the session was already authenticated"
    ],
    [
     "MFA",
     "Not invoked — there was no authentication event"
    ],
    [
     "Device fingerprint",
     "Can be reproduced from the same infostealer output"
    ],
    [
     "IP geolocation",
     "Residential proxy in the employee's region"
    ],
    [
     "Behavioural analytics",
     "A single profile edit, which is not anomalous"
    ]
   ]
  },
  {
   "type": "p",
   "html": "There is no signal to detect, which is why detection-based controls have not moved this loss category despite years of advisories."
  },
  {
   "type": "h2",
   "text": "Step 3 — Check your notification path"
  },
  {
   "type": "p",
   "html": "Most HRIS platforms notify the employee when direct deposit details change. Verify two things:"
  },
  {
   "type": "ol",
   "items": [
    "Where the notification goes. If it goes to the work email and the attacker holds the SSO session, they likely hold the mailbox too.",
    "Whether the notification address is itself editable in self-service. If an attacker can change the email and then the bank details in one session, notification is worthless."
   ]
  },
  {
   "type": "p",
   "html": "Sending to a personal address on file, and prohibiting self-service edits to the notification address, costs nothing and closes the most common bypass."
  },
  {
   "type": "h2",
   "text": "Step 4 — Gate the field"
  },
  {
   "type": "p",
   "html": "One field, one gesture. The employee signs a canonical statement rendering the full new account and routing details before the change takes effect."
  },
  {
   "type": "code",
   "text": "{\n  \"type\": \"manav-stmt/1\",\n  \"action\": \"direct_deposit_change\",\n  \"render\": [\n    \"Employee: [name, id]\",\n    \"Current: [bank] — [full account] — [full routing]\",\n    \"New:     [bank] — [full account] — [full routing]\",\n    \"Allocation: [percentage or amount]\",\n    \"Effective: [first affected pay date]\"\n  ],\n  \"employee\": \"[credential assertion, user verification required]\"\n}"
  },
  {
   "type": "p",
   "html": "The session does not matter. The attacker holding it cannot produce an assertion from a credential on the employee's device."
  },
  {
   "type": "h2",
   "text": "Step 5 — Handle the exception path"
  },
  {
   "type": "p",
   "html": "Employees lose phones, change devices, and join without one. The HR service desk must be able to process a change, and that path is where an attacker will go next."
  },
  {
   "type": "ul",
   "items": [
    "Require the exception to be performed by a named HR representative signing an exception statement, not by any service desk agent.",
    "Apply a hold across at least one pay cycle boundary.",
    "Notify the previous account's associated address and the employee's personal address.",
    "Report the exception rate monthly. A concentration by representative or by region is the signal."
   ]
  },
  {
   "type": "h2",
   "text": "Failure traps"
  },
  {
   "type": "ol",
   "items": [
    "Gating login instead of the field. The session is already past login.",
    "Allowing the notification address to be changed in the same session as the bank details.",
    "Applying the gate to all HRIS profile edits, which produces resistance disproportionate to the benefit. One field.",
    "Forgetting contractors and contingent workers paid through the same system, who frequently sit outside the SSO population entirely."
   ]
  },
  {
   "type": "h2",
   "text": "Why this endpoint specifically"
  },
  {
   "type": "table",
   "caption": "What makes the deposit field attractive",
   "head": [
    "Property",
    "Effect"
   ],
   "rows": [
    [
     "Self-service by design",
     "No ticket, no approver, no second party"
    ],
    [
     "Low apparent stakes",
     "Treated as profile data, not as payment instructions"
    ],
    [
     "Delayed detection",
     "Discovered at the next pay run, up to a full cycle later"
    ],
    [
     "Repeatable",
     "One session can change several employees if the account has scope"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The remedy is not a better anomaly model. It is treating the deposit account as what it is — a payment instruction — and requiring a fresh, bound assertion to change it, plus a notification to a channel the session cannot reach."
  },
  {
   "type": "h2",
   "text": "Objections and honest limits"
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“We require MFA on the HR portal.”</strong> At login. The stolen session is post-login, which is exactly the gap. Step-up on the change endpoint is the control; MFA at sign-in is not."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“We email a confirmation of the change.”</strong> To an inbox the same session can usually reach. Send it out of band, and make the notification say what changed rather than that something changed."
  }
 ],
 "faq": [
  {
   "q": "Would MFA on the HRIS fix this?",
   "a": "It helps against credential phishing and does nothing against a replayed session, because no authentication event occurs."
  },
  {
   "q": "Why only the direct deposit field?",
   "a": "Because that is where the money moves. Gating every profile edit generates friction and resistance without proportionate benefit."
  },
  {
   "q": "What about employees without smartphones?",
   "a": "The exception path exists for them, with a named HR signer, a hold across a pay cycle and dual notification. It must be staffed rather than improvised."
  },
  {
   "q": "Does this apply to contractors?",
   "a": "If they are paid through the same system, yes — and they are frequently outside the SSO population, which means the gate has to be designed for them explicitly."
  },
  {
   "q": "Why doesn't MFA stop payroll diversion?",
   "a": "MFA runs at login. A stolen session is post-login, so no authentication event occurs and nothing is prompted."
  },
  {
   "q": "Why is detection so slow?",
   "a": "The change looks routine and the consequence only appears at the next pay run — potentially a full cycle later."
  },
  {
   "q": "What is the single best change?",
   "a": "Treat the deposit account as a payment instruction and require a fresh, bound assertion to alter it."
  }
 ],
 "sources": [
  {
   "t": "IRS Newsroom — payroll and W-2 phishing warnings",
   "u": "https://www.irs.gov/newsroom"
  },
  {
   "t": "CISA — protecting against session hijacking and infostealers",
   "u": "https://www.cisa.gov/news-events/cybersecurity-advisories"
  }
 ],
 "related": [
  {
   "slug": "clinical-action-gate-infostealers",
   "title": "Assume the credentials are already stolen",
   "category": "Comparison"
  },
  {
   "slug": "consequence-tiered-student-record",
   "title": "The refund destination field",
   "category": "Vertical"
  },
  {
   "slug": "payout-field-control",
   "title": "Marketplace seller payout redirection",
   "category": "Vertical"
  }
 ],
 "image": "https://cdn.twc.sh/images/igcache/Payroll%20Diversion%20Crisis/1500_900/blog.jpg",
 "wordcount": 999,
 "url": "/blog/payroll-diversion-crisis-infostealer-malware-submits-unauthorized.html",
 "reading_time": "4 min read",
 "seo_title": "Payroll diversion when the session is stolen",
 "meta_description": "Infostealers harvest SSO sessions and change direct deposit details. Detection sees a legitimate session from a plausible location.",
 "hub": {
  "slug": "topics/payment-release-authorization",
  "title": "Payment release authorization"
 },
 "answer": "Because the session is genuine. Infostealer malware lifts the employee's authenticated session from their browser, so the direct deposit change arrives from a valid session, a plausible location and a compliant device. There is no failed login and no MFA prompt, because no authentication happens.",
 "answer_q": "Why can't an HR portal tell a payroll diversion from a real change?",
 "glossary": [
  {
   "term": "Infostealer",
   "def": "Commodity malware that harvests credentials and session material from a host. Stolen sessions trade in bulk at low prices."
  },
  {
   "term": "Session replay",
   "def": "Using a stolen session token to act as the user without authenticating."
  },
  {
   "term": "Step-up",
   "def": "Requiring a fresh assertion at a specific action rather than relying on the session that opened earlier."
  }
 ],
 "checklist": {
  "title": "Hardening the deposit change",
  "id": "harden",
  "desc": "Four steps.",
  "steps": [
   {
    "name": "Classify the deposit field as a payment instruction.",
    "text": "Not profile data. Everything else follows from that."
   },
   {
    "name": "Require a fresh bound assertion to change it.",
    "text": "Rendering the old and new account, with user verification."
   },
   {
    "name": "Notify out of band, stating the change.",
    "text": "To a channel the session cannot reach."
   },
   {
    "name": "Hold the first pay run after a change.",
    "text": "A short hold costs the employee little and removes the attacker's window."
   }
  ]
 },
 "cta": {
  "title": "Where this fits in Manav",
  "html": "Manav renders the full payment or change details, binds the approver's signature to that exact payload, and produces a receipt an insurer, an auditor or a court can verify without calling anyone.",
  "href": "../docs.html",
  "label": "See payment gating"
 }
}