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

Passwordless "Magic Code" has broken TOTP (aal0 forever) #4285

Closed
4 of 5 tasks
brenobaptista opened this issue Jan 31, 2025 · 4 comments
Closed
4 of 5 tasks

Passwordless "Magic Code" has broken TOTP (aal0 forever) #4285

brenobaptista opened this issue Jan 31, 2025 · 4 comments
Labels
bug Something is not working.

Comments

@brenobaptista
Copy link

brenobaptista commented Jan 31, 2025

Preflight checklist

Ory Network Project

No response

Describe the bug

If a user uses passwordless they will be assigned aal0, so if they set up TOTP it won't actually work. This means that if those users use TOTP they will be bugged, they won't actually be protected by it.

According to the documentation (https://www.ory.sh/docs/kratos/mfa/overview), the AAL parameter can take one of two values:

  • aal1: The user completed only the first authentication factor(s).

  • aal2: The user completed the first and the second authentication factor(s).

Reproducing the bug

When a user uses passwordless they will have an identity aal0. After they set up TOTP it will create identity_credential related to it, but then the identity will still use aal0. After trying to log in, the system won't ask for TOTP so it will be stuck on aal0 forever.

I tested in practice and confirmed that if the user is on aal0 and sets up TOTP they won't move from aal0 to aal2. The user can only go from aal1 to aal2 or from aal2 to aal1.

aal0 is on a limbo because aal0 won't ask for TOTP, so it will never get out of it.

Relevant log output

Relevant configuration

apiVersion: v1
kind: ConfigMap
metadata:
  name: kratos-config
  namespace: redacted
data:
  kratos.yml: |
    version: v1.1.0
    dev: false
    session:
      cookie:
        domain: redacted
    serve:
      public:
        base_url: redacted
        cors:
          enabled: true
          allowed_origins:
            - redacted
          allowed_methods:
            - POST
            - GET
            - PUT
            - PATCH
            - DELETE
          allowed_headers:
            - Authorization
            - Cookie
            - Content-Type
          exposed_headers:
            - Content-Type
            - Set-Cookie
      admin:
        base_url: redacted
    selfservice:
      default_browser_return_url: redacted
      allowed_return_urls:
        - redacted
      methods:
        password:
          enabled: true
        code:
          passwordless_enabled: true
        oidc:
          config:
            providers:
              - id: google
                provider: google
                client_id: redacted
                client_secret: redacted
                mapper_url: "file:///etc/config/oauth/google-jsonnet.txt"
                scope:
                  - email
                  - profile
                requested_claims:
                  id_token:
                    email:
                      essential: true
                    email_verified:
                      essential: true
              - id: microsoft
                provider: microsoft
                client_id: redacted
                client_secret: redacted
                microsoft_tenant: common
                mapper_url: "file:///etc/config/oauth/microsoft-jsonnet.txt"
                scope:
                  - profile
                  - email
                requested_claims:
                  id_token:
                    email:
                      essential: true
                    email_verified:
                      essential: true
          enabled: true
        totp:
          config:
            issuer: redacted
          enabled: true
        lookup_secret:
          enabled: true
      flows:
        error:
          ui_url: redacted
        settings:
          ui_url: redacted
          privileged_session_max_age: 87600h
        recovery:
          enabled: true
          ui_url: redacted
        verification:
          enabled: true
          ui_url: redacted
        logout:
          after:
            default_browser_return_url: redacted
        login:
          ui_url: redacted
          lifespan: 10m
          after:
            oidc:
              default_browser_return_url: redacted
        registration:
          login_hints: true
          lifespan: 10m
          ui_url: redacted
          after:
            password:
              hooks:
                - hook: web_hook # To use webhooks, you must set 'hook' to 'web_hook'
                  config:
                    url: http://svc-user:3000/webhooks/validate-email
                    method: POST # HTTP method used to send request to the webhook URL.
                    body: redacted # Encoded Jsonnet template used to render payload.
                    can_interrupt: true
                    response:
                      ignore: false # Defines if the webhook response should be ignored and run async. Boolean. OPTIONAL
                - hook: session
            oidc:
              hooks:
                - hook: session
                - hook: show_verification_ui
            code:
              hooks:
                - hook: session
    log:
      level: info
      format: text
      leak_sensitive_values: false
    secrets:
      cookie:
        - redacted
      cipher:
        - redacted
    ciphers:
      algorithm: xchacha20-poly1305
    hashers:
      algorithm: bcrypt
      bcrypt:
        cost: 8
    identity:
      default_schema_id: default
      schemas:
        - id: default
          url: file:///etc/config/kratos/identity.schema.json
    courier:
      smtp:
        from_address: redacted

Version

1.1.0

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Kubernetes

Additional Context

No response

@brenobaptista brenobaptista added the bug Something is not working. label Jan 31, 2025
@brenobaptista brenobaptista changed the title Passwordless "Magic Code" breaks TOTP (aal0) Passwordless "Magic Code" is broken on TOTP (aal0 forever) Jan 31, 2025
@brenobaptista brenobaptista changed the title Passwordless "Magic Code" is broken on TOTP (aal0 forever) Passwordless "Magic Code" has broken TOTP (aal0 forever) Jan 31, 2025
@Tan-Aki
Copy link

Tan-Aki commented Feb 4, 2025

Could be linked to #3942 ? Not a 100% sure.
Edit: maybe not.

I think I have the same issue.

  • I enabled both passwordless sign up and passwordless sign in in kratos config/identity schema.
  • Created an account with passwordless sign up.
  • Then enabled 2FA for that account.
  • Then tried to sign in with that account, it never asked for 2FA.

It does seem to work if the the account is created using credentials though. They can even use passwordless flawlessly afterwards. And 2FA works like a charm in both scenarios. The issue really is if the acccount was created using passwordless

Here are my configs

kratos.yml

selfservice:
  flows:
    registration:
      after:
        password:
          hooks:
            - hook: session
        code:
          hooks:
            - hook: session
  methods:
    code:
      enabled: true
      passwordless_enabled: true

partial identity schema

{
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "ory.sh/kratos": {
            "credentials": {
              "code": {
                "identifier": true,
                "via": "email"
              }
            }
          }
        }
      }
    }
  }
}

@brenobaptista
Copy link
Author

Thanks for confirming the issue. We've been using Ory for almost an year and only noticed this bug now because only a handful of partners did these exact steps and none of them have flagged it before.

Anyway, we're planning on upgrading Kratos and Hydra to more recent versions hoping that it somehow fixes the problem, but we checked the changelog quickly and it doesn't seem that the fix is there.

@aeneasr
Copy link
Member

aeneasr commented Feb 10, 2025

This is fixed in newer versions

@aeneasr aeneasr closed this as completed Feb 10, 2025
@Tan-Aki
Copy link

Tan-Aki commented Feb 10, 2025

Thank you! I tried 1.3, but not 1.3.1. Will try that when I get back.

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

3 participants