Secure Ideas is currently working on a revamp and redesign of our website and client portal, to promote a better user experience for our clients. Since a lot of our infrastructure is in AWS, we started to consider Cognito for authentication. On paper it seems to have a lot of what a security consultant could want in an authentication system:
- Identity Federations between Social media and Enterprise accounts
- (Google, Facebook, Amazon, Active Directory and SAML)
- Multi-factor Authentication built-in
- Encryption at-rest and in-transit
- Straightforward access control for backend resources
Despite these benefits there are still three glaring issues that give us pause when considering it for our sole authentication system. While these issues are not security vulnerabilities, they are problems that affect usability, and any security system that isn’t usable doesn’t get used.
Reconfiguring MFA is Obtuse
We are big proponents of Multi-factor Authentication. It is one of the most effective ways anyone can harden their authentication systems and restrict access to their online accounts. One of our core design choices is this: there should be more than one method of ascertaining that somebody really is who they claim to be. This decision is reflected in the architecture for the redesign. When we heard that AWS comes with MFA out of the box, I was ecstatic. However, in AWS Cognito, changing methods of MFA is counterintuitive if you require it for users.
Currently, when you create a Cognito user pool and set MFA as required for all users, you are unable to change the MFA preference for ANY user. Any attempts to do so through the adminSetUserMFAPrefrence() method of CognitoIdentityServiceProvider or through the console result in an error that states “Cannot change the MFA setting when the user pool MFA is required”. The console also will list MFA as disabled even when MFA through SMS works for that user. These problems and many others are documented in a number of issues on the old repository for Cognito as well as for the new AWS-Amplify.
CloudFormation templates can destroy a User Pool
To be honest this one is more of a problem with AWS CloudFormation than it is with Cognito, but if you are managing several different resources for your AWS infrastructure there is a good chance you are using CloudFormation. If you have a lot of resources in AWS there are a few choices for orchestration use CloudFormation, DIY by scripting around each AWS resource and differing versions of your own automation scripts, use a 3rd party vendor like Terraform, or some combination of all of the above.
For the sake of simplicity, we’ve decided to use CloudFormation to manage many of our AWS resources. For many of those resources it runs smoothly, but with Cognito some core functionality requires a full replacement of the Cognito user pool. Allowing a user to use an alias instead of an email, or adding another custom attribute to a created user pool requires replacement. If you are unfamiliar with update behavior for CloudFormation Stacks all you need to know is that replacement destroys a resource and recreates it when a stack’s changeset is executed, provided that there are in fact changes to the resource in question. This has been a problem since 2016, but AWS hasn’t been very responsive. This issue is pretty bad, but it can be catastrophic when combined with the next problem.
There are no User Pool backups
Currently, Amazon does not have any native support for User Pool backups. AWS only provides a way to import users into a user pool, but not export them. This means that if your CloudFormation template updated the User Pool schema, a developer fat fingers some admin tool, or a severe flaw within your app allowed a malicious attacker to get access to AWS resources, your entire user database could be destroyed.
Think about that for a moment. Unless basic information of your entire user base is backed up by some other method, you’re one mistake away from irreversibly losing all of your user information. Databases can be backed up and restored a Cognito User Pool cannot. Of course, a proper staging environment with continuous integration and continuous delivery principles can aid in detecting this and many other problems before they make it into the production environment. However, this bandaid alone cannot treat a gun wound caused by deficiencies in Cognito itself.
There is an npm package that has been recently released to create backups of User Pools, but we are hesitant to trust a random 3rd party script with handling all of our user information. If a user is required to create maintain their own backups, or rely on third parties it defeats the purpose of an all-in-one authentication solution.
Final thoughts
These problems are not security vulnerabilities, but really affect the usability of any system that relies on Cognito for authentication. A core authentication product is not something to just throw together on a quick login page, it is a security product. Any security product that aims to have widespread adoption needs to be as user-friendly as possible.
If you know of someone who has managed to find solution(s) around these issues please let us know in the comments below. In the meantime, we will be looking into other authentication products.