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:
- Initialize Lock with
_enableIdPInitiatedLogin: true or _enableImpersonation: true.
- Start an authentication flow for the same Auth0 application as an attacker and capture the resulting callback fragment.
- Ensure the victim browser has no matching local transaction state stored for that callback route.
- 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
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
Severity: High
CWE: CWE-352 (Cross-Site Request Forgery), CWE-384 (Session Fixation)
Affected file/line:
src/core/web_api/p2_api.js:24src/core/web_api/p2_api.js:174-180auth0-js/src/web-auth/index.js:345-348Root cause:
Lock copies the private
_enableIdPInitiatedLogin/_enableImpersonationoptions intothis._enableIdPInitiatedLoginand always forwards that flag toclient.parseHash()as__enableIdPInitiatedLogin. In the bundledauth0-jsflow,validateAuthenticationResponse()skips the normal state mismatch rejection when both the callback fragment and stored transaction are missingstateand__enableIdPInitiatedLoginis true. That means a callback route can accept an unsolicited login result without a matching local transaction.Reproduction steps:
_enableIdPInitiatedLogin: trueor_enableImpersonation: true.https://app.example/callback#id_token=ATTACKER_ID_TOKEN&access_token=ATTACKER_ACCESS_TOKEN&token_type=BearerparseHash()accepts the attacker identity because state validation is bypassed under the no-state/no-transaction condition.Suggested fix:
__enableIdPInitiatedLoginfrom Lock by default.stateis missing unless the flow is explicitly authenticated as a trusted IdP-initiated callback._enableImpersonation/_enableIdPInitiatedLoginin public Lock integrations.Commit tested:
75336c98dbdc8ee01f4c2651e50d4c65cda32f01