The essential security checklist for user identity
Tags: tutorial, security, webdev, beginners
Published: 2023-07-03 13:43:14

## Introduction

Building user identity is a critical component of any application. It enables you to provide personalized experiences, enhance data quality, and improve user retention.

Validating usernames and passwords may seem like the simplest approach, but there are many other aspects to consider. Let's get started!

## Infrastructure

### Enforce HTTPS

Let's start with the basics. Always enforce the use of [HTTPS](https://en.wikipedia.org/wiki/HTTPS) (Hypertext Transfer Protocol Secure) to encrypt data transmission over the internet. HTTPS ensures that the data exchanged between the user's device and your server remains confidential and tamper-proof.

Setting up HTTPS may seem challenging, but there are many tools and services available to help you:

- If you are self-hosting, [Let's Encrypt](https://letsencrypt.org/) provides free SSL/TLS certificates that can be used to enable HTTPS on your website.
- If you are using a cloud provider, such as AWS, Azure, or Google Cloud, you can use their managed services to set up HTTPS.

### Don't allow public database access, limited to trusted sources only

Although it may seem basic as well, there have been numerous security breaches due to allowing public access to databases. So it's worth mentioning here.

Always remember to never allow public access to your database. Put your database in a private network and only allow access from trusted sources.

### Securely manage private tokens

Private tokens, such as access tokens or API keys, are often used for programmatic authentication and authorization purposes. To manage these tokens securely:

- Use short-lived tokens and refresh tokens to minimize the risk of unauthorized access.
- Use a secure token storage mechanism, such as a key vault, to protect tokens from unauthorized access.
- Regularly rotate tokens to prevent them from being compromised. Some protocols, such as OAuth 2.0, provide a mechanism for token rotation.
- Retain control over token revocation in case of a security breach.

### Choose a password hash algorithm wisely

If you have experience with password hashing, you may be aware that there are many algorithms available, some of which are no longer considered secure, such as MD5, SHA-1, and SHA-2.

Some common reasons for their insecurity are:

- They were not specifically designed for password hashing, and their computational speed is too fast, making brute force attacks easier.
- They lack the use of salt, which makes it easier to create [rainbow tables](https://en.wikipedia.org/wiki/Rainbow_table) for them.
- They are susceptible to collision attacks, allowing attackers to generate different passwords with the same hash value.

Industry-standard password hashing algorithms, such as [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) and [Argon2](https://www.password-hashing.net/argon2-specs.pdf), have been designed to address these issues. Due to the limited scope of this article, we won't go into detail about them. You can choose a mature library for one of these algorithms in your programming language.

### Learn and strictly adhere to open standards

Open standards like [OAuth 2.0](https://www.rfc-editor.org/rfc/rfc6749) and [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html) (OIDC) provide secure and standardized approaches for user authentication and authorization. They have been battle-tested and widely adopted by the industry.

However, implementing them incorrectly can lead to security vulnerabilities, even for large teams with experienced developers. A recent example is [the OAuth vulnerability discovered in Expo](https://blog.logto.io/oauth-security-recap/), a popular framework for building mobile apps. It serves as a good example of how a small mistake can result in a security breach.

### Encrypt data at rest

Data at rest, such as stored user information or database backups, should be encrypted using a strong encryption algorithm. This ensures that even if the data is compromised, it cannot be read without the decryption key. Double-check if your cloud provider supports this feature, as it is commonly required for compliance purposes.

### Set up firewalls

DDoS (Distributed Denial of Service) attacks, though ancient, remain a significant threat. According to the [Cloudflare DDoS threat report for 2022 Q4](https://blog.cloudflare.com/ddos-threat-report-2022-q4/), the amount of HTTP DDoS attack traffic increased by 79% YoY. Instead of building your own solution, it's a good idea to set up managed firewalls and utilize notifiers to mitigate this risk.

## Apps and clients

### Improve security level for public clients

Public clients, such as mobile apps or single-page applications, are more susceptible to security vulnerabilities. Even if you provide them, you should treat them as untrusted sources in your security model. For example:

- If you are using OAuth 2.0, use [Proof Key for Code Exchange](https://www.rfc-editor.org/rfc/rfc7636) (PKCE) to protect against authorization code interception attacks.
- Enforce [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP) to mitigate certain types of attacks, including [Cross-Site Scripting](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) (XSS) and data injection attacks.

### Never trust public input data

User input can be a significant source of security vulnerabilities, often overlooked. Some common types of overlooked vulnerabilities are [Cross-Site Scripting](https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting) (XSS) and [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection). Make sure to validate and sanitize all user input data before using it.

### Keep track of activities

Maintaining an audit trail of user activities helps in detecting and investigating security incidents. Log and monitor user actions, such as login attempts, password changes, or sensitive operations. Analyzing these logs can provide valuable insights into potential security breaches or suspicious activities.

### Implement solid authentication

Implement a strong authentication mechanism to verify the identity of users. As mentioned earlier, consider using secure protocols like OAuth 2.0 or OpenID Connect for authentication. For more information, you can refer to [CIAM 101: Authentication, Identity, SSO](https://blog.logto.io/ciam-101-intro-authn-sso/).

### Build solid authorization (e.g., Implement Role-Based Access Control)

In addition to authentication, proper authorization mechanisms should be in place. Implement Role-Based Access Control (RBAC) to ensure that users only have access to the resources and actions they are authorized to perform. For more information, you can refer to [CIAM 102: Authorization & Role-based Access Control](https://blog.logto.io/ciam-102-authz-and-rbac/).

### Implement Multi-Factor Authentication (MFA)

Multi-Factor Authentication (MFA) adds an extra layer of security by requiring users to provide one or multiple forms of identification, such as a password and a one-time code sent to their mobile device. Another good example of MFA is when GitHub asks users to enter a one-time code from their mobile app, which is displayed on the webpage, for performing sensitive operations like deleting a repository.

## Culture

The advice provided above mostly covers "passive" security measures, which are known before a security incident occurs. However, there are also "active" security measures you can take to improve your overall security posture, which are more effective in the long run.

### Educate your team and users about phishing and social engineering

Phishing attacks and social engineering are critical because they can render many of the security measures mentioned above useless. For example, if a user is tricked into giving away their password or clicking on a seemingly innocent cat picture that contains malware, the strength of your password hashing algorithm or firewall rules becomes irrelevant.

Most people find security training boring, and it often is. So, change the way you educate your team and users. For example, you can simulate a phishing email before an actual attacker does and demonstrate how to identify it. You can even offer rewards for reporting the email to the security team.

### Set up DevSecOps

In addition to manual security reviews, you can also implement DevSecOps practices to automate security checks. For example, you can set up a CI/CD pipeline to run static code analysis tools like [CodeQL](https://securitylab.github.com/tools/codeql) and automatically run penetration tests using tools like [OWASP ZAP](https://www.zaproxy.org/).

### Embrace the most strict configuration without impacting user experience

When it comes to security, always opt for the most secure configuration that doesn't negatively impact the user experience. Avoid taking shortcuts or compromising security for convenience. Security should always be a top priority.

As a startup or indie developer, you may feel that you lack the necessary resources to implement these measures. Nevertheless, there are professional security services available that offer free or startup-friendly options. Take the time to review and consider utilizing them.

## Conclusion

Security is a complex topic, and it is impossible to cover everything in a single article. We hope that this article has helped you build a stronger sense of security for yourself or your team. If you are building a new app, you may also want to check out [Logto](https://logto.io/), a platform that helps you develop, manage, and secure your product's user identities with minimal effort.