OWASP Top 10
A deep dive into the most critical web application security risks — and what you need to know as an ethical hacker in 2024.
If you're just getting into web hacking or application security, there's one resource you should commit to memory: the OWASP Top 10. It's not just a list — it's a globally recognised standard for the most critical security risks to web applications. Think of it as your roadmap for both defence and offence.
In a world where apps are the new perimeter and APIs are the lifeline of modern systems, the surface area for attacks is huge. Businesses move fast, developers push code daily, and security often gets left behind.
This post breaks down each OWASP category in plain English, explains why it matters, how attackers exploit it, and what you — as an ethical hacker — should be looking for.
What is OWASP?
The Open Web Application Security Project (OWASP) is a nonprofit foundation dedicated to improving software security. The OWASP Top 10 is their flagship project — a standard awareness document representing the most critical security risks to web applications, updated every few years based on consensus from security experts worldwide.
The latest version was released in 2021, with significant changes from the 2017 list, reflecting the evolving threat landscape.
Why the Top 10 Matters
For Developers
A checklist of what NOT to do when building applications
For Security Professionals
A framework for testing and assessing application security
For Organizations
A baseline for security requirements and compliance
Access control determines who can do what in a system — whether that's reading data, modifying content, or accessing admin functions.
When access control is broken, users can perform actions they shouldn't be able to. For example: changing your user ID in a URL and seeing someone else's account details.
Common Vulnerabilities
- Insecure Direct Object References (IDOR) - manipulating IDs to access unauthorized resources
- Bypassing access control checks by modifying the URL or HTML page
- Allowing API access without proper authentication
- Elevation of privilege - acting as a user without being logged in
- Metadata manipulation (e.g., replaying or tampering with JWT tokens)
- CORS misconfiguration allowing unauthorized API access
Real-World Example
In 2019, a major social media platform had a vulnerability where changing the user ID in an API request allowed attackers to post content on behalf of any user, including celebrities and politicians. The bug was discovered by a security researcher and reported through their bug bounty program.
How to Test for Broken Access Control
1.Identify all access control points in the application (URLs, APIs, functions)
2.Map out different user roles and their expected permissions
3.Test vertical access controls (privilege escalation) by attempting admin functions as a regular user
4.Test horizontal access controls by accessing resources belonging to other users at the same privilege level
5.Check for insecure direct object references by manipulating IDs in requests
🔍 Hacker Tips
- Intercept requests with Burp Suite and test IDORs by modifying object IDs
- Try accessing admin endpoints directly (e.g.,
/admin,/dashboard) - Modify JWT tokens and see if the application still accepts them
- Test API endpoints with different HTTP methods (GET, POST, PUT, DELETE)
- Check if you can access resources after logging out
# Original request to view your profile
GET /api/users/profile/1337 HTTP/1.1
Host: vulnerable-app.com
Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# Modified request to view someone else's profile
GET /api/users/profile/1338 HTTP/1.1
Host: vulnerable-app.com
Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Encryption protects data — both in transit and at rest. Cryptographic failures often come down to not encrypting sensitive data, using outdated algorithms, or exposing data in logs.
Think passwords stored in plaintext, or credit card details passed over HTTP.
Common Vulnerabilities
- Transmitting sensitive data over unencrypted connections (HTTP instead of HTTPS)
- Using weak cryptographic algorithms (MD5, SHA1, DES)
- Hardcoded encryption keys in source code
- Weak key generation or management
- Not enforcing encryption through HTTP security headers
- Using deprecated or weak SSL/TLS protocols
Real-World Example
In 2017, Equifax suffered a massive data breach affecting 147 million people. The breach exposed names, SSNs, birth dates, addresses, and driver's license numbers. One of the contributing factors was the failure to encrypt sensitive personal data within their internal databases.
How to Test for Cryptographic Failures
1.Identify all sensitive data processed by the application
2.Check if data is transmitted over encrypted channels (HTTPS)
3.Verify SSL/TLS configuration for known vulnerabilities
4.Examine how passwords and sensitive data are stored
5.Check for sensitive data in logs, error messages, or client-side code
🔍 Hacker Tips
- Use tools like
testssl.shorsslyzeto check for weak cipher suites - Inspect browser storage (localStorage, sessionStorage) for sensitive data
- Check if JWTs or other tokens contain sensitive information and if they're properly protected
- Look for API responses that might contain more data than what's displayed
- Search source code for encryption keys, passwords, or API tokens
# Weak: MD5 hash (easily cracked)
5f4dcc3b5aa765d61d8327deb882cf99 # "password"
# Strong: Argon2id with salt and high work factor
$argon2id$v=19$m=65536,t=3,p=4$c2FsdHNhbHRzYWx0$WwD2/wGGTuw7u4BW8sLM0Q
One of the oldest tricks in the book. Injection attacks happen when untrusted input is sent to an interpreter. SQL injection is the classic example — but don't sleep on LDAP, OS command, and NoSQL injection either.
You'd be surprised how many modern APIs are still vulnerable.
SQL Injection
SQL injection occurs when an attacker can insert or "inject" malicious SQL code into a query that an application sends to its database. This can allow attackers to read sensitive data, modify database data, execute admin operations, or even recover files from the system.
// Vulnerable PHP code
$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
// Secure PHP code with prepared statements
$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
🔍 SQL Injection Attack Vectors
- Classic injection:
' OR 1=1 -- - Union-based:
' UNION SELECT username, password FROM users -- - Error-based:
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) -- - Blind SQL injection:
' AND (SELECT SUBSTRING(username,1,1) FROM users WHERE id=1)='a' -- - Time-based:
' AND IF(SUBSTRING(username,1,1)='a', SLEEP(5), 0) --
Real-World Example
In 2017, Equifax suffered a massive data breach affecting 147 million people. The attackers exploited a vulnerability in Apache Struts that allowed for remote code execution through a command injection vulnerability. The breach exposed names, SSNs, birth dates, addresses, and driver's license numbers.
🔍 Hacker Tips
- Test every input field. Send special characters like
' or 1=1 --and see how the app reacts - Use automated tools like SQLmap for SQL injection testing
- Check for blind injection vulnerabilities where there's no direct output
- Test GraphQL endpoints for injection vulnerabilities
- Look for error messages that might reveal database structure
- Try different encoding techniques to bypass filters (URL encoding, hex encoding)
This is about flawed thinking — not bugs. Apps that trust client-side validation, expose internal logic, or lack proper threat models fall into this category.
If a design assumes users will "do the right thing," it's likely insecure.
Common Design Flaws
- Relying solely on client-side validation
- Missing rate limiting on critical functions
- Allowing unlimited attempts for sensitive operations
- Exposing sensitive business logic to the client
- Lack of proper data segregation between tenants
- Insufficient authorization checks in multi-step processes
Real-World Example
A major e-commerce platform had a design flaw in their gift card system. Users could apply a gift card to an order, then remove items from the cart without the gift card balance being recalculated. This allowed attackers to make multiple small purchases with the same gift card balance, effectively stealing merchandise.
How to Identify Insecure Design
1.Map out the application's business logic and workflows
2.Identify critical functions and sensitive operations
3.Test for race conditions in multi-step processes
4.Check for missing rate limits and anti-automation controls
5.Look for ways to bypass intended workflows
🔍 Hacker Tips
- Look for flows that can be abused logically — like reusing gift cards or bypassing business rules
- Test for race conditions by making simultaneous requests
- Try skipping steps in multi-step processes
- Check if you can manipulate quantities or prices after server validation
- Look for ways to abuse features for unintended purposes
// Frontend validation only
function validateCoupon() {
const coupon = document.getElementById('coupon').value;
if (coupon === 'DISCOUNT50') {
applyDiscount(50);
}
}
// Server-side validation
app.post('/apply-coupon', (req, res) = {
const { coupon } = req.body;
db.coupons.findOne({ code: coupon, valid: true }, (err, result) = {
if (result) {
// Apply discount server-side
}
});
});
The low-hanging fruit of the Top 10. It includes everything from exposed admin panels and directory listings to verbose error messages leaking stack traces.
This is often what gives an attacker the first foothold — and sometimes, it's all they need.
Common Misconfigurations
- Default credentials left unchanged
- Unnecessary features enabled (e.g., directory listing)
- Debugging enabled in production
- Outdated or vulnerable software
- Missing security headers
- Default accounts left enabled
- Overly verbose error messages
- Cloud storage with public access
Real-World Example
In 2019, a major financial services company exposed over 100 million customer records due to a misconfigured AWS S3 bucket. The attacker was able to access sensitive customer data because the cloud storage was configured with excessive permissions, allowing public access to private data.
How to Test for Security Misconfigurations
1.Check for default credentials on all systems and components
2.Scan for unnecessary open ports and services
3.Review HTTP headers for missing security controls
4.Test error handling to check for information disclosure
5.Check cloud storage permissions and access controls
🔍 Hacker Tips
- Scan for common admin paths (
/admin,/phpmyadmin), check response headers, and look for open ports - Use tools like Shodan to find exposed services and interfaces
- Check for directory listing by accessing folders directly
- Trigger errors to see if they reveal sensitive information
- Look for development features left enabled in production
- Check for missing security headers like CSP, X-Frame-Options, etc.
# Missing Security Headers
HTTP/1.1 200 OK
Server: Apache/2.4.29 (Ubuntu)
Content-Type: text/html; charset=UTF-8
# Secure Headers
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: no-referrer-when-downgrade
Modern apps rely heavily on third-party packages. If those components are outdated or unpatched, your app inherits their vulnerabilities.
Examples? Think Log4Shell, or that ancient jQuery version still running on a government site.
Common Vulnerable Components
- Outdated frontend libraries (jQuery, Bootstrap, etc.)
- Unpatched server software (Apache, Nginx, etc.)
- Legacy frameworks with known vulnerabilities
- Unmaintained dependencies in package managers
- Outdated CMS plugins and themes
- Vulnerable JavaScript libraries loaded from CDNs
Real-World Example
In 2021, the Log4Shell vulnerability (CVE-2021-44228) affected millions of systems using the popular Log4j logging library. This critical vulnerability allowed attackers to execute arbitrary code on affected servers by sending specially crafted requests. Many organizations were impacted because Log4j was deeply embedded in numerous applications and services.
How to Test for Vulnerable Components
1.Inventory all components and dependencies used in the application
2.Check versions against known vulnerability databases
3.Scan client-side JavaScript libraries for known vulnerabilities
4.Review update and patch management processes
5.Check for components that are no longer maintained
🔍 Hacker Tips
- Use tools like
retire.js,npm audit, ordependency-checkto find outdated libraries - Check HTTP response headers for server software versions
- Look at HTML source for JavaScript library versions
- Use Wappalyzer or similar tools to identify technologies in use
- Search for known exploits for identified components on ExploitDB or CVE databases
# npm audit output
$ npm audit
found 24 vulnerabilities (8 low, 10 moderate, 6 high)
run `npm audit fix` to fix them
# High severity vulnerability
Package: lodash
Severity: high
Prototype Pollution in lodash
CVE-2019-10744
# HTTP Server Header
Server: Apache/2.4.29 (Ubuntu)
# JavaScript Library in HTML Source
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
# WordPress Version in Source
<meta name="generator" content="WordPress 4.7.5" />
Weak authentication is a goldmine. It includes bad session handling, lack of MFA, and even user enumeration on login screens.
If you can guess someone's password, hijack their session, or brute force your way in — this is where it lives.
Common Authentication Vulnerabilities
- Weak password policies allowing easily guessable passwords
- Credential stuffing vulnerabilities (no protection against known breached passwords)
- Missing or ineffective multi-factor authentication
- Exposed session identifiers in URLs
- Session fixation attacks
- Insecure "forgot password" flows
- Plain text, encrypted, or weakly hashed passwords
- User enumeration vulnerabilities
Real-World Example
In 2019, a major social media platform discovered they had been storing hundreds of millions of user passwords in plaintext within their internal systems. While there was no evidence of abuse, this represented a significant authentication failure that could have led to account compromises if the data had been breached.
How to Test for Authentication Failures
1.Test password policies by attempting to create weak passwords
2.Check for user enumeration in login, registration, and password reset
3.Test session management (timeout, invalidation after logout)
4.Attempt credential stuffing with known username/password pairs
5.Test for default or weak credentials
🔍 Hacker Tips
- Look for missing rate limits, weak password policies, and session IDs in URLs
- Test password reset functionality for vulnerabilities
- Check if you can use old session tokens after logout
- Look for different error messages that reveal valid usernames
- Test for multi-factor authentication bypass techniques
- Check if "remember me" functionality is implemented securely
# Response for invalid username
"error": "Username not found"
# Response for valid username but wrong password
"error": "Incorrect password"
# Secure generic response
"error": "Invalid username or password"
# Session ID in URL (insecure)
https://example.com/account?sessionid=1234567890
# Missing secure/httpOnly flags on cookies
Set-Cookie: sessionid=1234567890; Path=/
# Secure cookie implementation
Set-Cookie: sessionid=1234567890; Path=/; Secure; HttpOnly; SameSite=Strict
This is about supply chain trust. When you rely on code or data from external sources and don't verify its integrity, you open the door for attackers.
CI/CD pipelines that auto-deploy unverified packages are a prime example.
Common Integrity Failures
- Using plugins, libraries, or modules from untrusted sources
- Auto-updating software without integrity checks
- Insecure CI/CD pipelines without proper code signing
- Unsigned or unverified application updates
- Deserialization of untrusted data
- Using unsigned JavaScript libraries from CDNs
Real-World Example
The SolarWinds supply chain attack in 2020 involved attackers compromising the software build system to insert malicious code into product updates. When customers installed the legitimate-looking updates, they unknowingly installed a backdoor that gave attackers access to their systems. This affected thousands of organizations, including government agencies and major corporations.
How to Test for Integrity Failures
1.Review update mechanisms for integrity verification
2.Check for unsigned code or libraries loaded from external sources
3.Test deserialization functions with malicious data
4.Review CI/CD pipeline security controls
5.Check for subresource integrity on external scripts
🔍 Hacker Tips
- Check for unsigned updates, weak download checks, or CDN scripts injected into apps
- Look for deserialization of user-controlled data
- Test if the application verifies the integrity of plugins or extensions
- Check if external JavaScript resources use Subresource Integrity (SRI) attributes
- Review how the application handles updates and patches
# No integrity check (vulnerable)
<script src="https://cdn.example.com/library.js"></script>
# With Subresource Integrity (secure)
<script src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
# Vulnerable PHP deserialization
$data = unserialize($_GET['data']);
# Safer approach
$data = json_decode($_GET['data'], true);
// Or with allowed classes only
$data = unserialize($_GET['data'], ['allowed_classes' = ['SafeClass']]);
What happens after the hack? If no one's watching — nothing.
Poor logging means you can't detect breaches, trace exploits, or meet compliance. Many companies don't find out they were hacked until months later — or someone tweets about it.
Common Logging and Monitoring Failures
- Auditable events not being logged (login attempts, high-value transactions)
- Logs not containing enough detail for forensic analysis
- Logs not being monitored for suspicious activity
- Alerts not being generated for suspicious activity
- Penetration testing and scans not triggering alerts
- Logs only stored locally
- Inappropriate log levels (debug in production)
- Sensitive data stored in logs
Real-World Example
In 2017, Equifax suffered a massive data breach that went undetected for 76 days. The breach was eventually discovered when they noticed suspicious traffic from one of their web applications. Proper logging and monitoring could have detected the initial compromise much earlier, potentially limiting the damage.
How to Test for Logging and Monitoring Failures
1.Attempt to perform malicious actions and check if they're logged
2.Review log content for sensitive information
3.Check if logs are protected from unauthorized access
4.Verify if high-risk actions trigger alerts
5.Test log storage and retention policies
🔍 Hacker Tips
- As a red teamer, you might test this by seeing how long you can stay in the system undetected
- Try to perform actions that should trigger security alerts
- Check if logs contain sensitive information that could be exploited
- Look for ways to tamper with or clear logs
- Test if the application logs failed login attempts and other security events
# Insufficient logging
[2023-04-15] Login failed
[2023-04-15] User logged in
[2023-04-15] Database query executed
# Proper logging with context
[2023-04-15T14:22:31.645Z] [WARNING] Login failed for user 'admin' from IP 192.168.1.100 using Firefox/98.0
[2023-04-15T14:23:05.127Z] [INFO] User 'john.doe' logged in successfully from IP 192.168.1.101 using Chrome/99.0
[2023-04-15T14:25:12.389Z] [INFO] User 'john.doe' accessed resource '/api/users/123' with GET method
SSRF is when an attacker tricks a server into making requests on their behalf. This can expose internal services, metadata, or cloud environments like AWS.
It's sneaky, powerful, and increasingly common with microservices and APIs.
Common SSRF Vulnerabilities
- URL input fields that fetch remote resources
- Webhook functionality
- PDF generators that can include remote content
- Document importers (XML, Word, etc.)
- Image processors that fetch remote images
- API integrations that forward requests
Real-World Example
In 2019, a security researcher discovered an SSRF vulnerability in a major cloud service provider that allowed access to the metadata service. This could have potentially exposed sensitive information like access keys and user data. The company awarded a significant bug bounty for the finding.
How to Test for SSRF
1.Identify all features that fetch remote resources
2.Test with internal IP addresses and localhost
3.Try accessing cloud metadata endpoints
4.Use different protocols (file://, dict://, gopher://)
5.Test for DNS rebinding attacks
🔍 Hacker Tips
- Try supplying URLs in fields (e.g. image upload) like
http://169.254.169.254— a known AWS metadata endpoint - Use Burp Collaborator or similar tools to detect blind SSRF
- Try URL encoding or double encoding to bypass filters
- Use DNS rebinding to bypass hostname-based restrictions
- Look for indirect SSRF in PDF generators, webhooks, and file importers
# Basic SSRF
http://localhost:8080/admin
http://127.0.0.1:8080/admin
# Cloud metadata endpoints
http://169.254.169.254/latest/meta-data/
http://metadata.google.internal/
# Alternative protocols
file:///etc/passwd
dict://internal-service:11211/
# Vulnerable Node.js code
app.get('/fetch', (req, res) = {
const url = req.query.url;
fetch(url)
.then(response = response.text())
.then(data = res.send(data));
});
# Safer implementation
const allowlist = ['api.example.com', 'api.trusted.com'];
app.get('/fetch', (req, res) = {
const url = new URL(req.query.url);
if (!allowlist.includes(url.hostname)) {
return res.status(403).send('Forbidden');
}
// Proceed with request
});
OWASP isn't about memorising a list — it's about developing a mindset. You're looking at how apps handle trust, process logic, and respond to bad input. The top 10 risks will keep evolving, but your approach should always be the same: think critically, test everything, and dig deeper than surface-level bugs.
Whether you're starting out or preparing for certs like OSCP, bug bounties, or red teaming — this is your baseline. Learn it well, and you'll be far ahead of most.
Key Takeaways
- Security is a mindset, not a checklist — understand the underlying principles
- Modern applications have complex attack surfaces — stay updated on new vulnerability types
- Many vulnerabilities are combinations of multiple issues — look for chains of weaknesses
- The most effective hackers think like developers first, then like attackers
- Documentation and clear communication are as important as finding vulnerabilities
💡 Pro tip: Practise with tools like OWASP Juice Shop or DVWA, and always read bug bounty writeups — they're gold for real-world tactics.
Practice Environments
- OWASP Juice Shop
Modern vulnerable web application with a complete shopping experience
- Damn Vulnerable Web App (DVWA)
PHP/MySQL web application with intentional vulnerabilities
- PortSwigger Web Security Academy
Free, hands-on labs covering all web security topics
- Hack The Box
Online platform with realistic machines and web challenges
Essential Tools
- Burp Suite
The industry standard for web application security testing
- OWASP ZAP
Free and open-source web app scanner
- SQLmap
Automated SQL injection and database takeover tool
- Kali Linux
Security-focused Linux distribution with hundreds of tools
Recommended Reading
The Web Application Hacker's Handbook
Comprehensive guide to finding and exploiting security flaws
Real-World Bug Hunting
A field guide to web hacking with real-world examples
Bug Bounty Bootcamp
The guide to finding and reporting web vulnerabilities