Amplify-js: Plaintext Password Visible for 'SignUp' ONLY using USER_SRP_AUTH as CognitoUser.authenticationFlowType

Created on 27 Sep 2019  路  5Comments  路  Source: aws-amplify/amplify-js

Describe the bug
Plaintext password is visible on the client-side (web browser) when using Amplify to authenticate with Cognito for the 'SignUp' method only, the 'SignIn' method does not have this issue.

Using Chrome dev tools, when Amplify's 'SignUp' method is called, it displays the password as plaintext in the 'Password' field in the 'AuthParameters' HTTP(s) header request payload.

To Reproduce
Steps to reproduce the behavior:

_Source Code:_

  1. Use the 'Auth' package from 'aws-amplify'
  2. Call the 'signUp' method of the 'Auth' package

_UI_

  1. Open Chrome
  2. Access UI
  3. Use 'Inspect' feature of Chrome
  4. Input 'SignUp' details (username, password, etc)
  5. Click 'SignUp' button
  6. Go to 'Network' tab of the 'Inspect' panel
  7. Search for request accessing 'https://cognito-idp...' using 'POST' as the method
  8. Go to the 'Headers' tab of the request
  9. Scroll down to the 'Request Payload' section of the 'Headers' tab

Expected behavior
Similar to the 'SignIn' method, the 'SignUp' method should only show the SRP token, not the plaintext password, when using USER_SRP_AUTH as the auth flow type (authenticationFlowType).

Screenshots
'SignIn' use case:
Screen Shot 2019-09-27 at 13 58 33

'SignUp' use case:
Screen Shot 2019-09-27 at 13 57 56

Desktop (please complete the following information):

  • OS: OS X 10.14.5
  • Browser Chrome
  • Version 77

Additional context
Related to Cognito auth

Sample code
auth flow type setting when cognito user is created:
https://github.com/aws-amplify/amplify-js/blob/master/packages/amazon-cognito-identity-js/src/CognitoUser.js#L94

cognito user creation inside 'SignUp' method:
https://github.com/aws-amplify/amplify-js/blob/master/packages/amazon-cognito-identity-js/src/CognitoUserPool.js#L116

Auth Cognito question

Most helpful comment

Hi @chrismcdonald0111

Thanks for creating this issue, let me share my thoughts on this

Cognito uses SRP for Authentication and passwords are not stored at all on the service

From https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

In layman's terms, during SRP (or any other PAKE protocol) authentication, one party (the "client" or "user") demonstrates to another party (the "server") that they know the password, without sending the password itself nor any other information from which the password can be derived. The password never leaves the client and is unknown to the server.

This assumes that the server had, at some point, knowledge of the "password" (or a cryptographic verifier derived from the password), SRP doesn't cover the transmission of the password or verifier to the server (the "registration"/signup step) and that's why the signUp call sends the password in clear text (so the server can generate a password verifier and store it). The protections for the signup operation (a one time operation for each user) are the ones provided in this case by the transport protocol (https, meaning communication is encrypted). All signIn operations never send the password and follow the SRP protocol.

You still get the advantage that the server doesn't know or store the password (only a verifier derived from it).

From the SRP RFC https://tools.ietf.org/html/rfc2945#section-4

SRP has been designed not only to counter the threat of casual password-sniffing, but also to prevent a determined attacker equipped with a dictionary of passwords from guessing at passwords using captured network traffic.

SRP also has the added advantage of permitting the host to store passwords in a form that is not directly useful to an attacker.

I'll dig a little bit more into this

All 5 comments

This is a serious security issue, I have exactly the same problem!

Hi @chrismcdonald0111

Thanks for creating this issue, let me share my thoughts on this

Cognito uses SRP for Authentication and passwords are not stored at all on the service

From https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

In layman's terms, during SRP (or any other PAKE protocol) authentication, one party (the "client" or "user") demonstrates to another party (the "server") that they know the password, without sending the password itself nor any other information from which the password can be derived. The password never leaves the client and is unknown to the server.

This assumes that the server had, at some point, knowledge of the "password" (or a cryptographic verifier derived from the password), SRP doesn't cover the transmission of the password or verifier to the server (the "registration"/signup step) and that's why the signUp call sends the password in clear text (so the server can generate a password verifier and store it). The protections for the signup operation (a one time operation for each user) are the ones provided in this case by the transport protocol (https, meaning communication is encrypted). All signIn operations never send the password and follow the SRP protocol.

You still get the advantage that the server doesn't know or store the password (only a verifier derived from it).

From the SRP RFC https://tools.ietf.org/html/rfc2945#section-4

SRP has been designed not only to counter the threat of casual password-sniffing, but also to prevent a determined attacker equipped with a dictionary of passwords from guessing at passwords using captured network traffic.

SRP also has the added advantage of permitting the host to store passwords in a form that is not directly useful to an attacker.

I'll dig a little bit more into this

@manueliglesias My understanding is that the plain text password is never sent to the server in SRP. Therefore, the implementation in Amplify is incorrect.

After some more thought, I agree with @manueliglesias.

The verifier is derived from the password in a cryptographic one-way function, but without any tunable workload parameters (such as the number of iterations in PBKDF). Therefore, if an attacker were to obtain the verifier, then brute-forcing it is pretty easy: the salt is known, the only entropy is in the password.

So sending the verifier rather than the plain password is not adding a great deal more security. It would be better to make sure the TLS tunnel is secure in the first place.

However, it would still be better to send up only the verifier and the salt since they are the minimal set of information required.

Thanks for the feedback @amzhang . Looks like @manueliglesias helped out here, so will close.

Was this page helpful?
0 / 5 - 0 ratings