Hacker DirectoryHacker Directory

WEB / WEB-14.04

Trust assumptions behind MFA

Two screens or two secrets do not necessarily mean two independent factors. Follow the MFA decision through challenges, account binding, and assurance state.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Independent factor accepted

  1. First factor complete; MFA pending

    The Application receives a verified first-factor result for this attempt. The Browser has neither completed MFA context nor a sensitive-action result yet; acceptance conditions for the second factor remain pending.

    Browser / Duru
    No completed MFA context
    Application verifier
    Primary verified; MFA pending
    Factor and challenge records
    Enrolled factor bound to subject-duru
  2. Pending challenge created

    Within the same process, the Application binds challenge-ledger-a to attempt-duru-a, subject-duru, factorRef and purpose=mfa-login. Creating a pending record does not complete MFA; the Browser has not received the prompt either.

    Browser / Duru
    No completed MFA context
    Application verifier
    Challenge issued
    Factor and challenge records
    challenge-ledger-a: pending
  3. Challenge prompt reached the Browser

    The response contains a challenge alias/prompt, not OTP output.

    Browser / Duru
    Prompt for challenge-ledger-a
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  4. Factor input prepared

    Enrolled-device output is represented by an alias; this step is local in the Browser with no actual device wire.

    Browser / Duru
    Output alias ready
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  5. Completion request arrived

    The completion request reached the Application with its output alias and attempt reference. While the Browser waits, the verifier will evaluate this attempt’s pending record and account binding; request arrival alone is not MFA acceptance.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Completion received; not accepted yet
    Factor and challenge records
    challenge-ledger-a: pending
  6. Verification and lifecycle gate

    For this attempt, firstFactorVerified, distinctFactors, factorBoundToSubject, purposeMatches, outputMatches, unused, withinLifetime and attemptAllowed are all true. The Application consumes the pending challenge once: afterState=consumed and mfaEstablished=true. The Browser has not received the result yet.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Accepted: challenge consumed
    Factor and challenge records
    challenge-ledger-a: consumed
  7. Terminal decision at the Browser

    The Browser received the completed MFA-context result. It belongs only to attempt-duru-a and mfa-login; session-cookie issuance and sensitive-action object/action permission are evaluated separately.

    Browser / Duru
    MFA context complete
    Application verifier
    Accepted: challenge consumed
    Factor and challenge records
    challenge-ledger-a: consumed

Lifetime expired

  1. First factor complete; MFA pending

    The Application receives a verified first-factor result for this attempt. The Browser has neither completed MFA context nor a sensitive-action result yet; acceptance conditions for the second factor remain pending.

    Browser / Duru
    No completed MFA context
    Application verifier
    Primary verified; MFA pending
    Factor and challenge records
    Enrolled factor bound to subject-duru
  2. Pending challenge created

    Within the same process, the Application binds challenge-ledger-a to attempt-duru-a, subject-duru, factorRef and purpose=mfa-login. Creating a pending record does not complete MFA; the Browser has not received the prompt either.

    Browser / Duru
    No completed MFA context
    Application verifier
    Challenge issued
    Factor and challenge records
    challenge-ledger-a: pending
  3. Challenge prompt reached the Browser

    The response contains a challenge alias/prompt, not OTP output.

    Browser / Duru
    Prompt for challenge-ledger-a
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  4. Factor input prepared

    Enrolled-device output is represented by an alias; this step is local in the Browser with no actual device wire.

    Browser / Duru
    Output alias ready
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  5. Completion request arrived

    The completion request reached the Application with its output alias and attempt reference. While the Browser waits, the verifier will evaluate this attempt’s pending record and account binding; request arrival alone is not MFA acceptance.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Completion received; not accepted yet
    Factor and challenge records
    challenge-ledger-a: pending
  6. Verification and lifecycle gate

    Although the output predicate passes, withinLifetime=false. The Application does not extend the challenge: afterState=expired and mfaEstablished=false remain. Other positive predicates cannot compensate for the lifetime boundary; completed assurance is withheld.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Denied: lifetime expired
    Factor and challenge records
    challenge-ledger-a: expired
  7. Terminal decision at the Browser

    The Browser received rejection for lifetime expiry. No completed MFA context or sensitive-action result was delivered; a matching output does not reopen this expired challenge. A new challenge must follow its own policy.

    Browser / Duru
    No completed MFA context
    Application verifier
    Denied: lifetime expired
    Factor and challenge records
    challenge-ledger-a: expired

Same factor · deny

  1. First factor complete; MFA pending

    The Application receives a verified first-factor result for this attempt. The Browser has neither completed MFA context nor a sensitive-action result yet; acceptance conditions for the second factor remain pending.

    Browser / Duru
    No completed MFA context
    Application verifier
    Primary verified; MFA pending
    Factor and challenge records
    Enrolled factor bound to subject-duru
  2. Pending challenge created

    Within the same process, the Application binds challenge-ledger-a to attempt-duru-a, subject-duru, factorRef and purpose=mfa-login. Creating a pending record does not complete MFA; the Browser has not received the prompt either.

    Browser / Duru
    No completed MFA context
    Application verifier
    Challenge issued
    Factor and challenge records
    challenge-ledger-a: pending
  3. Challenge prompt reached the Browser

    The response contains a challenge alias/prompt, not OTP output.

    Browser / Duru
    Prompt for challenge-ledger-a
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  4. Factor input prepared

    A second knowledge input is prepared as an alias; it does not create a distinct possession-factor result.

    Browser / Duru
    Knowledge response alias ready
    Application verifier
    Waiting for completion
    Factor and challenge records
    challenge-ledger-a: pending
  5. Completion request arrived

    The completion request reached the Application with its output alias and attempt reference. While the Browser waits, the verifier will evaluate this attempt’s pending record and account binding; request arrival alone is not MFA acceptance.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Completion received; not accepted yet
    Factor and challenge records
    challenge-ledger-a: pending
  6. Verification and lifecycle gate

    The first and second factors are both knowledge, so distinctFactors=false. Even with outputMatches=true, the Application does not accept two knowledge results as MFA: afterState=rejected and mfaEstablished=false remain.

    Browser / Duru
    Waiting for final decision
    Application verifier
    Denied: same factor category
    Factor and challenge records
    challenge-ledger-a: rejected
  7. Terminal decision at the Browser

    The Browser received rejection for the repeated factor category. No completed MFA context or sensitive-action result was delivered; two successful knowledge prompts do not supply the required knowledge-plus-possession composition.

    Browser / Duru
    No completed MFA context
    Application verifier
    Denied: same factor category
    Factor and challenge records
    challenge-ledger-a: rejected

ACTORS · STATE · DATA FLOW

Duru passed the password check; authentication is not complete

Atlas receives Duru’s password result for an action requiring another factor. The verified subject from WEB-14.01 is the first-stage input. The Application does not set mfaComplete=true yet: it must verify that another authenticator is bound to this account and produced the required result for this attempt.

The normal fixture follows authAttempt=attempt-duru-a, subject=subject-duru, and factorRef=otp-device-a. These are correlation aliases. A pending challenge withholds the sensitive action; passing the password stage does not deliver the second-stage protected capability to the Browser.

Factor count is not prompt count

Knowledge, possession, and inherence are different factor types. A password followed by another password or centrally checked PIN repeats the knowledge category. Password plus proof of authenticator possession can use different categories. Correct binding to the same account and resistance to replacement through one weak recovery path remain separate requirements.

A single authenticator can be multi-factor: a device PIN or biometric activation can unlock use of its private key. The activation secret need not be sent to the server as another password. Biometrics alone are not an authenticator under the NIST model; their relationship to a physical authenticator matters. Location and IP reputation are risk signals rather than substitutes for factors.

Challenge lifecycle: issue, verify, consume

The Application associates challenge-ledger-a with an attempt, subject, factor, and purpose=mfa-login. The alias returned to the Browser is not an OTP; enrolled-authenticator output is represented only by OTP_RESPONSE_ALIAS. OutputMatches=true is a supplied input standing for a trusted verification result.

Acceptance is a conjunction: firstFactorVerified, distinctFactors, factorBoundToSubject, purposeMatches, outputMatches, unused, withinLifetime, and attemptAllowed must all be true. Acceptance consumes the challenge and completes assurance for that attempt. Atomic consumption prevents concurrent completions from independently using the same pending record; storage may be in process or shared.

In the expired branch, an apparently correct output does not change withinLifetime=false. In the same-factor branch, outputMatches=true cannot overcome distinctFactors=false. These outcomes explain independent acceptance conditions rather than secret-guessing success.

OTP, push, and WebAuthn protect different phishing boundaries

MFA can reduce the effect of password disclosure without making every MFA protocol phishing-resistant. NIST uses that term for a protocol property that prevents valid authenticator output reaching an impostor verifier without depending on user vigilance. Manual OTP entry lacks that verifier binding; WebAuthn can provide verifier name binding.

Push approval depends on user intent and the request being approved. Rate limits, clear context, and number matching can reduce mistaken approval; a push screen alone does not establish WebAuthn-style cryptographic origin binding. This lesson models OTP lifecycle, not push delivery, WebAuthn signatures, or measured AAL compliance.

Phishing-resistant authentication does not automatically secure subsequent session use or correct resource permissions. WEB-13.03 completes the session lifecycle, while WEB-14.S02 develops recovery and credential-association boundaries.

2. Red · Trust & Impact

Read every scenario without motion

Same factor type

  1. The attempt context was separated

    subject-duru, attempt-duru-a and challenge-ledger-a define this decision scope. The response alias is not an actual OTP code; output matching does not establish a global MFA flag.

    Attempt context
    case=same-factor
    Factor gate
    Factor not evaluated
    Assurance decision
    MFA not established
  2. The first-factor outcome was preserved

    firstFactorVerified=true is supplied. The primary factor is knowledge; this one outcome does not complete all authentication-assurance conditions.

    Attempt context
    case=same-factor
    Factor gate
    Primary knowledge verified
    Assurance decision
    MFA not established
  3. The second-factor gate was read

    A knowledge secondary factor gives distinctFactors=false. Two knowledge challenges do not become an independent knowledge-plus-possession pair under this policy.

    Attempt context
    case=same-factor
    Factor gate
    distinctFactors=false
    Assurance decision
    MFA not established
  4. Binding conditions were kept separate

    True subject, purpose, output, unused and attemptAllowed predicates do not compensate for failed distinctFactors. The conditions remain bound to the same attempt.

    Attempt context
    case=same-factor
    Factor gate
    Failed gate retained
    Assurance decision
    MFA not established
  5. Assurance was not elevated

    mfaEstablished=false and afterState=rejected remain. A completed label in the browser cannot change this server decision.

    Attempt context
    case=same-factor
    Factor gate
    afterState=rejected
    Assurance decision
    mfaEstablished=false
  6. The rejection reason was not broadened

    Rejecting the same factor type does not make knowledge invalid for every use; this MFA-composition condition was not satisfied.

    Attempt context
    case=same-factor
    Factor gate
    Composition denial
    Assurance decision
    No elevated assurance

Expired challenge

  1. The attempt context was separated

    subject-duru, attempt-duru-a and challenge-ledger-a define this decision scope. The response alias is not an actual OTP code; output matching does not establish a global MFA flag.

    Attempt context
    case=expired
    Factor gate
    Factor not evaluated
    Assurance decision
    MFA not established
  2. The first-factor outcome was preserved

    firstFactorVerified=true is supplied. The primary factor is knowledge; this one outcome does not complete all authentication-assurance conditions.

    Attempt context
    case=expired
    Factor gate
    Primary knowledge verified
    Assurance decision
    MFA not established
  3. The second-factor gate was read

    The secondary factor is possession with distinctFactors=true, but withinLifetime=false. A correct output does not extend an expired challenge.

    Attempt context
    case=expired
    Factor gate
    withinLifetime=false
    Assurance decision
    MFA not established
  4. Binding conditions were kept separate

    True subject, purpose, output, unused and attemptAllowed predicates do not compensate for failed withinLifetime. The conditions remain bound to the same attempt.

    Attempt context
    case=expired
    Factor gate
    Failed gate retained
    Assurance decision
    MFA not established
  5. Assurance was not elevated

    mfaEstablished=false and afterState=expired remain. A completed label in the browser cannot change this server decision.

    Attempt context
    case=expired
    Factor gate
    afterState=expired
    Assurance decision
    mfaEstablished=false
  6. The rejection reason was not broadened

    An expired response can result from a benign delay. This reason is not evidence of a malicious actor; new challenges and recovery follow their own policies.

    Attempt context
    case=expired
    Factor gate
    Lifetime denial
    Assurance decision
    No elevated assurance

ASSUMPTION · BOUNDARY · CONTROL

A verified output cannot authorize the wrong attempt

Normal operation binds enrolled-authenticator output to Duru’s pending attempt. Turning an isolated “output correct” boolean into a global MFA flag loses subject, purpose, and lifecycle relationships. The potential effect is elevated assurance assigned to an incorrect or stale context.

The blocking control evaluates the pending attempt record alongside trusted account binding and lifetime. A challenge reference and decision reason can explain the result without logging the output. A completed label in the Browser cannot replace the server decision.

Independence must survive recovery and fallback

The benefit of multiple factors does not depend only on normal-login prompts. If factor replacement or an alternative API skips the assurance gate, authenticated state can be established under that weaker path’s conditions. Scope is the affected account and granted session/action authority, not automatic access to every resource.

Make fallback an explicit policy with an allowed method, required proof, and limited recovery capability. Support users who lose a factor without removing an enrolled factor solely because a session exists. Normal use, device migration, and incident recovery are different cases.

3. Blue · Secure development & defense

Read every scenario without motion

Assurance record

  1. The assurance-audit scope was selected

    An audit example produced by the Application’s normal decision was selected. This review covers the selector’s distinctFactors, lifetimeValid, purposeMatched and challengeState fields; it contains no actual authenticator output.

    Assurance audit
    normal assurance: full record
    Challenge review
    Audit not examined
    Integrity conclusion
    No integrity conclusion
  2. Attempt and purpose were correlated

    mfaEstablished=true belongs to attempt-duru-a and purpose mfa-login. This assurance is not automatically carried as permission for another action or account.

    Assurance audit
    normal assurance: full record
    Challenge review
    Purpose matched; attempt scope
    Integrity conclusion
    No integrity conclusion
  3. Factor independence was read

    The normal branch uses knowledge plus possession with distinctFactors=true. Review compares factor type and account binding rather than merely counting successful prompts.

    Assurance audit
    normal assurance: full record
    Challenge review
    Distinct factors=true
    Integrity conclusion
    No integrity conclusion
  4. The terminal challenge outcome was separated

    challengeState=consumed records the one-time decision for this attempt. Terminal state can be correlated without storing the output value in the audit.

    Assurance audit
    normal assurance: full record
    Challenge review
    Challenge consumed
    Integrity conclusion
    No integrity conclusion
  5. Lifetime evidence was sought

    lifetimeValid=true is present in the full record, allowing the integrity predicate to be evaluated with distinctFactors and purpose.

    Assurance audit
    normal assurance: full record
    Challenge review
    Lifetime valid=true
    Integrity conclusion
    Complete predicate can be read
  6. The audit conclusion closed in scope

    The main example has integrity count=0 for the four recorded conditions; a separate same-factor positive fixture gives count=1. This narrow result does not prove unrecorded output verification and account-binding checks or recovery adequacy.

    Assurance audit
    normal assurance: full record
    Challenge review
    Fixture integrity consistent
    Integrity conclusion
    Four selected conditions consistent

Missing lifetime

  1. The assurance-audit scope was selected

    This branch examines fields other than lifetimeValid of the normal assurance record. Observation uses decision fields rather than actual authenticator output.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Audit not examined
    Integrity conclusion
    No integrity conclusion
  2. Attempt and purpose were correlated

    mfaEstablished=true belongs to attempt-duru-a and purpose mfa-login. This assurance is not automatically carried as permission for another action or account.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Purpose matched; attempt scope
    Integrity conclusion
    No integrity conclusion
  3. Factor independence was read

    The normal branch uses knowledge plus possession with distinctFactors=true. Review compares factor type and account binding rather than merely counting successful prompts.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Distinct factors=true
    Integrity conclusion
    No integrity conclusion
  4. The terminal challenge outcome was separated

    challengeState=consumed records the one-time decision for this attempt. Terminal state can be correlated without storing the output value in the audit.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Challenge consumed
    Integrity conclusion
    No integrity conclusion
  5. Lifetime evidence was sought

    lifetimeValid is not supplied in this review. Missing is not false; an empty selector result cannot prove the lifetime control passed.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Lifetime evidence missing
    Integrity conclusion
    UNKNOWN: assurance integrity
  6. The audit conclusion closed in scope

    This partial record does not support a clean assurance conclusion. Lifetime evidence must come from its trusted source; event absence is not promoted to actor attribution or MFA-failure evidence.

    Assurance audit
    normal assurance: lifetime omitted
    Challenge review
    Incomplete coverage
    Integrity conclusion
    UNKNOWN: lifetime gate

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Observe attempt, factor, and terminal outcome together

Sanitized audit emitted at the Application’s challenge issue/verify/consume decisions differs from observing a Browser prompt. attemptRef, subjectRef, factorType, purposeMatched, challengeState, lifetimeValid, and mfaEstablished belong to our instructional schema, not an existing product’s SIEM fields.

The artifact XPath checks four recorded conditions where mfaEstablished=true: distinctFactors, lifetimeValid, purposeMatched and challengeState=consumed. The main fixture contains no inconsistency among those fields and selects zero rows; a separate positive fixture with distinctFactors=false selects one. This count does not verify unrecorded checks such as output verification or account binding. Missing fields or events do not establish clean assurance, and the selector does not diagnose an account attack.

An accessible rollout and recovery inventory

Start policy changes with an account/factor inventory: enrolled methods, migration, accessibility needs, and fallback ownership must be understood. Lost devices, delayed output, and cancelled prompts are normal failures; rejection alone is not evidence of malice.

Compare the accepted, expired, and same-factor fixtures at the withholding/allow boundary. Established provider/library behavior, independent notification, and recovery need their own assessment in production; users need a way out of permanent lockout.

Make assurance elevation a server decision

Bind provider or library authenticator-verification results to the account’s enrolled factor and this authentication attempt. Two passwords are not two independent factors; the chosen assurance policy defines acceptable combinations. In this example, subject, purpose, lifetime and unused challenge state must pass before mfaEstablished is granted. Make challenge consumption and assurance elevation one consistent state transition; an unavailable verification service cannot be replaced by a successful-looking Browser prompt.

For an OTP flow, enforce a short lifetime, attempt limits and single use of successful output under the provider contract; acceptance must not leave reusable state. The normal accepted branch should establish assurance; expired and same-factor branches must withhold protected results. Missing account-binding or verifier-outcome evidence is not clean assurance. Design safe approval and notification for factor replacement and recovery independently of merely holding a session; timeout or reset must not silently reduce required authentication strength.

NOW APPLY IT TO THE CASE

Which attempt, factors and lifetime bind an MFA result?

MFA assurance depends on subject, purpose, distinct factors and challenge state as well as matching output. Missing audit fields are not a clean result.

Separate decisions for verified actor, tenant relation and requested action in the case. Do not substitute authentication or proof success for object permission.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

MFA challenge/result lifecycle

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "subject": "subject-duru",
  "attemptRef": "attempt-duru-a",
  "challengeRef": "challenge-ledger-a",
  "responseAlias": "OTP_RESPONSE_ALIAS_NOT_A_CODE",
  "primaryFactor": "knowledge",
  "purpose": "mfa-login",
  "rows": [
    {
      "case": "normal",
      "firstFactorVerified": true,
      "distinctFactors": true,
      "factorBoundToSubject": true,
      "purposeMatches": true,
      "outputMatches": true,
      "unused": true,
      "withinLifetime": true,
      "attemptAllowed": true,
      "mfaEstablished": true,
      "afterState": "consumed",
      "secondaryFactor": "possession",
      "factorRef": "otp-device-a",
      "responseAlias": "OTP_RESPONSE_ALIAS_NOT_A_CODE"
    },
    {
      "case": "expired",
      "firstFactorVerified": true,
      "distinctFactors": true,
      "factorBoundToSubject": true,
      "purposeMatches": true,
      "outputMatches": true,
      "unused": true,
      "withinLifetime": false,
      "attemptAllowed": true,
      "mfaEstablished": false,
      "afterState": "expired",
      "secondaryFactor": "possession",
      "factorRef": "otp-device-a",
      "responseAlias": "OTP_RESPONSE_ALIAS_NOT_A_CODE"
    },
    {
      "case": "same-factor",
      "firstFactorVerified": true,
      "distinctFactors": false,
      "factorBoundToSubject": true,
      "purposeMatches": true,
      "outputMatches": true,
      "unused": true,
      "withinLifetime": true,
      "attemptAllowed": true,
      "mfaEstablished": false,
      "afterState": "rejected",
      "secondaryFactor": "knowledge",
      "factorRef": "second-knowledge-factor-a",
      "responseAlias": "KNOWLEDGE_RESPONSE_ALIAS_ONLY"
    }
  ],
  "selector": {
    "language": "XPath",
    "xml": "<audit><attempt mfaEstablished=\"true\" distinctFactors=\"true\" lifetimeValid=\"true\" purposeMatched=\"true\" challengeState=\"consumed\"/></audit>",
    "xpath": "count(/audit/attempt[@mfaEstablished=\"true\" and (@distinctFactors=\"false\" or @lifetimeValid=\"false\" or @purposeMatched=\"false\" or @challengeState!=\"consumed\")])",
    "expected": 0,
    "positiveFixtureXml": "<audit><attempt mfaEstablished=\"true\" distinctFactors=\"false\" lifetimeValid=\"true\" purposeMatched=\"true\" challengeState=\"consumed\"/></audit>",
    "positiveExpected": 1,
    "scope": "Local assurance-integrity evidence only; no OTP/device verification or multi-host ordering.",
    "missingFieldBehavior": "Selection requires declared fields. Missing fields mean insufficient evidence; a zero count does not prove control efficacy."
  },
  "normalSecondaryFactor": "possession"
}
attemptRef / subject / challengeRef
Correlation aliases bind the decision to one attempt, account, and pending record.
outputMatches / unused / withinLifetime
Supplied verification and lifecycle predicates rather than output bytes or clock measurements.
distinctFactors / mfaEstablished
Repeating a factor category does not add a factor; completion requires every acceptance gate.
selector
Authored XML integrity selection; a missing field provides insufficient evidence.

Fixed aliases are not secrets. Cryptography, device output, email/push delivery, session issuance, and AAL compliance are not implemented; first-factor success and second-verification predicates are supplied inputs.

Two reality checks

Two password prompts automatically provide MFA.

Repeating knowledge does not create two independent factors; categories and account binding need separate checks.

Every OTP or push approval is phishing-resistant authentication.

MFA and phishing resistance are different properties; the protocol must provide verifier binding.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

A knowledge primary factor is followed by a verified second knowledge factor. Is selected MFA established?

  1. No; distinctFactors=false.
  2. Yes; any two successful prompts automatically constitute MFA.
Read the explained answer

No; distinctFactors=false. — In the same-factor row, outputMatches is true but the required factor-diversity gate fails.

Does a matching output complete an expired challenge?

Selected lesson artifact fields; teaching example

rows[1].outputMatches
true
rows[1].withinLifetime
false
rows[1].mfaEstablished
false
rows[1].afterState
expired
  1. Yes; lifetime policy is irrelevant when the response matches.
  2. No; an expired challenge produces no MFA context.
Read the explained answer

No; an expired challenge produces no MFA context. — WithinLifetime=false closes the gate despite the other true conditions; afterState is expired.

The normal possession challenge was consumed. Why does this establish neither phishing resistance nor permission for every sensitive action?

Read the explained answer

The selected fixture establishes MFA context using knowledge+possession and lifetime/purpose checks; it executes no actual OTP/device verification. An OTP-style factor alone is not proof of verifier-name binding or a phishing-resistant protocol. Completed MFA assurance does not automatically grant user/object/action authorization or action-specific reauthentication policy.

□ I separated MFA context from phishing resistance.

□ I did not count completed MFA as a blanket action grant.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope