Skip to content

[Security] High: Private options can disable OAuth state validation and enable login CSRF / session swapping #2786

@parasol-aser

Description

@parasol-aser

Severity: High

CWE: CWE-352 (Cross-Site Request Forgery), CWE-384 (Session Fixation)

Affected file/line:

  • src/core/web_api/p2_api.js:24
  • src/core/web_api/p2_api.js:174-180
  • Supporting behavior in bundled dependency: auth0-js/src/web-auth/index.js:345-348

Root cause:
Lock copies the private _enableIdPInitiatedLogin / _enableImpersonation options into this._enableIdPInitiatedLogin and always forwards that flag to client.parseHash() as __enableIdPInitiatedLogin. In the bundled auth0-js flow, validateAuthenticationResponse() skips the normal state mismatch rejection when both the callback fragment and stored transaction are missing state and __enableIdPInitiatedLogin is true. That means a callback route can accept an unsolicited login result without a matching local transaction.

Reproduction steps:

  1. Initialize Lock with _enableIdPInitiatedLogin: true or _enableImpersonation: true.
  2. Start an authentication flow for the same Auth0 application as an attacker and capture the resulting callback fragment.
  3. Ensure the victim browser has no matching local transaction state stored for that callback route.
  4. Navigate the victim to a callback URL containing the attacker-controlled fragment, for example:
    https://app.example/callback#id_token=ATTACKER_ID_TOKEN&access_token=ATTACKER_ACCESS_TOKEN&token_type=Bearer
  5. parseHash() accepts the attacker identity because state validation is bypassed under the no-state/no-transaction condition.

Suggested fix:

  • Do not forward __enableIdPInitiatedLogin from Lock by default.
  • Fail closed on callback parsing when state is missing unless the flow is explicitly authenticated as a trusted IdP-initiated callback.
  • Remove or tightly gate _enableImpersonation / _enableIdPInitiatedLogin in public Lock integrations.
  • Add regression tests for unsolicited callback fragments and missing-state callback handling.

Commit tested: 75336c98dbdc8ee01f4c2651e50d4c65cda32f01

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions