Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kratos generates broken redirects to AAL2 login flows if identity has both SMS and another 2FA method #3802

Open
5 tasks done
MichaelMarner opened this issue Mar 7, 2024 · 0 comments
Labels
bug Something is not working.

Comments

@MichaelMarner
Copy link

MichaelMarner commented Mar 7, 2024

Preflight checklist

Ory Network Project

No response

Describe the bug

If an identity is configured for SMS 2FA, and also has another 2FA method configured, such as TOTP, then any redirects to an AAL2 login flow generated by Kratos are broken, as they do not include a via request parameter.

Reproducing the bug

  1. Configure an identity schema with a phone verifiable phone number
  2. Configure Kratos to enable SMS based 2FA
  3. Configure Kratos to use highest_available on whoami, settings, or other self service flows
  4. Log into Kratos
  5. In a settings flow, add a phone number to the account, complete the verification process
  6. In a settings flow, add TOTP to the account
  7. Log out
  8. Attempt to log in with email/password

At this point, Kratos will redirect the client:

{
    "error": {
        "id": "browser_location_change_required",
        "code": 422,
        "status": "Unprocessable Entity",
        "reason": "In order to complete this flow please redirect the browser to: http://127.0.0.1:4433/self-service/login/browser?aal=aal2",
        "message": "browser location change required"
    },
    "redirect_browser_to": "http://127.0.0.1:4433/self-service/login/browser?aal=aal2"
}

However, navigating to the URL provided will result in an error screen, with the following error:

{
  "id": "ff1cb352-2137-40e9-8eb5-04f4c74ffdd1",
  "error": {
    "code": 400,
    "reason": "AAL2 login via code requires the `via` query parameter",
    "status": "Bad Request",
    "message": "The request was malformed or contained invalid parameters"
  },
  "created_at": "2024-03-07T01:53:18.011166Z",
  "updated_at": "2024-03-07T01:53:18.011166Z"
}

Note: I've focused on the login redirect here, but equivalent broken redirects are generated when making other calls, such as to whoami.

Relevant log output

No response

Relevant configuration

Kratos.yml:


version: 1.1.0
session:
  whoami:
    required_aal: highest_available
  methods:
    password:
      enabled: true
    totp:
      config:
        issuer: My Cool Business
      enabled: true
    lookup_secret:
      enabled: true
    code:
      enabled: true
      mfa_enabled: true


Identity Schema:


{
  "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "title": "E-Mail",
          "minLength": 3,
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "verification": {
              "via": "email"
            },
            "recovery": {
              "via": "email"
            }
          }
        },
        "phone": {
          "title": "Phone Number",
          "type": "string",
          "format": "tel",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "verification": {
              "via": "sms"
            }
          }
        },
        "name": {
          "type": "object",
          "properties": {
            "first": {
              "title": "First Name",
              "type": "string"
            },
            "last": {
              "title": "Last Name",
              "type": "string"
            }
          }
        }
      },
      "required": ["email"],
      "additionalProperties": false
    }
  }
}

Version

1.1.0

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

Docker

Additional Context

It feels like the via= request parameter isn't really the right approach to start an AAL2 login flow - it requires the client to know too much about how Kratos is configured, and requires the client to have information about the identity that is not possible to know (ie what 2FA approaches are enabled on the account). It makes the client very brittle and at risk of breaking if any Kratos configuration changes.

I think Kratos needs another step to the login flow that generates a UI presenting all the ways the user can complete AAL2 authentication, allowing the user to select "use Authenticator app" or "send an SMS". Kratos could be configured to have a default or preferred option.

This matches what other services tend to do. For example Github I have TOTP and phone number configured. When I login, Github asked for my TOTP code by default, but also gives me the option to authenticate with an SMS or recovery code.

@MichaelMarner MichaelMarner added the bug Something is not working. label Mar 7, 2024
@MichaelMarner MichaelMarner changed the title Kratos redirects incorrectly to AAL2 login flows if identity has SMS and another 2FA method Kratos redirects incorrectly to AAL2 login flows if identity has both SMS and another 2FA method Mar 7, 2024
@MichaelMarner MichaelMarner changed the title Kratos redirects incorrectly to AAL2 login flows if identity has both SMS and another 2FA method Kratos generates broken redirects to AAL2 login flows if identity has both SMS and another 2FA method Mar 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working.
Projects
None yet
Development

No branches or pull requests

1 participant