OWASP Top 10 (2021) With Examples
1. Broken Access Control
Broken Access Control occurs when an application doesn’t properly enforce restrictions on what authenticated users are allowed to do. This can allow attackers to access unauthorized functionality or data. Here are three examples:
URL Manipulation: A web application uses a parameter in the URL to determine what content to display, like
example.com/profile?user_id=123
. A user changes theuser_id
to456
and gains access to another user’s profile without proper authorization checks on the server side.Insecure Direct Object References (IDOR): An e-commerce site lets users view their order history via a link like
example.com/orders/789
. An attacker guesses or iterates through order IDs (e.g.,example.com/orders/790
) and views other customers’ order details because the server doesn’t verify the user’s ownership of the requested resource.Privilege Escalation via Missing Role Checks: A content management system has an admin feature to delete posts, accessible at
example.com/admin/delete?post_id=101
. A regular user discovers this endpoint and uses it to delete posts, as the server fails to check if the user has admin privileges before processing the request.
These examples highlight how weak access controls can expose sensitive data or functionality to unauthorized users.
2. Cryptographic Failures
Cryptographic Failures occur when sensitive data isn’t properly protected due to weak or missing encryption, outdated algorithms, or poor key management. Here are three examples:
Using Outdated Encryption Algorithms: A web application encrypts user passwords with MD5, an obsolete and easily cracked hashing algorithm. Attackers intercept the hashed passwords and use precomputed rainbow tables to quickly recover the original plaintext passwords.
Transmitting Data Without Encryption: An online banking app sends account details over an unencrypted HTTP connection instead of HTTPS. Attackers on the same network can eavesdrop and capture sensitive information like account numbers and balances in plain text.
Hardcoded Encryption Keys: A mobile app stores its encryption key in the source code (e.g.,
key = "secret123"
). An attacker decompiles the app, extracts the key, and decrypts sensitive user data stored locally on the device, bypassing any security measures reliant on that key.
These cases show how cryptographic weaknesses can leave critical data vulnerable to interception or unauthorized access.
3. Injection
Injection happens when untrusted data is interpreted as part of a command or query, allowing attackers to manipulate an application’s behavior. Here are three examples:
SQL Injection: A login form accepts a username and password, constructing a query like
SELECT * FROM users WHERE username = 'input' AND password = 'input'
. An attacker enters' OR '1'='1
as the username, turning the query intoSELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'input'
, bypassing authentication and logging in without valid credentials.Command Injection: A web app lets users ping an IP address by running a system command like
ping [user_input]
. An attacker inputs8.8.8.8 && rm -rf /
, which executesping 8.8.8.8
followed by a destructive command to delete files, because the input isn’t sanitized or validated before being passed to the operating system.Cross-Site Scripting (XSS): A forum allows users to post comments, which are displayed without escaping special characters. An attacker submits
<script>alert('Hacked');</script>
as a comment. When other users view the page, the script executes in their browsers, potentially stealing cookies or redirecting them to malicious sites.
These examples illustrate how injection vulnerabilities let attackers manipulate systems or data by sneaking malicious input past inadequate defenses.
4. Insecure Design
Insecure Design refers to flaws in the architecture or design of an application that create security weaknesses, often because security wasn’t prioritized from the start. Unlike implementation bugs, these stem from poor planning. Here are three examples:
Lack of Input Validation in Design: A payment system is designed to trust all client-side data without server-side checks. Users can submit a form claiming they paid $1 for a $100 item by altering the
amount
field in the browser’s developer tools, and the system processes it because no validation was built into the design to verify transactions.No Rate Limiting on Authentication: An app’s login system is designed without any mechanism to limit login attempts. Attackers can perform brute-force attacks, trying thousands of password combinations per second, because the design didn’t account for protecting against such abuse, leaving accounts vulnerable.
Inadequate Separation of Privileges: A cloud storage app gives all users the same access level to a shared database in its design, intending to filter permissions in the UI. An attacker exploits an API endpoint (e.g.,
GET /files/all
) that wasn’t meant to be public, accessing everyone’s files because the design didn’t enforce strict access controls at the data layer.
These cases show how failing to bake security into the design phase can leave applications exposed, even if the code itself is bug-free.
5. Security Misconfiguration
Security Misconfiguration occurs when systems, applications, or frameworks are not securely set up, leaving them vulnerable due to default settings, unnecessary features, or oversight. Here are three examples:
Default Admin Credentials Left Unchanged: A web server is deployed with its default admin username and password (e.g.,
admin:admin
) still active. An attacker discovers the login page, uses the well-known defaults, and gains full control because the administrator never changed them during setup.Directory Listing Enabled: A web application runs on a misconfigured server where directory indexing is turned on. Visiting
example.com/uploads/
reveals a list of all files in that directory, including sensitive ones likebackup.zip
orusers.csv
, which attackers can download because the server wasn’t configured to disable this feature.Verbose Error Messages Exposed: An API is set up to return detailed stack traces in error responses during production (e.g., “Database connection failed: user ‘dbuser’ at host ‘192.168.1.10’”). An attacker triggers an error, sees internal system details like database IPs and credentials, and uses this info to plan further attacks, all because debugging wasn’t disabled.
These examples highlight how simple oversights or lazy defaults in configuration can open the door to exploitation.
6. Vulnerable and Outdated Components
Vulnerable and Outdated Components refers to the use of software libraries, frameworks, or dependencies that have known security flaws or are no longer supported with updates. Here are three examples:
Old Version of a Web Framework: A site runs on Apache Struts 2.3.x, a version known to have a remote code execution vulnerability (e.g., CVE-2017-5638). An attacker sends a crafted HTTP request exploiting this flaw, executing commands on the server because the developers didn’t update to a patched version.
Unpatched Library with a Known Exploit: An application uses an outdated version of the Jackson JSON library (e.g., 2.9.4) with a deserialization vulnerability (CVE-2019-12384). Attackers send a malicious JSON payload, triggering the flaw to run arbitrary code, since the app never upgraded to a secure release.
End-of-Life Software: A company’s internal tool relies on Microsoft Windows Server 2003, which reached end-of-life in 2015 and no longer receives security patches. Attackers exploit an unpatched SMB vulnerability (e.g., like those used in WannaCry), compromising the system because the outdated OS wasn’t replaced.
These cases show how failing to keep components current or monitor their security status can leave applications exposed to well-known, preventable attacks.
7. Identification and Authentication Failures
Identification and Authentication Failures occur when systems fail to properly verify who a user is or allow unauthorized access due to weak authentication mechanisms. Here are three examples:
Weak Password Policies: An application allows passwords like
1234
orpassword
with no complexity requirements. An attacker easily guesses a user’s password or uses a basic brute-force tool to gain access, exploiting the lack of enforced strength in the authentication design.Session Fixation: A web app doesn’t regenerate session IDs after login. An attacker sends a victim a link with a pre-set session ID (e.g.,
example.com?sessionid=abc123
), waits for them to log in, then hijacks the session using the same ID to access their account, because the system failed to invalidate or refresh it.Credential Stuffing Due to No Multi-Factor Authentication (MFA): An online service relies solely on username and password for login, with no MFA option. Attackers use leaked credentials from another breach (e.g.,
user:pass123
) and successfully log in, since the system doesn’t require a second factor to verify identity.
These examples demonstrate how flaws in authentication processes can let attackers impersonate legitimate users with relative ease.
8. Software and Data Integrity Failures
Software and Data Integrity Failures occur when an application’s code, data, or dependencies lack mechanisms to ensure they haven’t been tampered with or corrupted, often due to insecure update processes or unverified sources. Here are three examples:
Unsigned Software Updates: A mobile app downloads updates over HTTP from
example.com/update.apk
without verifying a digital signature. An attacker performs a man-in-the-middle attack, replacing the update with a malicious version that steals user data, exploiting the app’s failure to ensure update integrity.Insecure Deserialization: A server accepts serialized user data (e.g., a Java object) from a client without validating its integrity. An attacker crafts a malicious payload that, when deserialized, executes harmful code—like deleting files—because the system blindly trusts the input’s structure and content.
Unverified Dependency in CI/CD Pipeline: A development team uses a third-party library from a public repository (e.g., npm or PyPI) without checking its authenticity. Attackers compromise the library’s supply chain, injecting backdoor code that ends up in the production app, undetected due to no integrity checks on dependencies.
These cases show how failing to protect the trustworthiness of software and data can lead to unauthorized changes or execution of malicious code.
9. Security Logging and Monitoring Failures
Security Logging and Monitoring Failures occur when an application doesn’t adequately record security events or track suspicious activity, making it hard to detect, respond to, or investigate breaches. Here are three examples:
No Logging of Failed Login Attempts: A web app doesn’t record unsuccessful login attempts. An attacker performs a brute-force attack, trying thousands of passwords, and eventually succeeds, but the breach goes unnoticed because there’s no log to alert admins or trigger an account lockout.
Insufficient Log Details: A cloud service logs access to sensitive files but only records timestamps, omitting user IDs or IP addresses. When a data leak occurs, investigators can’t trace who accessed the files or from where, hampering the ability to identify the attacker due to incomplete logging.
Lack of Real-Time Monitoring: An e-commerce platform logs payment transactions but doesn’t actively monitor for anomalies, like a single user making hundreds of purchases in minutes. An attacker exploits a stolen credit card undetected for hours, as the system lacks alerts or automated checks to flag unusual behavior.
These examples illustrate how weak logging and monitoring can leave systems blind to attacks, delaying detection and response.
10. Server-Side Request Forgery (SSRF)
SSRF occurs when an attacker manipulates a server into making unintended requests to internal or external resources, often bypassing security controls. Here are three examples:
Accessing Internal Metadata in Cloud Environments: A web app allows users to input a URL for fetching content (e.g.,
example.com/fetch?url=[input]
). An attacker submitshttp://169.254.169.254/latest/meta-data/
, tricking the server into requesting AWS instance metadata, exposing sensitive info like IAM credentials because the server doesn’t restrict internal requests.Port Scanning via SSRF: An API accepts a user-provided URL to check its status and blindly sends a request. An attacker inputs
http://localhost:3306
, causing the server to attempt a connection to the internal MySQL port. By iterating through ports, they map the server’s network, exploiting the lack of input validation.Bypassing Firewall to Hit External Services: A content preview service fetches images from user-supplied URLs. An attacker submits
http://malicious-site.com/exploit
, forcing the server to request a malicious resource outside the firewall. The server, trusted by other systems, unwittingly delivers the payload or exposes its own IP, as it doesn’t block or whitelist external destinations.
These examples show how SSRF can turn a server into an unwitting proxy for attackers to probe or exploit systems it has access to.