Does API access circumvent 2FA?


Thanks for adding 2FA to the web UI, this is an important step. However, I’m wondering about the current state of the API with respect to 2FA.

Please correct me if I’m wrong, but from reading the API documentation, my impression is that an adversary who obtained a valid username/password combination (e.g., through phishing) would have little reason to worry about 2FA at all, because pretty much everything can be done through API calls after obtaining a token from the login endpoint. The login endpoint is not secured by 2FA.

Is this correct? If yes, are there plans to extend the 2FA to the API login? The login endpoint might be extended so that a TOTP has to be provided for accounts where 2FA is active. For non-interactive use cases the web ui can be used to create long-term API tokens.

Cheers, and keep up the excellent work :slight_smile:

Hi RonObvious,

That’s not correct. In reality, what can be done with a token obtained from the login endpoint depends on whether the account has 2FA enabled or not.

If it’s not enabled, you obviously can do anything with a login token. However, if 2FA is enabled, all relevant endpoints (including those for domains, RRset, tokens, and token policies) require 2FA authentication before they can be accessed.

As the web interface immediately switches to the domains endpoint, it requires 2FA authentication directly after log-in.

“Change email” does not require 2FA because it only allows replacing one factor with another one of the same type. “Delete account” does not require 2FA, but generally can only be done when the account has no domains. (Domain deletion, however, requires 2FA if enabled.)

This mechanism is called step-up authentication. It has various advantages, most importantly being able to give the user a “weaker” type of session for non-critical activities. Such a session is then used e.g. to perform 2FA where needed, or to perform things like email change. In other words, 2FA-enabled accounts that only have done password authentication are not “fully disabled”, but that’s OK.

This is already the case.

From a technical perspective, each token has a mfa property. If the property is not set at all (None in Python), the token is a non-interactive token, and what it can access is determined by token policies, not by 2FA. If the value is set to False, then you have a login token that has not yet been promoted to full access. After 2FA step-up authentication has been performed, that flag is set to True, and the token has full access.

Stay secure,

1 Like

Thanks for the clarification, that helped a lot! From looking at the totp api test I found that I had to call

curl --header "Authorization: Token <logintoken>"

to get the token id, followed by

curl -X POST<id>/verify/ \
    --header "Authorization: Token <logintoken>" --header "Content-Type: application/json" --data @- <<< \
    '{"code": "012345"}'

to “update” my login token. Besides (which only briefly mentions the evolving 2FA API), is there a place where I can read about such new features which are under active development?

The 2FA API isn’t properly documented because it is not final yet, so we don’t want people to rely on its details. We’ll finalize it once WebAuthn / FIDO is implemented.

A sort of roadmap can be found here: Projects · desec-io/desec-stack · GitHub

However, please note that development is currently slowed down due to standardization work that we are doing in and around the IETF. So there are currently no ETAs. But we’ll happily accept pull requests :slight_smile:

Stay secure,