Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

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

Open
#2,786 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 4 days

@parasol-aser is already working on this.

Since Apr 23, 2026.

  • #2788 by @parasol-aser — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
38/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
javascript

Research direction

Start with src/core/web_api/p2_api.js at lines 24 and 174-180, then inspect auth0-js/src/web-auth/index.js:345-348 and reproduce the missing-state callback flow described in the issue. Add regression coverage for unsolicited callback fragments and missing-state handling, and verify that attacker-controlled callbacks are rejected unless explicitly trusted.

Written by the indexing model from the issue text.

Description

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

Dominant language
JavaScript
Stars
1.1k
Forks
563
Avg merge
4d 11h
Merged PRs (30d)
10

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from auth0/lock

All issues in auth0/lock

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.