OWASP Top 10 Explained: What Every Developer Should Know
What Is OWASP?
The Open Web Application Security Project (OWASP) is a nonprofit foundation that publishes free, open-source resources on web application security. Their most famous publication is the OWASP Top 10 — a ranked list of the most critical web application security risks.
Updated every few years, the Top 10 is the industry standard for web security awareness. It's referenced by PCI DSS, NIST, and virtually every security compliance framework.
A01: Broken Access Control
The #1 vulnerability. Users can act outside their intended permissions — viewing other users' data, modifying records they shouldn't, or escalating privileges.
Real Example
# Insecure: User can access any account by changing the ID
GET /api/users/12345/profile
# Attacker changes to:
GET /api/users/99999/profile # ← Access another user's data
Fix It
- Deny by default — require explicit grants for every resource
- Check ownership on every request:
if article.owner_id != current_user.id: abort(403) - Disable directory listing. Enforce rate limits on APIs.
A02: Cryptographic Failures
Sensitive data exposed due to weak or missing encryption — passwords stored in plaintext, HTTP instead of HTTPS, outdated TLS versions.
Real Example
# BAD: Storing passwords in plaintext
INSERT INTO users (email, password) VALUES ('user@example.com', 'password123');
# GOOD: Use bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
Fix It
- Always use HTTPS (TLS 1.2+). Never store plaintext passwords.
- Use bcrypt/scrypt/argon2 for password hashing. Encrypt data at rest.
- Rotate encryption keys regularly. Disable old TLS/SSL versions.
A03: Injection
Untrusted data sent to an interpreter as part of a command or query. SQL injection is the classic example, but it includes NoSQL, OS command, LDAP, and XPath injection.
Real Example
# VULNERABLE: String concatenation in SQL
query = f"SELECT * FROM users WHERE username = '{username}'"
# Attacker inputs: ' OR '1'='1' --
# SAFE: Parameterized query
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
Fix It
- Use parameterized queries / prepared statements — always
- Use ORMs (SQLAlchemy, Prisma) that handle escaping automatically
- Validate and sanitize all input. Apply least privilege to DB accounts.
A04: Insecure Design
Flaws in the architecture itself — no threat modeling, missing security requirements, business logic vulnerabilities that code-level fixes can't solve.
Real Example
A password reset flow that asks "What's your mother's maiden name?" — a security question attackable via OSINT. The design is insecure, not the implementation.
Fix It
- Threat model during design phase (STRIDE, PASTA)
- Write abuse cases alongside user stories
- Use secure design patterns: defense in depth, zero trust, least privilege
A05: Security Misconfiguration
Default credentials left unchanged, unnecessary services enabled, overly permissive CORS, stack traces exposed to users, missing security headers.
Real Example
# Exposed debug mode in production
FLASK_ENV=development # ← Shows full stack traces to attackers
DEBUG=True
# Server leaking version info
Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/8.1.2
Fix It
- Automate hardening: use security headers (HSTS, CSP, X-Frame-Options)
- Remove default accounts. Disable directory listing and debug modes.
- Regular configuration audits. Use tools like
niktoornmapscripts.
A06: Vulnerable and Outdated Components
Using libraries, frameworks, or OS components with known vulnerabilities. Log4Shell (CVE-2021-44228) affected millions of Java applications.
Fix It
- Run
npm audit,pip-audit, orsnyk testin CI/CD - Subscribe to CVE feeds for your dependencies
- Remove unused dependencies. Pin versions in lockfiles.
A07: Identification and Authentication Failures
Weak passwords allowed, brute force not prevented, session tokens exposed in URLs, no MFA available.
Fix It
- Enforce strong password policies + MFA
- Rate-limit login attempts. Use account lockout (with exponential backoff).
- Rotate session tokens after login. Never expose tokens in URLs.
A08: Software and Data Integrity Failures
Code and infrastructure without integrity verification — auto-updating without signature checks, CI/CD pipeline poisoning, insecure deserialization.
Fix It
- Verify digital signatures on updates and packages
- Use SBOMs (Software Bill of Materials) to track dependencies
- Protect CI/CD pipelines — restrict who can modify build configs
A09: Security Logging and Monitoring Failures
Breaches go undetected because there's no logging, no alerting, and no incident response plan.
Fix It
- Log all authentication events (login, logout, failed attempts)
- Send logs to a SIEM (ELK, Splunk, Wazuh). Set up alerts.
- Test your incident response plan regularly.
A10: Server-Side Request Forgery (SSRF)
The application fetches a URL supplied by the user without validation. Attackers use this to access internal services, cloud metadata endpoints, or other backend systems.
Real Example
# VULNERABLE: Fetching user-supplied URL
import requests
url = request.args.get("url")
response = requests.get(url) # ← Attacker sends http://169.254.169.254/
# Accessing AWS metadata for credentials
http://169.254.169.254/latest/meta-data/iam/security-credentials/
Fix It
- Whitelist allowed domains and protocols (no
file://, no internal IPs) - Block requests to cloud metadata endpoints (169.254.169.254)
- Use a dedicated egress proxy for outbound requests
Checklist for Your Next Project
- ✅ All endpoints enforce authorization (A01)
- ✅ Passwords hashed with bcrypt, data encrypted at rest and in transit (A02)
- ✅ Parameterized queries everywhere (A03)
- ✅ Threat model completed before coding (A04)
- ✅ Security headers set, debug mode off (A05)
- ✅ Dependencies audited in CI/CD (A06)
- ✅ MFA available, rate limiting on auth (A07)
- ✅ Signed updates, protected CI/CD (A08)
- ✅ Logging + alerting configured (A09)
- ✅ URL fetching restricted (A10)
Related Articles
Cross-Site Scripting (XSS) Explained with Real Examples
Understand Cross-Site Scripting (XSS) — reflected, stored, and DOM-based variants. Real payload examples, exploitation demos, and bulletproof prevention.
SQL Injection from Zero: Understand It, Exploit It, Fix It
Learn SQL injection from scratch — understand the vulnerability, exploit it in a safe lab environment, and write secure code that prevents it forever.
AI Model Poisoning Explained: Train a Tiny Model and Break It
Train a tiny ML model in Python, poison its training data, and watch it break. A hands-on walkthrough of label flipping, backdoor attacks, and defenses.
Stay Ahead in AI Security
Get weekly insights on AI threats, LLM security, and defensive techniques. No spam, unsubscribe anytime.
Join security professionals who read CyberBolt.