October is National Cyber Security Awareness Month. On top of that, OWASP just celebrated its 20th anniversary. To celebrate, we’re going to run through the newly updated OWASP TOP 10 to remind everyone of how you can better protect your applications, your businesses, and your customers from unlawful and damaging cyber attacks. We’ll also be highlighting where the updates were made and why and throw in some tips on how strengthening your identity solution can help mitigate these threats.
The new Top 10 is still a working draft, and OWASP is soliciting feedback on errors and corrections.
What is OWASP?
The Open Web Application Security Project (OWASP) is a non-profit organization that was set up to help raise awareness around web application security and provides guidance on how to incorporate preventative measures into your applications, infrastructure, and internal processes.
They have several projects, including an insecure JavaScript application used for security training, but the one that we’re focusing on today is the newly updated 2021 edition of their list of the top 10 threats to web app security.
Updated regularly, the OWASP Top 10 lists the main security threats that affect web applications today. Each entry enumerates the threat, shows possible attack vectors, and highlights preventive measures to reduce the risk of such threat. At Auth0, we take steps to mitigate most of the issues outlined below, so when you delegate your authentication needs to us, a lot of this is already taken care of for you.
Let’s run through the list, looking at the threats and what we could be doing to make sure our own applications are secure and examining some features of the Auth0 platform that help to mitigate or entirely remove such threats.
For a high-level overview of the list updates, please refer to this handy chart, provided by OWASP:
#1: Broken Access Control
Moving up to the #1 spot from its 2017 position at #5, broken access control is an umbrella term for possible weaknesses associated with the implementation of a reliable access control system. Access control systems have the ability to distinguish users based on privileges or permissions and determine who gets what access to content and functions. Weaknesses emerging from access control systems can be leveraged by attackers to elevate their permissions to levels they shouldn’t have. Some examples of this are:
- Failing to prevent access to ‘members only’ pages when the user is not logged in or does not have the right permissions to view the page.
- Not validating URL parameters that could be changed by the user (e.g., swapping one user ID out for another).
- Trusting that cookie values have not been altered where the value can be used to determine the user’s role.
- Forgoing security considerations in access control token management
Once Auth0 issues access and ID tokens, they cannot be revoked in the same way as cookies with session IDs for server-side sessions. As a result, tokens should be issued for relatively short periods and then refreshed periodically if the user remains active. You can revoke refresh tokens in case they become compromised. Auth0 treats token revocation as though the token has been potentially exposed to malicious adversaries. Taking care to validate user permissions is key. Do not trust any input that could be modified by the user when it comes to working out what that user can do.
#2: Cryptographic Failures
Formerly sitting at #3 and referred to as “Sensitive Data Exposure,” this entry in the OWASP Top 10 focuses on failures related to cryptography (or lack thereof) which often lead to exposure of sensitive data. It also deals with protecting sensitive information under normal operating conditions. It’s about handling sensitive data securely, encrypting data at rest, and being diligent about holding only as much data as you need only for as long as you need it. One of the reasons that the EU’s General Data Protection Regulation (GDPR) exists today is because of improper handling of sensitive personal data.
Some things that you can do to help prevent sensitive data being stolen from your application include:
- Making sure that web traffic is encrypted and transmitted over HTTPS using a valid SSL certificate and that insecure connections are upgraded where possible. Let’s Encrypt issue free SSL certificates, making it very easy to make sure your web traffic is secure.
- Encrypting and signing any browser cookies that contain sensitive information.
- Removing any sensitive data that is no longer needed.
- Hashing passwords using a strong hashing algorithm such as Bcrypt or PBKDF2.
- Encrypting sensitive data at rest.
Note that using automatic database encryption technology could still leave you exposed if an SQL injection attack is successful, as the data has to be read and decrypted at the database level. Doing the encryption and decryption step as part of your core application logic would help mitigate this.
#3: Injection
Injection flaws are a well-known attack vector and have been around for a long time. This vector particularly impacts legacy code. Despite slipping two spots from its former status as #1, OWASP continues to recognize SQL injection as a common attack that is not only easy to exploit and detect as a weakness in an application but can also have devastating effects if successfully exploited by an attacker. Injection has been expanded to include the former #7 — Cross-site scripting (XSS). This type of attack mostly involves the injection of unsanitized input that causes the user to unwittingly interact with a malicious site or file.
In most cases, these types of attacks are successful because either:
- the application relies on user input that has not been sanitized directly in an SQL query, or;
- the query itself is not parameterized.
Assuming that all user input could potentially be malicious is a good mantra to have when validating and processing it. Parameterizing your SQL queries can also help to protect your datastore from malformed queries manipulating your data in undesirable and damaging ways.
As an example of what SQL query parameterization looks like, imagine a query that inserts a new user into a database:
sql = db.prepare "INSERT INTO users (name, email) VALUES ('#{name}', '#{email}')" sql.execute
In the code snippet above, the values for
name
and email
are inserted into the SQL string without any sanitization performed on the input values. If those input values were to come from form fields, then an attacker could potentially supply malicious values that malform the SQL string and perform an attack. The same query using parameterized values might look like the following: sql = db.prepare "INSERT INTO users (name, email) VALUES (?, ?)" sql.execute 'some_user', 'some_user@email.com'
In this case, the values can be escaped and sanitized by the database library before they are included in the SQL statement. This way the SQL statement cannot be malformed in such a way that it can do damage or expose data.
In more recent times, NoSQL Injection has become a factor when using NoSQL databases such as Mongo. Although it doesn’t use SQL, it’s still potentially susceptible to attacks when user input has not been validated and sanitized, as the query itself can be manipulated. Validating your user input and rejecting values that do not conform to an expected format would be a good strategy.
SQL and NoSQL injection attacks are just a subset of a broad category of injection attacks, which also includes Command, Expression Language, and LDAP.
Many XSS issues can be mitigated by making sure that any data retrieved from third-party sources is properly encoded according to the context. Also, using frameworks that contain built-in mechanisms for sanitizing user input (such as Ruby on Rails or Play Framework) would go a long way to protecting your applications from these types of attacks.
#4: Insecure Design
Making its debut at #4 on this year's list, Insecure Design is a new entry that focuses on the design and architectural flaws. It is defined by OWASP as a broad category that centers around missing or ineffective control design.
Before we go further into this one, it’s important to understand that there is a difference between insecure design and insecure implementation. We differentiate between design flaws and implementation defects for a reason; they have different root causes and remediation. A secure design can still have implementation defects leading to vulnerabilities that may be exploited. An insecure design cannot be fixed by a perfect implementation as by definition, needed security controls were never created to defend against specific attacks.
Insecure design issues can be identified and remediated through effective threat modeling in the design phase. Threat modeling should be performed early in the development cycle when potential issues can be caught early and remedied, preventing a much costlier fix down the line. Threat modeling methods are used to create:
- an abstraction of the system (Assets, components involved, and data flow between them)
- personae of potential attackers and attack surfaces
- a catalog of potential threats that may arise
The outcome of threat modeling is documentation that outlines secure design recommendations and requirements for the system under consideration. This helps identify potential vulnerabilities earlier in the software development lifecycle.
#5: Security Misconfiguration
Moving up one spot from #6, this entry in the Top 10 list has been identified by OWASP as something that is easy to exploit, easy to discover, and extremely common. It concerns themes such as:
- Out of date security patches on the host system
- Application framework security feature not turned on or improperly configured
- Default accounts, passwords, and secure keys left enabled and unchanged
- Unused or default ports and services enabled on the host system
- Verbose error pages or directory listing turned on
This item also incorporates aspects of the former #4 on the list, XML External Entities (XXE). An XXE attack is designed to expose a vulnerability in poorly configured XML parsers. Such attacks can be used to expose sensitive data (such as reading system password files) or invoke a Denial of Service (DoS) attack on a resource.
It is important to make sure that the host system running your applications is updated with the latest security patches, and that your application frameworks have all of the appropriate security features turned on in order to mitigate these types of misconfiguration vulnerabilities.
Another serious concern in this area is making sure that any secret keys for third-party platforms (such as Auth0) are not committed and uploaded to your source control provider along with the rest of your code, particularly if your application is open source. These can be scanned by attackers using automation tools. Better to store these keys securely separate from your source code.
#6: Vulnerable and Outdated Components
This entry jumped three spots from 2017 and was renamed from “using components with known vulnerabilities.” Software these days tends to make use of many third-party components, and so being diligent about which version of these components you are using and keeping them up to date is paramount in protecting your application from attacks that stem from vulnerable dependencies.
Unfortunately, the number of dependencies that a given application uses — directly or indirectly — can sometimes make identifying and triaging vulnerable components difficult, usually meaning that the task doesn’t get done and developers are completely unaware as to their existence.
OWASP recommends a few tools that can help to identify and upgrade components that present a security risk, including their own OWASP Dependency-Check. Node.js applications using NPM version 5.10.0 or 6 and above can make use of the ‘audit’ command in the terminal, which can identify and automatically upgrade dependencies that have been identified as vulnerable.
Another popular tool (and one that we use ourselves here at Auth0) for the checking of vulnerabilities in dependencies is Snyk. Snyk can be set up to evaluate your projects directly in GitHub or can be used as a command-line tool to act directly on your project code.
#7: Identification and Authentication Failures
Formerly sitting at #2 and called “broken authentication,” this entry is close to our hearts here at Auth0. OWASP acknowledges this as easily exploitable with extreme damage potential.
Broken authentication covers many things to do with authenticating users with an application or service, including:
- Automated brute-force attacks using known password lists
- Permission of weak or well-known passwords
- Storage of plain-text or weakly-hashed passwords over strong hashes
- Lack of multi-factor authentication (MFA)
- Improper invalidation of a session when logging out or after a period of inactivity
Implementing features like Auth0’s adaptive MFA into your application will help prevent credential stuffing and other brute force attacks, as the attacker will not be able to complete the authentication steps. Regarding passwords, validating for weak or well-known passwords using a common password list and hashing the user’s password using a strong hashing algorithm (such as Bcrypt or PBKDF2) take the protection a step further. Never use a weak hash like MD5, and never store your passwords in plain text.
It’s also good practice to purposefully use vague login failure messages when your users enter an incorrect username or password. Otherwise, attackers may be able to identify valid accounts that they could use in order to instigate an attack.
The Auth0 identity platform has built-attack protection to address most of the issues around brute-force attacks, including cross-site scripting attacks (XSS) and strong password hashing are all handled for you. Additionally, we make it very easy to turn on and integrate MFA into your applications for that extra level of security.
#8: Software and Data Integrity Failures
Another new entry for 2021, this category includes the former #8: Insecure Deserialization. OWASP expanded the definition to include other ways software and data integrity can slip between the cracks and end in calamity. An insecure CI/CD pipeline, using plug-ins or modules from untrusted repositories or CDNs, along with situations where data is serialized in a structure that an attacker can access and modify are all possible vectors of attack covered by this category.
A partial list of security measures to implement includes:
- Ensuring your CI/CD processes are securely configured and have access controls in place to enable integrity checks on the code flowing through them.
- Incorporate software supply chain security controls to verify the integrity of any modules and plug-ins being used.
- Run any unsigned or unencrypted data through an integrity check before usage.
If your application deserializes objects from untrusted sources, you could be open to this kind of attack. The only safe way to prevent these from happening is to not accept serialized objects from untrusted locations. If that’s not possible, OWASP recommends using digital signatures to verify integrity, enforcing strict primitive type checking, and performing deserialization logic inside a low-privilege environment.
#9: Security Logging and Monitoring Failures
Entry 9 was bumped up from #10 and renamed from “insufficient logging and monitoring.” Being able to discover breaches, attack patterns, and user activity is a key property of a secure system. Without sufficient logging and application monitoring, it will be difficult to ascertain how a system was breached, where the breach came from, and where the holes lie in your application security strategy. If you don’t know where the holes are, you can’t fill them in!
OWASP recommends that application activity — particularly around authentication and permission activities — are logged in a common format that can be easily processed by a centralized logging system. As much detail about user context should be logged and retained as possible without compromising their personal data, which not only includes personally identifiable information (PII) but also secure keys, access tokens, and session tokens. If detailed information that could be used to identify a person must be recorded for forensics purposes, use a secure data warehouse coupled with tight access controls available only to trusted individuals.
#10: Server-Side Request Forgery (SSRF)
Making a debut at #10 this year is Server-Side Request Forgery, an item from OWASPs industry survey. Despite relatively low incidence rates (per the survey), this attack vector rates high in potential impact and damage, so it garnered the #10 spot. SSRF is a flaw that occurs when a web app fails to validate a user-supplied URL. An attacker can exploit this scenario to send a malicious request to any destination server they want.
There are numerous common ways to prevent this type of attack, some are more apt to be overlooked than others:
- Disable HTTP redirection
- Segment remote access functionality to a secure network separate from potential target resources
- Validate all client-supplied input data
- Employ a robust identity and access management solution
Mitigating Security Issues with Auth0
The Auth0 platform has many features which help protect your application and your users from security attacks. For starters, simply by using our Universal Login offering, you are effectively delegating all the work of making your login pages secure and resilient to attacks.
Additionally, Multi-factor Authentication (MFA) can easily be enabled on any application to provide an extra layer of security when your users log in and decrease the likelihood of unauthorized access. Options for completing the MFA step include receiving push notifications and codes via mobile authenticator apps.
Auth0’s Anomaly Detection includes options for protecting against brute-force attacks, blocking repeated attempts to log in, and notifying designated recipients of such unauthorized attempts. Furthermore, enabling our Breached Password Detection feature means that your users will be notified if we detect that their credentials were part of a published security breach.
Comprehensive logging is a feature of the Auth0 platform, which can be interrogated for events, such as:
- Failed login attempts
- Failed password changes
- Failed Access Token exchanges
- Too many failures
Logs can also be shipped to other providers via marketplace integrations, such as Logstash, Papertrail, and Splunk.
As added protection against man-in-the-middle attacks, we also enforce HTTPS connections to our services, meaning that any non-HTTPS connections are upgraded according to HSTS specifications.
Finally, to protect against XXE attacks through SAML, we use our own fork of XML parsing library 'XMLDOM', which does not allow DOCTYPE entity parsing at all—a key component of XXE attacks.
Summary
In this article, we’ve had a brief run through the newly updated OWASP Top 10 and examined the main threats to web application security that exist today. We've also considered some of the possible mitigations against such threats and how we can all do better to help protect our businesses and our users from problems arising as a result of poor and insecure implementation.
Some of these solutions are easy to implement and take only a short amount of time, while others require a bit more thought and planning to do properly. However, anything that can be done to improve the security of your products — especially where personal information and other sensitive data is concerned — can only be beneficial, and could be a key factor in preventing a data disaster should an attack be attempted.
We've also looked at several key features of the Auth0 platform that bolster the security of web applications and APIs, from relieving you of a lot of these issues through Universal Login to rich audit trails through comprehensive logging. To start taking advantage, sign up for a free account today or reach out to our team of identity experts to have your questions answered.
About the author
Chitra Dharmarajan
Senior Director, Product Security