OWASP Top 10 lists ten most critical security risks for web application. It assesses each security risks/vulnerability class and provides guidelines, examples, best practices for preventing attacks on web application and mitigate the security risks.
Broken Access Control
Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data, or performing a business function outside of the limits of the user.
In a web application the broken access control vulnerability arises when the application fails to properly validate authorization after the user has been authenticated. Broken access control vulnerability allows an attacker to bypass authorization safeguards and allow him/her to access private data or performs tasks/functions as privileged user (Vertical privilege escalation) or as another user with same privilege (horizontal privilege escalation). Example of some of the common Broken access control vulnerabilities are :
- Bypassing access control checks by modifying the URL, internal application state, or the HTML page, or simply using a custom API attack tool.
- Allowing the primary key to be changed to another users record, permitting viewing or editing someone else’s account, such as Insecure Direct Object Notation.
- Elevation of privilege. Acting as a user without being logged in, or acting as an admin when logged in as a user.
- Metadata manipulation, such as replaying or tampering with a JSON Web Token (JWT) access control token or a cookie or hidden field manipulated to elevate privileges, or abusing JWT invalidation.
- CORS misconfiguration allows unauthorized API access.
- Force browsing to authenticated pages as an unauthenticated user or to privileged pages as a standard user. Accessing API with missing access controls for POST, PUT and DELETE.
- CSRF vulnerability.
- Deny Access by Default, unless a resource is intended to be publicly accessible, deny access by default. Design an effective access control.
- Wherever possible, use a single application-wide mechanism for enforcing access controls.
- Continuous audit and test access controls to ensure they are working as designed.
- Restrict access to resources located outside of a given domain by minimizing CORS.
- Disable Web Server Directory Listing.
- Rate limit API and controller access to minimize the harm from automated attack tooling.
- Force All Requests to Go Through some sort of Access Control Checks.
- Give As Least or As Little Necessary Access as Possible.
Cryptographic Failures refers to the failures related to cryptography which often lead to leak/exposure of sensitive data. In OWASP Top 10 2017 list it is listed as Sensitive Data Exposure. One of the man reason behind sensitive data exposure is the improper cryptographic implementation or not using encryption at all. Some of the issues comes under this category are :
- Sensitive data transmitted (via HTTP, FTP, SMTP, etc) or stored in clear-text (in database, files, etc).
- Use of old or weak cryptographic algorithms.
- Use of weak or default encryption keys or reuse of compromised keys.
- Encryption not enforced or server certificates not validated while communicating with it.
- Analyze all the sensitive data that your application deals with and ensure that it’s encrypted at rest as well as in transit.
- Make use of strong and well-established encryption schemes and if there is a flaw in a scheme being used in the existing apps, make sure to update it.
- Never cache any sensitive data.
- The passwords you are storing must be hashed and salted.
- It is recommended to use a strong hashing algorithm with the use of salts to make password cracking harder.
- Make sure that your system is not suffering from a lousy algorithm setup. Correct the issue immediately upon discovery.
- Ensure that the application is encrypting appropriate data without leaving any critical data vulnerable to attack.
Injection vulnerabilities occurs when web applications process untrusted user supplied data as a part of command or database query without performing any sanitization and checking. The injection vulnerabilities allows an attacker to execute system commands on web server, compromise backend databases and data stores, hijack user sessions etc.
Almost any source of data can be an injection vector, environment variables, parameters, external and internal web services, and all types of users. Injection vulnerabilities are often found in SQL, LDAP, XPath, or NoSQL queries, OS commands, XML parsers, SMTP headers, expression languages, and ORM queries. An application is vulnerable to attack when :
- User supplied data is not validated, filtered, or sanitized by the application.
- Dynamic queries or non-parameterized calls without context aware escaping are used directly in the interpreter.
- Hostile data is used within Object Relational Mapping (ORM) search parameters to extract additional, sensitive records.
- Hostile data is directly used or concatenated, such that the SQL or command contains both structure and hostile data in dynamic queries, commands, or stored procedures.
- Use parameterized queries (prepared statements) instead of string concatenation within sql query.
- Treat all user input as untrusted. Any user input that is used in an SQL query introduces a risk of an SQL Injection. Treat input from authenticated and/or internal users the same way that you treat public input.
- Don’t filter user input based on blacklists. A clever attacker will almost always find a way to circumvent your blacklist. If possible, verify and filter user input using strict whitelists only.
These kind issues when the application is not designed with security in mind. Insecure design is a broad category representing different weaknesses, expressed as “missing or ineffective control design.” Insecure design is not the source for all other Top 10 risk categories. There is a difference between insecure design and insecure implementation, both 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.
One of the factors that contribute to insecure design is the lack of business risk profiling inherent in the software or system being developed, and thus the failure to determine what level of security design is required. For example suppose a website does not have implemented rate limiting against the endpoints of products which is used to add the product in the cart. The website usually sells some of the limited edition products which usually come in the quantity of 100–200 usually. Now since the rate limiting has not been applied some of the malicious user might use bots who regularly check when the product is available and once the product is available they purchase most of their quantity and then resell it. So the users that are genuinely looking for the product don’t get it and due to bots they will never be successful in purchasing a product. so during the design phase the team was not able to consider rate limiting on the endpoints. Hence it was not applied which resulted in the loss of the customers.
Some remediation can help to protect the insecure design vulnerability such as:
- Follow best practices, wherever possible.
- Implementing the Security in the SDLC will help so we usually considers all the factors from threat modeling to vulnerability assessment in SDLC.
- Build things with security-centric mindset.
- Secure design principles must be followed and adhered to for the lifetime of the application/services.
- Code reviews must be done thoroughly to avoid any bad code going into the production.
- Regular code audits and pentests are a good way to ensure the security of your products. It’s a general advice that would help detect and mitigate most of the trivial issues.
Security Misconfiguration is simply defined as failing to implement all the security controls for a server or web application, or implementing the security controls, but doing so with errors. The application might be vulnerable if the application is:
- Missing appropriate security hardening across any part of the application stack, or improperly configured permissions on cloud services.
- Unnecessary features are enabled or installed (e.g. unnecessary ports, services, pages, accounts or privileges, debugging enabled).
- Default accounts and their passwords still enabled and unchanged.
- Error handling reveals stack traces or other overly informative error messages to users.
- For upgraded systems, latest security features are disabled or not configured securely.
- The security settings in the application servers, application frameworks (e.g. Struts, Spring, ASP.NET), libraries, databases, etc. not set to secure values.
- The server does not send security headers or directives or they are not set to secure values.
- The software is out of date or vulnerable.
- Incorrect folder permissions.
- Setup/Configuration pages enabled.
- Disable administration interfaces.
- Disable debugging.
- Disable use of default accounts/passwords.
- Configure server to prevent unauthorized access, directory listing, etc.
- Consider running scans and doing audits periodically to help detect future misconfigurations or missing patches.
Vulnerable and Outdated Components
If the components used to develop applications become outdated or have a serious vulnerability, then it makes the whole application vulnerable to attack. These problems occurs when :
- You do not know the versions of all components you use (both client-side and server-side). This includes components you directly use as well as nested dependencies.
- If software is vulnerable, unsupported, or out of date. This includes the OS, web/application server, database management system (DBMS), applications, APIs and all components, runtime environments, and libraries.
- If you do not scan for vulnerabilities regularly and subscribe to security bulletins related to the components you use.
- If you do not fix or upgrade the underlying platform, frameworks, and dependencies in a risk based, timely fashion. This commonly happens in environments when patching is a monthly or quarterly task under change control, which leaves organizations open to many days or months of unnecessary exposure to fixed vulnerabilities.
- If software developers do not test the compatibility of updated, upgraded, or patched libraries.
- If you do not secure the component’s configurations.
- Maintain an inventory of components you are using and ensure that they are kept up-to-date.
- Remove unused dependencies and components to reduce the attack surface and your liabilities (yes, code is indeed a great liability!).
- Install the components via trusted channels and make sure to validate their integrity. Also, it’s better to use signed packages (if available).
- Be on the lookout for any security patches for the components you are relying on. If the packages you use are not maintained, then either make sure you apply patches yourself or use some alternate component that is well maintained and has a big user-base and supporting community. If possible, then this should actually be done right from the start choose your dependencies and components wisely!.
Identification and Authentication Failures
Authentication identifies the user and confirms that they are who they say they are. These types of issues can happen when an application:.
- Doesn’t prevents automated attacks like credential stuff or brute-forcing to guess passwords.
- Has flaws in the password reset or recovery flows.
- Doesn’t handles (invalidates or rotates) session identifiers after email/password update, logout, inactivity, re-login.
- Permits default, weak, or well-known passwords, such as “Password1” or “admin“.
- Uses weak or ineffective credential recovery and forgot password processes, such as “knowledge based answers”, which cannot be made safe.
- Uses plain text, encrypted, or weakly hashed passwords.
- Has missing or ineffective multifactor authentication.
- Exposes Session IDs in the URL (e.g., URL rewriting).
- Enable and enforce MFA.
- Ensure that default passwords are only for one-time use and are updated as the user logins.
- Enforce a password policy to prevent users from setting weak passwords.
- Rate limit the critical endpoints (and possibly all endpoints) such as login and forgot password and also limit the number of attempts for login and increase delays between 2 or more attempts.
- Session tokens must be secure enough and if you are using randomly generated tokens then ensure that the entropy source is quite good, the tokens are not transmitted in the URLs, and are validated timely and after every logout.
- Get your applications pentested and any code being pushed to production must be reviewed and well tested against such issues (a generic advice, but it helps quite a lot).
Software and Data Integrity Failures
Software and data integrity failures relate to code and infrastructure that does not protect against integrity violations. Use of critical data or apps without verification of their identity falls under this category. This type of issue occurs when the identity of the apps or data is not checked or verification process is not well-rounded.
An example of this is where an application relies upon plugins, libraries, or modules from untrusted sources, repositories, and content delivery networks (CDNs). An insecure CI/CD pipeline can introduce the potential for unauthorized access, malicious code, or system compromise. Lastly, many applications now include auto-update functionality, where updates are downloaded without sufficient integrity verification and applied to the previously trusted application. Attackers could potentially upload their own updates to be distributed and run on all installations. Another example is where objects or data are encoded or serialized into a structure that an attacker can see and modify is vulnerable to insecure deserialization.
- Always ensure that the app you are using is trusted and uses sane security practices.
- As a developer, ensure that the apps are signed and the trusted data sources are also tamper proof.
- Ensure that your CI/CD pipelines are secure and any malicious code doesn’t goes in.
- Audit the code before it makes it to the production.
- Get your software pentested frequently to ensure high security levels.
Security Logging and Monitoring Failures
Generally logging and monitoring help detect, escalate, and respond to active breaches. Without logging and monitoring, breaches cannot be detected. Insufficient logging, detection, monitoring, and active response occurs any time:
- Auditable events, such as logins, failed logins, and high-value transactions, are not logged.
- Logs not backed up, in case of failure of the app server holding the logs locally.
- Warnings and errors generate no, inadequate, or unclear log messages.
- Logs of applications and APIs are not monitored for suspicious activity.
- Logs are only stored locally.
- Appropriate alerting thresholds and response escalation processes are not in place or effective.
- Penetration testing and scans by dynamic application security testing (DAST) tools (such as OWASP ZAP) do not trigger alerts.
- The application cannot detect, escalate, or alert for active attacks in real-time or near real-time.
- Ensure that you log all login and failed attempt.
- Maintain a copy of the logs in case the server suffers issues.
- Ensure that the logs contains all the relevant data and are well-formatted to be consumed by other tools or log management solutions.
- Test if your monitoring systems that can suspicious activity and ensure the alerting is done in near real time.
- Ensure that your logs are tamper-proof.
Server Side Request forgery
- Server side request forgery occurs when a server can be exploited to make requests on behalf of an attacker.
- In a SSRF attack the attacker can change a parameter used on the web application to create or control requests from the vulnerable server.
- The exploitation of a SSRF vulnerability enables attackers to send requests made by the web application, often targeting internal systems behind a firewall. Sometimes a server needs to make URL-request based on user input. A clear example would be an import-function, where you can import images from a URL, perhaps when setting a profile picture. When you as a user enter a URL, the server will make a request to that URL and fetch the image.
Impacts of Server Side Request Forgery
As seen in the above examples, the impact of exploiting a Server Side Request Forgery vulnerability is almost always information disclosure, such as:
- It is possible to scan ports and IP addresses on internal networks.
- Interact with some protocols such as Gopher, which allow you to make further discoveries.
- Discover the IP addresses of servers running behind a reverse proxy.
- Remote code execution.
There are several other things attackers can do when exploiting a SSRF vulnerability, some of which can have more severe consequences, but it mainly depends on how the web application uses the responses from the remote resource.
- Sanitize and validate all client-supplied input data.
- Enforce the URL schema, port, and destination with a positive allow list.
- Do not send raw responses to clients.
- Disable HTTP redirections.
- Maintain an allow-list or a deny-list (or both) of URLs that you would make or deny the requests to, respectively.