- Published on
Web Security OWASP Top 10 Complete Guide 2025: 10 Vulnerabilities Every Developer Must Prevent
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction: Why Every Developer Must Know Security
- 1. OWASP Top 10 Overview
- 2. A01: Broken Access Control
- 3. A02: Cryptographic Failures
- 4. A03: Injection
- 5. A04: Insecure Design
- 6. A05: Security Misconfiguration
- 7. A06: Vulnerable and Outdated Components
- 8. A07: Identification and Authentication Failures
- 9. A08: Software and Data Integrity Failures
- 10. A09: Security Logging and Monitoring Failures
- 11. A10: Server-Side Request Forgery (SSRF)
- 12. Beyond OWASP: Additional Vulnerabilities
- 13. Security Headers Complete Guide
- 14. Security Testing Tools
- 15. Production Security Checklist (20 Items)
- 16. Interview Questions (15)
- 17. Quiz
- References
Introduction: Why Every Developer Must Know Security
According to IBM's 2024 Cost of a Data Breach Report, the average cost of a data breach is $4.88 million. Even more alarming is that roughly 70% of breaches originate from application-level vulnerabilities.
Security is not just the security team's responsibility. Every developer writing code is the first line of defense. OWASP (Open Web Application Security Project) periodically publishes the ten most critical web application security risks.
This guide analyzes each OWASP Top 10 2021 vulnerability with real code examples and provides defense strategies and production checklists.
1. OWASP Top 10 Overview
1.1 OWASP Top 10 2021 Rankings
| Rank | Category | Change from 2017 |
|---|---|---|
| A01 | Broken Access Control | Rose from 5th to 1st |
| A02 | Cryptographic Failures | Rose from 3rd (renamed) |
| A03 | Injection | Dropped from 1st to 3rd |
| A04 | Insecure Design | New entry |
| A05 | Security Misconfiguration | Rose from 6th to 5th |
| A06 | Vulnerable and Outdated Components | Rose from 9th to 6th |
| A07 | Identification and Authentication Failures | Dropped from 2nd to 7th |
| A08 | Software and Data Integrity Failures | New (split from 8th) |
| A09 | Security Logging and Monitoring Failures | Rose from 10th to 9th |
| A10 | Server-Side Request Forgery (SSRF) | New entry |
1.2 Key Changes from 2017
Injection dropped from 1st to 3rd because frameworks have improved their default defense mechanisms. Meanwhile, Broken Access Control rose to 1st due to the proliferation of API-based architectures increasing authorization mistakes.
Insecure Design (A04) and SSRF (A10) entered as new categories, reflecting emerging attack vectors in cloud-native and microservices architectures.
2. A01: Broken Access Control
2.1 Overview
Broken Access Control occurs when users can act beyond their intended permissions. It was found in 94% of applications tested.
2.2 Attack Scenario
IDOR (Insecure Direct Object Reference):
# Attacker changes the ID in the URL to access another user's data
GET /api/users/12345/profile -> own profile
GET /api/users/12346/profile -> another user's profile (unauthorized!)
2.3 Vulnerable Code
// Vulnerable - no ownership check
app.get('/api/users/:id/profile', async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user); // Anyone with the ID can access!
});
// Vulnerable - role check but no resource ownership check
app.delete('/api/posts/:id', requireRole('user'), async (req, res) => {
await Post.findByIdAndDelete(req.params.id); // Can delete others' posts!
res.json({ message: 'Deleted' });
});
2.4 Secure Code
// Secure - ownership verification
app.get('/api/users/:id/profile', authenticate, async (req, res) => {
if (req.params.id !== req.user.id && !req.user.isAdmin) {
return res.status(403).json({ error: 'Forbidden' });
}
const user = await User.findById(req.params.id);
res.json(user);
});
// Secure - ownership + role verification
app.delete('/api/posts/:id', authenticate, async (req, res) => {
const post = await Post.findById(req.params.id);
if (!post) return res.status(404).json({ error: 'Not found' });
if (post.authorId !== req.user.id && !req.user.isAdmin) {
return res.status(403).json({ error: 'Forbidden' });
}
await post.deleteOne();
res.json({ message: 'Deleted' });
});
2.5 Defense Checklist
- Default deny: deny all access and allow only when needed
- IDOR prevention: always verify ownership or permission on resource access
- Restrict CORS settings to the minimum
- Re-validate JWT role claims server-side
- Write access control tests for every API endpoint
3. A02: Cryptographic Failures
3.1 Overview
When encryption is missing or improperly implemented for protecting sensitive data. Previously called "Sensitive Data Exposure."
3.2 Vulnerable vs Secure Code
// Vulnerable: MD5 for password hashing
const crypto = require('crypto');
const hashedPassword = crypto.createHash('md5').update(password).digest('hex');
// Vulnerable: hardcoded encryption key
const SECRET_KEY = 'my-super-secret-key-123';
const encrypted = encrypt(data, SECRET_KEY);
const bcrypt = require('bcrypt');
// Secure: bcrypt with auto-generated salt
const SALT_ROUNDS = 12;
const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS);
const isMatch = await bcrypt.compare(inputPassword, hashedPassword);
// Secure: load key from environment + AES-256-GCM
const crypto = require('crypto');
const SECRET_KEY = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
function encrypt(plaintext) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', SECRET_KEY, iv);
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
return { iv: iv.toString('hex'), encrypted: encrypted.toString('hex'), tag: tag.toString('hex') };
}
// Secure: TLS 1.2+ only
const server = https.createServer({
minVersion: 'TLSv1.2',
ciphers: 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256',
});
3.3 Defense Checklist
- Enforce HTTPS (TLS 1.2+) for all communication
- Use bcrypt, scrypt, or Argon2 for passwords (never MD5, SHA-1)
- Store encryption keys in environment variables or KMS
- Use authenticated encryption algorithms (AES-256-GCM)
- Do not store sensitive data unnecessarily
4. A03: Injection
4.1 Overview
Injection occurs when user input is interpreted as part of a query, command, or code. SQL Injection, NoSQL Injection, OS Command Injection, and XSS are the primary types.
4.2 SQL Injection Attack Scenario
-- Normal query
SELECT * FROM users WHERE username = 'admin' AND password = 'password123'
-- Attack input: username = ' OR '1'='1' --
SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = ''
-- Result: all user records returned!
4.3 Vulnerable vs Secure Code
// ===== SQL Injection =====
// Vulnerable: string concatenation
const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
db.query(query);
// Secure: parameterized query (Prepared Statement)
const query = 'SELECT * FROM users WHERE username = ? AND password = ?';
db.query(query, [username, hashedPassword]);
// Secure: ORM (Sequelize example)
const user = await User.findOne({
where: { username, password: hashedPassword },
});
// ===== NoSQL Injection =====
// Vulnerable: user input directly in query
app.post('/login', async (req, res) => {
const user = await User.findOne(req.body);
});
// Secure: type validation + mongo-sanitize
const sanitize = require('mongo-sanitize');
app.post('/login', async (req, res) => {
const username = sanitize(req.body.username);
if (typeof username !== 'string') return res.status(400).send('Invalid input');
const user = await User.findOne({ username, password: hashedPassword });
});
// ===== OS Command Injection =====
// Vulnerable: user input in shell command
const { exec } = require('child_process');
exec(`ping ${userInput}`, callback);
// Attack: userInput = "8.8.8.8; rm -rf /"
// Secure: execFile (no shell interpretation)
const { execFile } = require('child_process');
execFile('ping', ['-c', '4', userInput], callback);
4.4 XSS (Cross-Site Scripting)
// ===== Stored XSS =====
// Vulnerable: raw user input in HTML
app.get('/comments', async (req, res) => {
const comments = await Comment.find();
let html = '';
comments.forEach(c => {
html += `<div>${c.text}</div>`; // XSS vulnerable!
});
res.send(html);
});
// Secure: output encoding
const he = require('he');
comments.forEach(c => {
html += `<div>${he.encode(c.text)}</div>`;
});
// React auto-escapes JSX by default
function Comment({ text }) {
return <div>{text}</div>; // Automatically HTML-escaped
}
4.5 Defense Checklist
- SQL: always use parameterized queries or ORM
- NoSQL: input type validation + mongo-sanitize
- OS Command: use execFile, never pass user input to shell directly
- XSS: output encoding, CSP headers, leverage framework auto-escaping
5. A04: Insecure Design
5.1 Overview
Security controls missing from the design phase. A04 addresses architecture-level vulnerabilities rather than code-level ones. Even perfect implementation cannot fix a fundamentally flawed design.
5.2 Secure Design Principles
// Principle 1: Rate Limiting
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // max 5 attempts
message: 'Too many login attempts. Please try again after 15 minutes.',
standardHeaders: true,
});
app.post('/login', loginLimiter, loginHandler);
// Principle 2: Business Logic Validation
async function applyCoupon(userId, couponCode) {
const coupon = await Coupon.findOne({ code: couponCode });
if (!coupon || coupon.usedBy.includes(userId)) {
throw new Error('Invalid or already used coupon');
}
// Atomic update to prevent race conditions
const result = await Coupon.findOneAndUpdate(
{ code: couponCode, usedBy: { $ne: userId } },
{ $push: { usedBy: userId } },
{ new: true }
);
if (!result) throw new Error('Coupon already used');
return result;
}
5.3 Defense Checklist
- Perform threat modeling during design (STRIDE, DREAD)
- Include rate limiting in business logic
- Write Abuse Cases alongside Use Cases
- Use security design pattern libraries
- Include security requirements in User Stories
6. A05: Security Misconfiguration
6.1 Overview
When server, framework, or cloud service security settings are left at defaults or improperly configured. Found in 90% of applications.
6.2 Vulnerable vs Secure Configuration
// Vulnerable: default settings
const app = express();
app.use(express.json());
// X-Powered-By header exposes "Express"
// Secure: Helmet middleware + hardening
const helmet = require('helmet');
const app = express();
app.use(helmet());
app.disable('x-powered-by');
// Secure: prevent error information disclosure
app.use((err, req, res, next) => {
console.error(err.stack); // log server-side only
res.status(500).json({
error: 'Internal Server Error', // generic message only
});
});
# Docker security configuration
# Vulnerable: running as root
FROM node:20
COPY . .
CMD ["node", "server.js"]
# Secure: non-root user
FROM node:20-slim
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["node", "server.js"]
6.3 Defense Checklist
- Disable debug mode in production
- Change default accounts/passwords
- Disable unnecessary features, ports, and services
- Set security headers (Helmet, etc.)
- Block public access to cloud resources
- Maintain configuration consistency with IaC
7. A06: Vulnerable and Outdated Components
7.1 Overview
Using libraries, frameworks, or software components with known vulnerabilities. Log4Shell (CVE-2021-44228) is a prime example.
7.2 Defense Tools and Automation
# npm dependency audit
npm audit
npm audit fix
# Snyk vulnerability scanning
npx snyk test
npx snyk monitor
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
reviewers:
- "security-team"
7.3 Defense Checklist
- Run npm audit / Snyk / OWASP Dependency-Check regularly
- Integrate dependency scanning into CI/CD pipeline
- Use Dependabot or Renovate Bot for automatic update PRs
- Remove unused dependencies
- Maintain SBOM (Software Bill of Materials)
8. A07: Identification and Authentication Failures
8.1 Overview
When authentication mechanisms are improperly implemented, allowing attackers unauthorized access to user accounts.
8.2 Vulnerable vs Secure Code
// ===== Vulnerable session management =====
// Vulnerable: sequential session IDs
let sessionCounter = 0;
function createSession() {
return (++sessionCounter).toString(); // Predictable!
}
// Secure: cryptographically secure random session ID
const crypto = require('crypto');
function createSession() {
return crypto.randomBytes(32).toString('hex'); // 256-bit random
}
// ===== Vulnerable JWT implementation =====
// Vulnerable: algorithm none allowed
const payload = jwt.verify(token, secret);
// Secure: explicit algorithm specification
const payload = jwt.verify(token, secret, {
algorithms: ['HS256'],
issuer: 'my-app',
audience: 'my-api',
});
// ===== MFA Implementation =====
const speakeasy = require('speakeasy');
async function setupMFA(userId) {
const secret = speakeasy.generateSecret({
name: `MyApp:user-${userId}`,
issuer: 'MyApp',
});
const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
await User.updateOne({ _id: userId }, { mfaSecret: encrypt(secret.base32) });
return { qrCodeUrl, backupCodes: generateBackupCodes() };
}
function verifyMFA(token, userSecret) {
return speakeasy.totp.verify({
secret: userSecret,
encoding: 'base32',
token: token,
window: 1,
});
}
8.3 Defense Checklist
- Implement and encourage MFA
- Require minimum 12-character passwords with complexity
- Limit failed login attempts (Account Lockout)
- Set session timeouts
- Use bcrypt/Argon2 for password hashing
- JWT: specify algorithms, set expiration, use Refresh Token Rotation
9. A08: Software and Data Integrity Failures
9.1 Overview
When software updates, CI/CD pipelines, and data serialization lack integrity verification. The SolarWinds supply chain attack is a prime example.
9.2 Secure Code
// Vulnerable: deserializing user input directly
app.post('/api/data', (req, res) => {
const data = JSON.parse(req.body.serializedData);
processData(data);
});
// Secure: schema validation before deserialization
const Joi = require('joi');
const schema = Joi.object({
name: Joi.string().max(100).required(),
age: Joi.number().integer().min(0).max(150),
email: Joi.string().email(),
});
app.post('/api/data', (req, res) => {
const { error, value } = schema.validate(req.body);
if (error) return res.status(400).json({ error: error.details });
processData(value);
});
9.3 Defense Checklist
- Add SRI (Subresource Integrity) hashes to CDN resources
- Sign and verify artifacts in CI/CD pipelines
- Verify npm lockfile integrity
- Validate schemas before deserialization (Joi, Zod)
- Verify digital signatures on software updates
10. A09: Security Logging and Monitoring Failures
10.1 Overview
When security events are not logged or monitored, making it impossible to detect attacks. On average, breach detection takes 194 days.
10.2 Secure Security Logging
const winston = require('winston');
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
defaultMeta: { service: 'security' },
transports: [
new winston.transports.File({ filename: 'security.log' }),
],
});
function logAuthEvent(event) {
securityLogger.info('Authentication event', {
type: event.type,
userId: event.userId,
ip: event.ip,
userAgent: event.userAgent,
timestamp: new Date().toISOString(),
// Never log passwords!
});
}
function logAuditEvent(action, userId, resource, details) {
securityLogger.info('Audit event', {
action,
userId,
resource,
details,
timestamp: new Date().toISOString(),
});
}
10.3 Defense Checklist
- Log all login success/failure, permission changes, and critical operations
- Never include passwords or tokens in logs
- Use centralized log management (ELK Stack, CloudWatch)
- Set up anomaly detection alerts
- Prevent log tampering (store on separate server, immutable audit logs)
11. A10: Server-Side Request Forgery (SSRF)
11.1 Overview
An attack that tricks a server into making requests to URLs specified by the attacker. It was the core vulnerability in the 2019 Capital One breach.
11.2 Vulnerable vs Secure Code
const axios = require('axios');
const { URL } = require('url');
const dns = require('dns').promises;
const ipaddr = require('ipaddr.js');
// Vulnerable: directly requesting user-supplied URL
app.post('/api/fetch-url', async (req, res) => {
const response = await axios.get(req.body.url);
res.json(response.data);
});
// Secure: URL validation + IP blocking
async function isUrlSafe(urlString) {
const parsed = new URL(urlString);
if (parsed.protocol !== 'https:') return false;
const blockedHosts = ['localhost', '127.0.0.1', '0.0.0.0', 'metadata.google.internal'];
if (blockedHosts.includes(parsed.hostname)) return false;
const addresses = await dns.resolve4(parsed.hostname);
for (const addr of addresses) {
const ip = ipaddr.parse(addr);
if (ip.range() !== 'unicast') return false;
}
return true;
}
app.post('/api/fetch-url', async (req, res) => {
if (!await isUrlSafe(req.body.url)) {
return res.status(403).json({ error: 'URL not allowed' });
}
const response = await axios.get(req.body.url, {
timeout: 5000,
maxRedirects: 0,
});
res.json(response.data);
});
11.3 Defense Checklist
- Allowlist-based URL validation
- Block internal IP ranges (10.x, 172.16-31.x, 192.168.x, 169.254.x)
- Use IMDSv2 (AWS metadata service protection)
- Use dedicated network interfaces for server-side outbound requests
- DNS Rebinding prevention: re-verify IP after DNS resolution
12. Beyond OWASP: Additional Vulnerabilities
12.1 CSRF (Cross-Site Request Forgery)
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.get('/form', csrfProtection, (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/transfer', csrfProtection, (req, res) => {
processTransfer(req.body);
});
// SameSite cookies for CSRF defense
res.cookie('session', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'Strict',
maxAge: 3600000,
});
12.2 CORS (Cross-Origin Resource Sharing)
const cors = require('cors');
// Vulnerable: allow all origins
app.use(cors()); // origin: '*'
// Secure: specific origins only
app.use(cors({
origin: ['https://myapp.com', 'https://admin.myapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true,
maxAge: 86400,
}));
12.3 CSP (Content Security Policy)
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'nonce-abc123'"],
styleSrc: ["'self'", "https://fonts.googleapis.com"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://api.myapp.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
objectSrc: ["'none'"],
frameSrc: ["'none'"],
},
}));
12.4 Rate Limiting
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const limiter = rateLimit({
store: new RedisStore({
sendCommand: (...args) => redisClient.call(...args),
}),
windowMs: 15 * 60 * 1000,
max: 100,
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req) => req.ip,
});
const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 });
const apiLimiter = rateLimit({ windowMs: 60 * 1000, max: 30 });
app.use('/api/auth', authLimiter);
app.use('/api/', apiLimiter);
13. Security Headers Complete Guide
app.use((req, res, next) => {
// XSS defense
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-XSS-Protection', '0');
// Clickjacking defense
res.setHeader('X-Frame-Options', 'DENY');
// Force HTTPS
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
// Referrer information restriction
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
// Browser feature restriction
res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
// CSP
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self'");
next();
});
| Header | Purpose | Recommended Value |
|---|---|---|
| Content-Security-Policy | XSS/injection defense | default-src 'self' |
| Strict-Transport-Security | Force HTTPS | max-age=31536000; includeSubDomains |
| X-Frame-Options | Clickjacking defense | DENY |
| X-Content-Type-Options | MIME sniffing defense | nosniff |
| Referrer-Policy | Referrer info restriction | strict-origin-when-cross-origin |
| Permissions-Policy | Browser feature restriction | camera=(), microphone=() |
14. Security Testing Tools
14.1 DAST (Dynamic Application Security Testing)
| Tool | Type | Features |
|---|---|---|
| OWASP ZAP | Open Source DAST | Auto scan + manual testing, CI/CD integration |
| Burp Suite | Commercial DAST | Industry standard web security testing |
| Nuclei | Open Source Scanner | Template-based vulnerability scanning |
14.2 SAST (Static Application Security Testing)
| Tool | Type | Features |
|---|---|---|
| SonarQube | Open Source SAST | Code quality + security vulnerability analysis |
| Semgrep | Open Source SAST | Lightweight static analysis, custom rules |
| CodeQL | GitHub SAST | GitHub integration, semantic analysis |
14.3 SCA (Software Composition Analysis)
| Tool | Type | Features |
|---|---|---|
| Snyk | SCA + SAST | Dependency + code vulnerabilities |
| npm audit | Built-in | npm dependency vulnerability check |
| Trivy | Open Source | Container image + filesystem scanning |
# GitHub Actions security scan integration
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/owasp-top-ten
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
15. Production Security Checklist (20 Items)
Authentication and Access Control
- MFA implementation
- Minimum 12-character password with complexity requirements
- Session timeout configuration (e.g., 30 minutes)
- JWT Refresh Token Rotation
- RBAC or ABAC-based permission management
Data Protection
- HTTPS (TLS 1.2+) enforced for all communication
- Password hashing with bcrypt/Argon2
- Encryption key management via KMS
- PII: minimal collection + encrypted storage
Input Validation
- Parameterized queries (SQL Injection prevention)
- Output encoding (XSS prevention)
- CSRF tokens or SameSite cookies
- File upload type/size restrictions
Infrastructure and Configuration
- Security headers (CSP, HSTS, X-Frame-Options)
- Debug mode disabled in production
- Docker containers run as non-root
- Public access blocked on cloud resources
Monitoring and Response
- Security event logging (auth, permission changes, critical operations)
- Automated dependency vulnerability scanning (CI/CD integration)
- Incident response playbook prepared
16. Interview Questions (15)
Basic
Q1: What is OWASP Top 10 and why is it important?
The OWASP Top 10 is a list of the ten most critical web application security risks. Updated every 3-4 years, it serves as a security awareness tool and development guideline widely used across the industry. It is also referenced in compliance standards like PCI DSS.
Q2: Name three ways to prevent SQL Injection.
- Parameterized queries (Prepared Statements): separate query structure from data. 2) ORM usage: Sequelize, Prisma automatically parameterize queries. 3) Input validation: whitelist-based filtering of allowed characters only.
Q3: Explain the three types of XSS.
- Stored XSS: malicious script stored in DB and served to other users. 2) Reflected XSS: script in URL parameters included in response. 3) DOM-based XSS: client-side JavaScript manipulates the DOM. Defense involves output encoding and CSP headers.
Q4: What is CSRF and how do you defend against it?
CSRF exploits an authenticated user's browser to send malicious requests. Defense: 1) Anti-CSRF tokens, 2) SameSite cookie attribute, 3) Referer/Origin header validation, 4) Re-authentication for critical operations.
Q5: Why is HTTPS more secure than HTTP?
HTTPS uses TLS to guarantee three things: 1) Confidentiality: encryption prevents eavesdropping, 2) Integrity: detects data tampering, 3) Authentication: verifies server identity via certificates. HTTP transmits in plaintext, making it vulnerable to MITM attacks.
Intermediate
Q6: What is the difference between Broken Access Control and Authentication Failure?
Authentication Failure is incorrectly determining "who you are," while Broken Access Control is incorrectly controlling "what you can do." Authentication verifies identity; access control manages permissions.
Q7: Why is SSRF particularly dangerous in cloud environments?
Cloud environments have metadata services (169.254.169.254) that SSRF can exploit to steal IAM credentials, environment variables, etc. The Capital One breach is a prime example. AWS IMDSv2 mitigates this by requiring a token via PUT request first.
Q8: Explain JWT security vulnerabilities and countermeasures.
Vulnerabilities: 1) Algorithm None attack, 2) Secret key brute force, 3) Token theft usable until expiry. Countermeasures: explicit algorithm validation, strong secret key (256+ bits), short expiry + Refresh Token Rotation.
Q9: How does Content Security Policy (CSP) work?
CSP is an HTTP header that tells browsers which resource origins are allowed. Directives like script-src and style-src specify allowed origins per resource type. Inline scripts require nonce or hash values. Violations can be reported via report-uri.
Q10: What are Rate Limiting strategies and distributed environment considerations?
Strategies: 1) Fixed Window, 2) Sliding Window, 3) Token Bucket, 4) Leaky Bucket. In distributed environments, use centralized storage like Redis for consistent counting across all servers. Combined IP-based + user ID-based limiting is effective.
Advanced
Q11: What is Zero Trust architecture and how does it differ from traditional perimeter security?
Traditional security trusts the internal network behind firewalls. Zero Trust follows the principle of "never trust, always verify," validating even internal traffic. Key elements: least privilege, micro-segmentation, continuous verification, encrypted communication.
Q12: How do you defend against supply chain attacks?
- Lockfile usage with integrity verification, 2) SRI hashes on CDN resources, 3) SBOM maintenance, 4) CI/CD pipeline security (code signing, artifact verification), 5) Minimal dependency principle.
Q13: Explain the differences between CORS and CSP and their respective roles.
CORS relaxes the browser's same-origin policy to control cross-origin resource access (server-to-server API calls). CSP restricts what resources a page can load (XSS defense). CORS answers "who can call my API," while CSP answers "what can my page load."
Q14: What does Shift Left mean in DevSecOps and how is it implemented?
Shift Left moves security activities to earlier stages of development. Implementation: 1) SAST plugins in IDE, 2) Pre-commit hooks for secret scanning, 3) Automated security checks in PR reviews, 4) Sprint-level threat modeling, 5) Developer security training.
Q15: List five best practices for session management.
- Cryptographically secure random session IDs (minimum 128 bits), 2) HTTPS-only + HttpOnly + Secure + SameSite cookie attributes, 3) Regenerate session ID on login/privilege change, 4) Absolute and idle timeout settings, 5) Complete server-side session invalidation on logout.
17. Quiz
Q1: Which vulnerability rose to 1st place in OWASP Top 10 2021?
A01: Broken Access Control. It was 5th in 2017 but rose to 1st due to the proliferation of API-based architectures increasing authorization mistakes.
Q2: What is the most effective defense against SQL Injection?
Parameterized queries (Prepared Statements). By separating query structure from data, user input is fundamentally prevented from being interpreted as SQL commands. ORM usage provides the same protection.
Q3: Why is the 169.254.169.254 address dangerous in SSRF attacks?
169.254.169.254 is the cloud instance metadata service address. SSRF access can steal IAM credentials, environment variables, and network configurations. AWS IMDSv2 mitigates this by requiring a PUT request for token issuance first.
Q4: Why should you avoid using 'unsafe-inline' in CSP?
Allowing 'unsafe-inline' enables inline script execution, making the application vulnerable to XSS attacks. Instead, use nonce-based CSP to assign unique nonce values to each inline script, allowing only scripts with matching nonces to execute.
Q5: What are the three core principles of Zero Trust?
- Never Trust: Verify all requests even from internal networks.
- Always Verify: Perform authentication and authorization checks on every access.
- Least Privilege: Grant only the minimum necessary permissions and review regularly.
References
- OWASP Top 10 2021 Official Documentation
- OWASP Cheat Sheet Series
- OWASP Testing Guide
- OWASP ASVS
- IBM Cost of a Data Breach Report 2024
- NIST Cybersecurity Framework
- CWE (Common Weakness Enumeration)
- CVE (Common Vulnerabilities and Exposures)
- MDN Web Security
- Google Web Security Guidelines
- Node.js Security Checklist
- Helmet.js Documentation
- OWASP ZAP
- Snyk Learn - Security Education
- PortSwigger Web Security Academy