โ† Back to oday.com.au
0day ยท oday.com.au

OWASP Top 10 โ€” 2021
Developer Quick Reference

Framework: OWASP Top 10:2021 Audience: Developers & technical leads Contact: hello@oday.com.au
A01
Broken Access Control

What is it?

Users can access data or functions they shouldn't. This includes accessing other users' records, admin pages, or API endpoints by modifying IDs or URLs.

Common examples

  • Changing ?user_id=123 to access another user's data
  • Directly accessing admin URLs while logged in as standard user
  • Insecure direct object references (IDOR)

How to fix

โœ“ Always enforce authorisation server-side

Never rely on client-side checks. Verify every request against the authenticated user's permissions.

// BAD app.get('/invoice/:id', (req, res) => { return db.query('SELECT * FROM invoices WHERE id = ?', [req.params.id]); }); // GOOD โ€” verify ownership app.get('/invoice/:id', auth, (req, res) => { return db.query( 'SELECT * FROM invoices WHERE id = ? AND user_id = ?', [req.params.id, req.user.id] ); });
A02
Cryptographic Failures

What is it?

Sensitive data transmitted or stored without adequate encryption. Includes using weak algorithms, hardcoded keys, or plain-text passwords.

Common examples

  • Passwords stored as MD5 or SHA1 hashes
  • API keys in git repositories
  • HTTP used instead of HTTPS
  • Weak SSL/TLS configuration

How to fix

โœ“ Use bcrypt for passwords, AES-256 for data

Never write your own crypto. Use well-tested libraries.

// BAD โ€” MD5 password hash const hash = crypto.createHash('md5').update(password).digest('hex'); // GOOD โ€” bcrypt with 12+ rounds const bcrypt = require('bcrypt'); const hash = await bcrypt.hash(password, 12);
A03
Injection (SQL, NoSQL, OS Command)

What is it?

Attacker-controlled input is interpreted as code or commands. SQL injection is the most common โ€” attacker injects SQL via form fields or URLs.

Common examples

  • SQL injection via login forms
  • OS command injection in file processing
  • LDAP, XML, XPath injection

How to fix

โœ“ Use parameterised queries โ€” always

Never concatenate user input into SQL strings.

// BAD const q = "SELECT * FROM users WHERE email = '" + email + "'"; // GOOD โ€” parameterised query const q = 'SELECT * FROM users WHERE email = ?'; db.query(q, [email], callback);
A04
Insecure Design

What is it?

Security is an afterthought in the design phase. The application is architecturally weak regardless of how well it's coded.

Common examples

  • Password reset flows that expose tokens in URLs
  • Multi-step processes that skip steps
  • Rate limiting not designed in from the start

How to fix

โœ“ Threat model before you build

Ask: "How would someone abuse this feature?" before writing code. Use secure design patterns.

  • Use server-side tokens for password reset (not user IDs)
  • Enforce rate limits at design time
  • Require re-authentication for sensitive operations
A05
Security Misconfiguration

What is it?

Default credentials, unnecessary features enabled, verbose error messages, missing security headers, or cloud storage left public.

Common examples

  • AWS S3 buckets set to public
  • Default admin passwords not changed
  • Stack traces exposed in production errors
  • Directory listing enabled on web servers

How to fix

โœ“ Harden and audit your config

Remove default credentials. Disable unused features. Review cloud IAM policies regularly.

# Nginx โ€” add security headers add_header X-Frame-Options "DENY"; add_header X-Content-Type-Options "nosniff"; add_header Content-Security-Policy "default-src 'self'"; add_header Strict-Transport-Security "max-age=31536000";
A06
Vulnerable & Outdated Components

What is it?

Using libraries, frameworks, or OS components with known CVEs. Log4Shell, Heartbleed, and most major breaches exploit known-vulnerable components.

Common examples

  • npm packages with known CVEs
  • Outdated WordPress plugins
  • End-of-life PHP or Node versions

How to fix

โœ“ Automate dependency scanning

Use Dependabot, Snyk, or npm audit in CI/CD. Keep a software bill of materials (SBOM).

# Check for vulnerabilities in your project npm audit # or pip-audit # or bundle audit
A07
Identification & Authentication Failures

What is it?

Weak authentication, missing MFA, insecure session management, or credential stuffing vulnerabilities.

Common examples

  • No rate limiting on login โ€” brute-force possible
  • Session tokens not invalidated on logout
  • Weak "remember me" tokens
  • No MFA for privileged accounts

How to fix

โœ“ MFA + rate limiting + secure sessions

Implement MFA for all accounts. Lock accounts after N failures. Use short-lived JWTs.

  • Implement rate limiting: max 5 failed logins before lockout
  • Require MFA for admin accounts โ€” always
  • Invalidate all sessions on password change
  • Use cryptographically secure session IDs (128-bit)
A08
Software & Data Integrity Failures

What is it?

Code and infrastructure that doesn't protect against integrity violations โ€” including insecure CI/CD pipelines, unverified updates, or untrusted deserialisation.

Common examples

  • Auto-update from untrusted sources without signature verification
  • Deserialising untrusted JSON/XML objects
  • CI/CD pipeline with unrestricted access

How to fix

โœ“ Verify all integrity โ€” sign everything

Use subresource integrity (SRI) for CDN assets. Sign release artifacts. Restrict CI/CD pipeline access.

<!-- SRI for CDN scripts --> <script src="https://cdn.example.com/lib.js" integrity="sha384-[hash]" crossorigin="anonymous"></script>
A09
Security Logging & Monitoring Failures

What is it?

Without adequate logging and monitoring, breaches go undetected. The average breach dwell time (time from intrusion to detection) is 200+ days.

What to log

  • All login attempts (success and failure)
  • All admin actions
  • All access control failures
  • API calls with high error rates

How to fix

โœ“ Log, alert, and review

Log security events in a structured format. Alert on anomalies. Review logs weekly at minimum.

// Log authentication events logger.warn({ event: 'auth_failure', user: email, ip: req.ip, timestamp: new Date().toISOString(), reason: 'invalid_credentials' });
A10
Server-Side Request Forgery (SSRF)

What is it?

The server makes HTTP requests to attacker-specified URLs โ€” potentially reaching internal services (AWS metadata, internal APIs) not accessible from the internet.

Common examples

  • URL preview / screenshot features
  • Webhook URL validation
  • PDF generation from user-provided URLs

How to fix

โœ“ Validate and allowlist URLs server-side

Never fetch arbitrary user-provided URLs. Validate against an allowlist and block private IP ranges.

const ALLOWED_HOSTS = ['api.example.com']; function isSafeUrl(url) { const parsed = new URL(url); // Block private IPs and internal hosts if (['localhost','127.0.0.1','169.254.169.254'].includes(parsed.hostname)) return false; return ALLOWED_HOSTS.includes(parsed.hostname); }