October 14, 2026
The Hacker’s Cheat Sheet: OWASP Top 10.(2026)
Websites get hacked every day, and most of the time it’s not some Hollywood genius. It’s a basic mistake: a missing permission check, a…

By Nikhilvarun
9 min read
Websites get hacked every day, and most of the time it's not some Hollywood genius. It's a basic mistake: a missing permission check, a default password, a copy-pasted query.
The good news is that the same ten mistakes cause most of the damage. These are listed in the OWASP Top 10. In this post, I'll explain each one in simple words, show how the attack actually happens, and tell you how to fix it.
What is OWASP?
OWASP (Open Worldwide Application Security Project) is a non-profit that helps make software safer. Every few years it publishes a list of the 10 most critical security risks in web applications.
Easy way to remember: Imagine your app is a building. Each risk below is a way a thief can get in: an unlocked door, an open window, a fake delivery guy, and so on.
First, a quick clarification
Searching "OWASP Top 10 2026" can be confusing. OWASP updates its web application list roughly every four years (2017, 2021, 2025). The current edition is officially the OWASP Top 10:2025, and it is the version in force throughout 2026. (OWASP also published a separate Top 10 for LLM Applications 2026, but that's a different list for AI apps.)
Note: all websites, names, emails and passwords shown in the images are fictional and created only for education.
1. Broken Access Control: "Anyone can open any door"
What is it?
The app doesn't properly check who is allowed to see or do what. It's the #1 risk because it shows up in almost every kind of app.
How the attack happens
- You log in to a shopping site and open your invoice:
shop.com/invoice/1001 - You change the number in the URL to
1002 - The server doesn't check whose invoice it is, so it shows you someone else's invoice, with their name, phone number and address
Attackers automate this. A small script tries 1002, 1003, 1004... and downloads thousands of records. This trick is called IDOR (Insecure Direct Object Reference).
Vulnerable code vs fixed code
javascript
// ❌ Bad: returns any invoice:-
const invoice = await db.invoices.findById(req.params.id);
// ✅ Good: only the owner can see it:-
const invoice = await db.invoices.findOne({
id: req.params.id,
userId: req.user.id
});// ❌ Bad: returns any invoice:-
const invoice = await db.invoices.findById(req.params.id);
// ✅ Good: only the owner can see it:-
const invoice = await db.invoices.findOne({
id: req.params.id,
userId: req.user.id
});Bonus: SSRF is part of this category now
SSRF means tricking the server into fetching a URL the attacker chooses, for example internal cloud addresses that hold secret keys. Fix: allow only approved domains and block internal IPs.
How to protect yourself
- Deny by default, and give access only when explicitly allowed
- Check permissions on the server, never only in the browser or app screen
- Test with two different user accounts to see if one can reach the other's data
2. Security Misconfiguration: "Left the window open"
What is it?
Your code may be fine, but the settings are unsafe: default passwords, debug mode on, public cloud storage, unnecessary features enabled. This risk climbed the ranking because modern apps have so many settings (cloud, containers, frameworks).
How the attack happens
- The attacker runs a scanner that checks thousands of sites for common mistakes
- It finds
/admin,/backup.zipand/.envopen to the internet - The login
admin / adminwas never changed, and the debug error page shows database passwords and cloud keys - The attacker connects straight to your database
Companies have leaked millions of records only because a storage bucket was set to "public" by mistake. No hacking skill was needed, only a link.
python
# ❌ Debug mode left on in production
app.run(debug=True)
# ✅ Safe
app.run(debug=False)# ❌ Debug mode left on in production
app.run(debug=True)
# ✅ Safe
app.run(debug=False)How to protect yourself
- Change all default usernames and passwords
- Turn off debug mode and remove unused features
- Never expose files like
.envand backups - Review cloud permissions regularly, and automate the checks
3. Software Supply Chain Failures: (NEW)
What is it?
Modern apps are built using hundreds of other people's libraries. If any one of them is fake, hacked or outdated, your app is at risk too. This category is new in the 2025 list and expands the old "Vulnerable and Outdated Components".
How the attack happens
- An attacker uploads a fake package called
reqeusts(note the typo), hoping someone mistypesrequests - A developer in a hurry types
pip install reqeusts - The package installs normally, but hidden code runs in the background
- It sends the developer's SSH keys,
.envfile and cloud keys to the attacker
This is called typosquatting. Other versions: hacking a real maintainer's account, or tampering with the build pipeline (CI/CD) that creates your app.
// ❌ Risky: accepts any version, even a hacked new one
"lodash": "*"
// ✅ Better: pinned version + lockfile
"lodash": "4.17.21"// ❌ Risky: accepts any version, even a hacked new one
"lodash": "*"
// ✅ Better: pinned version + lockfile
"lodash": "4.17.21"How to protect yourself
- Install only well-known packages and double-check the names
- Commit lockfiles and pin versions
- Scan dependencies regularly (
npm audit, Dependabot) - Limit who can change your build pipeline
4. Cryptographic Failures: "Valuables in a see-through box"
What is it?
Sensitive data (passwords, card numbers, personal info) isn't properly protected. It's either not encrypted at all, or protected with old, weak methods.
How the attack happens
- A user signs up on a site that uses plain HTTP, from a public cafe Wi-Fi
- The attacker on the same Wi-Fi can read the password as it travels over the network
- The site also stores passwords as plain text in its database
- When the database is leaked, every password is readable. People reuse passwords, so their email and bank accounts are in danger too
python
# ❌ Bad
save(password)
hashlib.md5(password.encode())
# ✅ Good: slow, salted, modern hashing
from argon2 import PasswordHasher
save(PasswordHasher().hash(password))# ❌ Bad
save(password)
hashlib.md5(password.encode())
# ✅ Good: slow, salted, modern hashing
from argon2 import PasswordHasher
save(PasswordHasher().hash(password))How to protect yourself
- Use HTTPS everywhere
- Store passwords only as strong hashes (Argon2, bcrypt)
- Never hardcode secret keys in code; use a secrets manager
- Don't collect sensitive data you don't need
5. Injection: "Tricking the app with sneaky input"
What is it?
The attacker types code instead of normal data, and the app mistakenly runs it. The most famous version is SQL Injection. XSS (injecting JavaScript into a page) and command injection also belong here.
How the attack happens (SQL Injection)
Your login code builds the database query by gluing text together:
python
query = f"SELECT * FROM users WHERE email = '{email}' AND password = '{pwd}'"query = f"SELECT * FROM users WHERE email = '{email}' AND password = '{pwd}'"The attacker types this in the email box and leaves the password empty:
' OR '1'='1' --' OR '1'='1' --The query becomes: "find a user where email is empty OR 1 equals 1", which is always true. The attacker is logged in without any password, often as the first user in the table, which is usually the admin. Tools like sqlmap can then automate the theft of the whole database.
Fix: parameterized queries
python
cursor.execute(
"SELECT * FROM users WHERE email = %s AND password_hash = %s",
(email, pwd_hash)
)cursor.execute(
"SELECT * FROM users WHERE email = %s AND password_hash = %s",
(email, pwd_hash)
)Now the input is treated as data only, never as a command.
XSS in one example
javascript
// ❌ Bad: a comment containing <script> will run for every visitor
div.innerHTML = userComment;
// ✅ Good: shown as plain text
div.textContent = userComment;// ❌ Bad: a comment containing <script> will run for every visitor
div.innerHTML = userComment;
// ✅ Good: shown as plain text
div.textContent = userComment;How to protect yourself
- Always use parameterized queries or a trusted ORM
- Validate input (allow only what's expected)
- Encode output before showing it on a page
- Never pass user input into system commands
6. Insecure Design: "The blueprint itself is flawed"
What is it?
This isn't a coding bug. The plan was weak from the start. Even perfect code can't save a badly designed feature.
How the attack happens
- The attacker clicks "Forgot password" on the victim's account
- The only security question is "What's your pet's name?"
- The victim posted about her dog Bruno on Instagram, so the answer is public
- The attacker resets the password, logs in, and drains the wallet
No bug was exploited here. The feature itself was guessable.
More examples
- A coupon system with no limit per user, so bots redeem the same coupon thousands of times
- A ticket site with no limit on seats held, so scalpers lock all seats without paying
- A password reset link that never expires
How to protect yourself
- Do threat modeling before building: ask "How could someone misuse this?"
- Write abuse stories along with user stories
- Use email/OTP reset links instead of guessable questions
- Add limits (rate limits, quotas, expiry times) by design
7. Authentication Failures: "Weak lock on the front door"
What is it?
Problems in how users log in and stay logged in: weak passwords, no attempt limits, bad session handling.
How the attack happens
- A bot (using a tool like Hydra) tries thousands of common passwords on one account:
123456,password,qwerty... This is brute force - Or it takes email/password pairs leaked from other sites and tries them on yours: credential stuffing
- The login has no attempt limit and no OTP, so eventually one password works
- The attacker now sees saved cards, addresses and the wallet balance
Common mistakes
- Allowing weak passwords like
123456 - No limit on wrong attempts
- Guessable session IDs that never expire
- Not logging users out properly
How to protect yourself
- Add rate limiting and temporary lockouts
- Offer multi-factor authentication (OTP, authenticator app, passkeys)
- Block known leaked passwords
- Create a fresh session ID after login and expire sessions on logout
8. Software or Data Integrity Failures: "Not checking the package seal"
What is it?
Your app trusts code or data without verifying that it's genuine. This includes unsigned updates, scripts loaded from outside, and unsafe deserialization.
How the attack happens
- Your checkout page loads a JavaScript file from a third-party CDN
- The attacker hacks that CDN and adds a few lines to the file
- Every visitor to your site now runs the attacker's code
- The code silently sends card number, expiry and CVV to the attacker's server, while the page still looks normal
This kind of attack is known as web skimming (Magecart-style). Another version: an app that accepts serialized data (like Python pickle) from users, letting the attacker run code on your server.
html
<!-- ✅ Integrity check: the browser blocks the file if it was changed -->
<script src="https://cdn.example.com/lib.js"
integrity="sha384-..." crossorigin="anonymous"></script><!-- ✅ Integrity check: the browser blocks the file if it was changed -->
<script src="https://cdn.example.com/lib.js"
integrity="sha384-..." crossorigin="anonymous"></script>python
# ❌ Dangerous with untrusted data
pickle.loads(data)
# ✅ Use a data-only format
json.loads(data)# ❌ Dangerous with untrusted data
pickle.loads(data)
# ✅ Use a data-only format
json.loads(data)How to protect yourself
- Use Subresource Integrity (SRI) for external scripts
- Add a strict Content Security Policy (CSP)
- Verify signatures on updates and downloads
- Never deserialize untrusted data with unsafe formats
9. Security Logging & Alerting Failures: "CCTV that nobody watches"
What is it?
Attacks happen, but your app doesn't record them, or nobody gets notified. The longer an attacker stays unnoticed, the more damage they do.
How the attack happens
- An attacker tries 500 wrong passwords on the admin account
- The app logs nothing and sends no alert
- The attacker gets in and quietly copies customer data, week after week
- The admin dashboard still says "All systems normal"
- The breach is discovered months later, often by an outsider
python
# ❌ Silent failure
except AuthError:
pass
# ✅ Log it and raise an alert if it keeps happening
except AuthError:
logger.warning("login_failed", extra={"user": user, "ip": ip})
alerts.check_threshold("login_failed", ip=ip)# ❌ Silent failure
except AuthError:
pass
# ✅ Log it and raise an alert if it keeps happening
except AuthError:
logger.warning("login_failed", extra={"user": user, "ip": ip})
alerts.check_threshold("login_failed", ip=ip)How to protect yourself
- Log logins, failed logins, permission errors and important transactions
- Keep logs in a safe, central place that attackers can't edit
- Never write passwords or secrets in logs
- Set up real alerts, and have a plan for what to do when one fires
10. Mishandling of Exceptional Conditions: (NEW)
What is it?
When something breaks (a service is down, input is weird, a timeout happens), the app behaves in an unsafe way. This is also a new category in the 2025 list.
How the attack happens
- Your app asks a separate permission service "is this user allowed?"
- The attacker floods that service with requests until it stops responding
- Your code says "if there's an error, return True", so everyone is allowed in while the service is down
- The error page also leaks file paths and database credentials
This is called failing open. The safe approach is failing closed.
python
# Bad: fails open
except Exception:
return True
# Good: fails closed
except Exception:
return False# Bad: fails open
except Exception:
return True
# Good: fails closed
except Exception:
return FalseAnother common mistake: showing raw errors
Showing users messages like Error: table users_db not found at /var/app/db.py line 42 gives attackers free information. Show "Something went wrong (ref: 8F2A)" and keep the details in your private logs.
How to protect yourself
- When in doubt, deny
- Use a global error handler with generic user messages
- Roll back incomplete operations so data isn't left half-changed
- Test failure cases: timeouts, empty input, and services being down
Quick Summary Table
Where can you practice (legally)?
Never test on websites you don't own or don't have written permission to test. Use these safe practice labs instead:
- OWASP Juice Shop: a deliberately vulnerable shop app
- DVWA: Damn Vulnerable Web Application
- PortSwigger Web Security Academy: free guided labs
Final Thoughts
Most big breaches don't come from genius hackers. They come from simple mistakes. The basics fix a huge share of the problems:
- Check permissions on the server
- Never trust user input
- Keep settings and dependencies clean
- Protect passwords and data
- Log, alert, and plan for failure