{
 "slug": "session-hijacking-via-infostealers-mfa-login-protect-post",
 "topic_id": "TOPIC-026",
 "cluster": "Privileged Identity & Help-Desk Takeover",
 "tier": "Tier B",
 "title": "Why MFA at login does not protect anything after login",
 "summary": "Multi-factor authentication establishes who opened the session. Everything consequential happens later, to a session token that can be copied off the machine.",
 "lede": "An employee authenticates at nine in the morning with a hardware key. By eleven, a session cookie lifted from their browser is being replayed from another continent, and no authentication event occurs because none is required.",
 "date": "2025-01-04",
 "category": "Developer",
 "author_id": "tobias-lindqvist-rao",
 "tags": [
  "session hijacking",
  "infostealers",
  "MFA",
  "token theft",
  "step-up authentication",
  "endpoint security"
 ],
 "image_title": "MFA Login Post Login Gap",
 "schema": "Article",
 "key_takeaways": [
  "MFA is an event at the session boundary. Actions taken during the session inherit its authority without re-establishing it.",
  "Infostealer malware targets session material directly, which sidesteps authentication entirely rather than defeating it.",
  "Binding a fresh assertion to the specific action makes a stolen session insufficient for the operations that matter."
 ],
 "body": [
  {
   "type": "h2",
   "text": "The architectural gap"
  },
  {
   "type": "diagram",
   "kind": "flow",
   "alt": "One morning, four actions, two of them stolen",
   "caption": "The strength of the 09:00 authentication does not reach 11:47.",
   "nodes": [
    {
     "label": "09:00 login with a hardware key",
     "note": "the human",
     "good": true
    },
    {
     "label": "09:00 session token issued",
     "note": "represents that"
    },
    {
     "label": "11:47 payment released",
     "note": "the token",
     "bad": true
    },
    {
     "label": "11:52 bank details changed",
     "note": "the token",
     "bad": true
    }
   ]
  },
  {
   "type": "p",
   "html": "Authentication answers a question once, at the start. A session token then represents that answer for hours."
  },
  {
   "type": "p",
   "html": "Everything of consequence — the payment release, the permission change, the data export — happens somewhere inside that window, authorised by the token rather than by the human. The strength of the original authentication does not reach that far."
  },
  {
   "type": "table",
   "head": [
    "Time",
    "Event",
    "What authorises it"
   ],
   "rows": [
    [
     "09:00",
     "Login with hardware key",
     "The human, with user verification"
    ],
    [
     "09:00",
     "Session token issued",
     "The successful authentication"
    ],
    [
     "11:47",
     "Payment of 84,000 released",
     "<strong style=\"font-weight:600\">The token</strong>"
    ],
    [
     "11:52",
     "Beneficiary bank details changed",
     "<strong style=\"font-weight:600\">The token</strong>"
    ]
   ]
  },
  {
   "type": "h2",
   "text": "How the token leaves the machine"
  },
  {
   "type": "p",
   "html": "Infostealer families are commodity malware with a narrow, well-optimised job: collect credentials and session material from a host and exfiltrate it. Browser cookie stores, token caches and credential managers are the primary targets."
  },
  {
   "type": "p",
   "html": "The economics are why this matters. Stolen sessions are traded in bulk at low prices, which means a token is worth stealing even when the account is unremarkable. Volume compensates for value."
  },
  {
   "type": "p",
   "html": "Note what is not happening: the attacker never authenticates. There is no failed login, no MFA prompt, no anomalous authentication event. The security control was never engaged."
  },
  {
   "type": "h2",
   "text": "Why the usual mitigations fall short"
  },
  {
   "type": "table",
   "head": [
    "Mitigation",
    "Effect",
    "Limit"
   ],
   "rows": [
    [
     "Shorter session lifetimes",
     "Narrows the window",
     "Tokens are used within minutes of theft; also degrades usability sharply"
    ],
    [
     "Device binding / token binding",
     "Real improvement",
     "Binds to the device — and the malware is on the device"
    ],
    [
     "IP and geolocation checks",
     "Catches lazy operators",
     "Defeated by proxying through the victim's network or a residential relay"
    ],
    [
     "Behavioural anomaly detection",
     "Catches some cases",
     "Probabilistic; the attacker is using a real session doing plausible things"
    ],
    [
     "Continuous access evaluation",
     "Useful",
     "Revokes on signal; the signal usually arrives after the action"
    ]
   ]
  },
  {
   "type": "p",
   "html": "Each of these is worth doing. None changes the underlying fact that the token, by design, carries authority the human is not present to exercise."
  },
  {
   "type": "h2",
   "text": "Re-establishing presence at the action"
  },
  {
   "type": "p",
   "html": "The fix is not a stronger session. It is refusing to let the session alone authorise the operations that matter."
  },
  {
   "type": "code",
   "text": "def release_payment(request, payment):\n    # The session identifies the caller. It does not authorise this.\n    stmt = canonical({\n        \"action\": \"payment.release\",\n        \"beneficiary\": payment.beneficiary_name,\n        \"account\": mask(payment.account),   # last four only\n        \"amount\": payment.amount,\n        \"currency\": payment.currency,\n    })\n    digest = sha256(stmt)\n\n    assertion = request.assertion\n    verify(assertion.signature, credential_for(request.user))\n    require(assertion.challenge == digest)      # bound to THIS payment\n    require(assertion.user_verified)            # biometric or PIN, now\n    require(now() - assertion.issued < 120)     # fresh\n\n    execute(payment)"
  },
  {
   "type": "p",
   "html": "An attacker holding the session can reach this endpoint. They cannot produce the assertion, because it requires the authenticator and a user-verification gesture on the real employee's device."
  },
  {
   "type": "h2",
   "text": "Choosing where to apply it"
  },
  {
   "type": "p",
   "html": "Not everywhere. Prompting on every request would be unusable and would train people to approve reflexively, which destroys the control's value."
  },
  {
   "type": "ul",
   "items": [
    "Money movement and changes to where money goes",
    "Permission and role changes, particularly self-elevation",
    "Bulk data export",
    "Credential enrolment and recovery",
    "Destructive operations on production systems"
   ]
  },
  {
   "type": "p",
   "html": "In most enterprise applications that is a list of ten to thirty endpoints. It is findable in a day by grepping for the operations that write irreversibly."
  },
  {
   "type": "h2",
   "text": "The endpoint-hygiene objection"
  },
  {
   "type": "p",
   "html": "Someone will point out that if the machine is compromised, the attacker could wait and hijack the assertion at the moment the user approves something."
  },
  {
   "type": "p",
   "html": "That is true and it is a much harder attack: it requires presence on the device at the right moment, and it yields exactly one action rather than a session's worth. More importantly, the assertion is bound to a specific rendered effect, so the attacker gets the action the user meant to take, not one of their own choosing — unless they can also control what was displayed, which is a deeper compromise than cookie theft."
  },
  {
   "type": "p",
   "html": "Raising the cost from \"buy a stolen cookie for a few dollars\" to \"maintain interactive presence on a specific endpoint and defeat the rendering path\" is a real change in the threat model, not a rhetorical one."
  },
  {
   "type": "h2",
   "text": "Why the usual mitigations fall short"
  },
  {
   "type": "table",
   "caption": "Each helps; none closes it",
   "head": [
    "Mitigation",
    "Limit"
   ],
   "rows": [
    [
     "Shorter sessions",
     "Stolen tokens are used within minutes; aggressive timeouts push users to workarounds"
    ],
    [
     "Device binding",
     "Binds to the device — and the malware is on the device"
    ],
    [
     "Geolocation checks",
     "Defeated by proxying through the victim's network"
    ],
    [
     "Behavioural detection",
     "Probabilistic; the attacker is doing plausible things in a real session"
    ],
    [
     "Continuous access evaluation",
     "Revokes on signal, and the signal usually arrives after the action"
    ]
   ]
  },
  {
   "type": "h2",
   "text": "Objections and honest limits"
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“If the endpoint is compromised, nothing helps.”</strong> The attacker must then be present at the moment of approval and gets one action, bound to what the user was shown. That is a far higher bar than replaying a purchased cookie."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“How many endpoints need this?”</strong> Ten to thirty in a typical enterprise application — money movement, permission changes, bulk export, credential enrolment, destructive operations. Findable in a day by grepping for irreversible writes."
  }
 ],
 "faq": [
  {
   "q": "Is MFA still worth deploying?",
   "a": "Yes. It closes credential stuffing and password phishing, which remain high-volume. It simply does not address theft of the session that MFA produced."
  },
  {
   "q": "Won't shorter sessions fix this?",
   "a": "Marginally. Stolen tokens are typically used within minutes, and aggressive timeouts push users toward workarounds that are worse."
  },
  {
   "q": "How many endpoints need step-up?",
   "a": "Usually ten to thirty in an enterprise application — money movement, permission changes, bulk export, credential enrolment, destructive operations."
  },
  {
   "q": "What if the endpoint is fully compromised?",
   "a": "The attacker must be present at the moment of approval and gets one action, bound to what the user was shown. That is a far higher bar than replaying a purchased cookie."
  }
 ],
 "sources": [
  {
   "t": "CISA — Implementing phishing-resistant MFA",
   "u": "https://www.cisa.gov/resources-tools/resources/implementing-phishing-resistant-mfa"
  },
  {
   "t": "CISA — protecting against session hijacking and infostealers",
   "u": "https://www.cisa.gov/news-events/cybersecurity-advisories"
  },
  {
   "t": "OpenID Continuous Access Evaluation Profile",
   "u": "https://openid.net/specs/openid-caep-specification-1_0.html"
  },
  {
   "t": "W3C Web Authentication: An API for accessing Public Key Credentials Level 3",
   "u": "https://www.w3.org/TR/webauthn-3/"
  }
 ],
 "related": [
  {
   "slug": "scattered-spider-help-desk-mfa-reset-prevention",
   "title": "Making help-desk MFA resets social-engineering-proof",
   "category": "AEO"
  },
  {
   "slug": "illusion-zero-trust-network-microsegmentation-fails-against",
   "title": "The illusion of Zero Trust",
   "category": "Developer"
  },
  {
   "slug": "human-middle-hitm-attack-passkeys-phishing-proxies",
   "title": "Phishing proxies and passkeys",
   "category": "Developer"
  },
  {
   "slug": "payroll-diversion-crisis-infostealer-malware-submits-unauthorized",
   "title": "Payroll diversion when the session is stolen",
   "category": "Compliance"
  }
 ],
 "image": "https://cdn.twc.sh/images/igcache/MFA%20Login%20Post%20Login%20Gap/1500_900/blog.jpg",
 "wordcount": 603,
 "url": "/blog/session-hijacking-via-infostealers-mfa-login-protect-post.html",
 "reading_time": "3 min read",
 "hub": {
  "slug": "topics/privileged-identity",
  "title": "Privileged identity and account recovery"
 },
 "answer": "No. MFA is an event at the session boundary; everything consequential happens inside the session, authorised by a token. Infostealers lift that token from the browser, so the attacker never authenticates and no authentication event ever fires.",
 "answer_q": "Does MFA protect anything after login?",
 "glossary": [
  {
   "term": "Infostealer",
   "def": "Commodity malware harvesting credentials and session material, traded in bulk at low prices."
  },
  {
   "term": "Session token",
   "def": "A bearer credential representing an earlier authentication, valid for hours."
  },
  {
   "term": "Step-up",
   "def": "A fresh assertion required at a specific action rather than relying on the session."
  }
 ],
 "checklist": {
  "title": "Finding your step-up set",
  "id": "stepup",
  "desc": "Four steps.",
  "steps": [
   {
    "name": "Grep for irreversible writes.",
    "text": "Money, permissions, bulk export, credential changes, destructive operations."
   },
   {
    "name": "Bind the assertion to the action.",
    "text": "The challenge is a digest of the rendered effect."
   },
   {
    "name": "Require freshness and user verification.",
    "text": "Under two minutes, biometric or PIN."
   },
   {
    "name": "Leave everything else alone.",
    "text": "Prompting on every request trains reflexive approval."
   }
  ]
 },
 "cta": {
  "title": "Where this fits in Manav",
  "html": "Manav requires a fresh assertion bound to the specific action, from a credential under the person's sole control. A stolen session reaches the endpoint and cannot produce it.",
  "href": "../docs.html",
  "label": "See step-up gating"
 }
}