Skip to content

handling restricted session token for 2FA #5305

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

Closed
wants to merge 3 commits into from

Conversation

Etto91
Copy link

@Etto91 Etto91 commented Jan 20, 2019

Our goal was to integrate Two Factor Authentication by generating two-factor session token and validating them.

The steps that I developed are:

  • Add two-factor authentication’s options on the parse-server configuration.
    Available options are the following:
    • token: string used to encrypt two-factor session token
    • twoFactorAlwaysRequired: boolean. When “true” any sessions needs to carry a 2FA Token. When false the system check per user basis. ( default false )
    • firstSessionExpireTime: number of minutes added to the expiration of the session when is created. ( Minutes, default 4 )

During the login, if 2fa is active, we set expiration time based on firstSessionExpireTime option on the session object.

Login’s response has not changed.

/login/two-factor-validation

The API requires masterKey.
The API creates a token, encrypted with the “token” set on configuration options, updates the session expiration time, save the session, and returns the encrypted token.

X-Parse-Session-Two-Factor-Token

The token needs to be attached to every request.
It should be passed as X-Parse-Session-Two-Factor-Token in the header or as part of the body request as _SessionTwoFactorToken. We tested with REST API, and we made an integration for the JS SDK user (We can make a PR for this)

Auth Middleware update

On the auth middleware we have added a condition that checks if 2FA is required for the case. When is required, we verify the encrypted session token otherwise we return UnAuthorized.

This personally my first PR. I’m not sure the code is matching your ideas but its working. I need some help with the test creation and in updating faling tests.

@flovilmart
Copy link
Contributor

@Etto91 great getting this started. I am curious why you chose to implement something completely custom, and not use a note/totp library like this https://github.com/guyht/notp

I see multiple advantages in using a standard OTP protocol, From the ability to use an app like google Authenticator or Authy to the fact that it is a real standard.

@flovilmart
Copy link
Contributor

Also, I recommended a different approach for the session handling, in the issue, that I wish to see in this implementation. If this was unclear, let me know.

Copy link
Contributor

@flovilmart flovilmart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking at the code, I am very confused by the implementation. I really enjoy that you are taking on this feature, but as you are touching to security, we need to be extra careful.

A few advices:

  • don’t reinvent a 2FA protocol, please use an existing one
  • add tests, for everything
  • do not over engineer

);
}
const sessionToken = req.info.sessionToken;
if (!req.auth.isMaster) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only the master user can do that? This does not make any sense.

if (
req.url === '/login/two-factor-validation' &&
info.sessionToken &&
info.masterKey !== req.config.masterKey
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow! Big security flaw creating a master session when keys mismatch.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obv big mistake

@flovilmart
Copy link
Contributor

I’ll be closing this Pr as the implementation is very far from what was originally discussed and there is still a lot of work to get a functional 2FA implementation. Please refer to conventional implementations.

@flovilmart flovilmart closed this Jan 20, 2019
@flovilmart
Copy link
Contributor

@Etto91 I made a document here on the wiki in order to help with the implementation: https://github.com/parse-community/parse-server/wiki/Draft:-Parse---OTP

@Etto91
Copy link
Author

Etto91 commented Jan 20, 2019

@flovilmart

what we thought was the possibility of using the preferred two-factor system.
we are not security experts and we probably lack some knowledge.

the procedure is: the first step normally log in the user to create the session, after which the developer can implement the two-factor system (google auth, sms, etc.). after verifying the user with any two-factor verification, on the server side, it is necessary to call the session validation. the master key must be used because otherwise it can be called from the user (we have passed a session token on login). in response we have a second session key that must be linked to requests to validate them.

all this was done to create two authentication steps and to give the developer the opportunity to develop their second authentication step.

I have a question for you. I wanted to ask you why do you prefer that authentication occurs in a single call with username password and otp?

as soon as I have some time I try to start the steps you have written in the documentation

@flovilmart
Copy link
Contributor

the first step normally log in the user to create the session, after which the developer can implement the two-factor system (google auth, sms, etc.). after verifying the user with any two-factor verification, on the server side, it is necessary to call the session validation. the master key must be used because otherwise it can be called from the user (we have passed a session token on login). in response we have a second session key that must be linked to requests to validate them.

This is completely not necessary with using TOTP.

after which the developer can implement the two-factor system (google auth, sms, etc.). after verifying the user with any two-factor verification, on the server side, it is necessary to call the session validation

google auth, sms etc... as just delivery methods for the OTP. This would be configured when the user configures the OTP for his account. I agree this is a 'nice to have' to be able to provide a simple OTP through sms, and yes you could send the OTP to the user's email account, those are all valid delivery strategies, but they should be baked in at registration AND at login, and for now, I do not believe they provide any value thinking about it because you NEED a valid TOTP authentication method to begin with.

the developer can implement the two-factor system (google auth, sms, etc.)

In all cases, the underlying implementation is a TOTP. That the email or sms is sent is a detail that can be solved later on.

all this was done to create two authentication steps and to give the developer the opportunity to develop their second authentication step.

This is not necessary to create a session just for that. For example Apple implement this flow for iCloud login with OTP:

  1. User logs in with email / password
  2. The user account require 2FA, a notification is sent to the uSer devices to show a locally generate TOTP
  3. the user puts the OTP inside the password field instead of the existing password.

In all thoses steps an intermediate session is not necessary at all.

I wanted to ask you why do you prefer that authentication occurs in a single call with username password and otp?

Because there is no technical or security reason to add an additional step through creating a temporary session? What guarantee does this provide?

@Etto91
Copy link
Author

Etto91 commented Jan 20, 2019

Because there is no technical or security reason to add an additional step through creating a temporary session? What guarantee does this provide?

you're right.

i will try to implement totp user setup as soon as possible.

@flovilmart
Copy link
Contributor

I am trying a working prototype on my side too. Let's see how your implementation is going :)

@brianmwadime
Copy link

Because there is no technical or security reason to add an additional step through creating a temporary session? What guarantee does this provide?

you're right.

i will try to implement totp user setup as soon as possible.

Hey @Etto91 did you manage to complete this?

@Etto91
Copy link
Author

Etto91 commented Nov 21, 2019

@brianmwadime
I'm sorry but I couldn't complete it

@REPTILEHAUS
Copy link

@flovilmart Ive been trawling the issues etc and see you are looking into this the most. Im looking to implement this functionality using speakeasy OTP library. Have you managed to get anywhere with an implementation ? or can you give me some pointers on how to get this integrated.

@flovilmart
Copy link
Contributor

It was 2 years ago, I don't have a copy of this project anymore

@REPTILEHAUS
Copy link

REPTILEHAUS commented Sep 15, 2020

Its more relevant now than ever, almost every site uses some kind of OTP, MFA etc.

is this on the roadmap at all ? Can you give advice if I was to tackle it. My use case is simply to have google authenticator as an extra step after successful login

@REPTILEHAUS
Copy link

@flovilmart is there any way we can have a chat about how you would like to see this implemented, Im willing to submit a PR for this feature as I need it myself but your knowledge of the parse internals and its session management would be really great to have.

@flovilmart
Copy link
Contributor

@REPTILEHAUS i don't maintain this project anymore, you can submit a Pr, I guess one of the maintainers will take care of it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants