OWASP Top 10¶
Definition¶
OWASP (Open Web Application Security Project) - Top 10 most critical web application security risks. These cover ~95% of attacks on web applications.
A01: Broken Access Control¶
// BROKEN ACCESS CONTROL: Users acting outside permissions
// VULNERABLE: Direct object reference without authorization
@GetMapping("/api/users/{userId}/orders")
public List<Order> getUserOrders(@PathVariable String userId) {
// Anyone can access any user's orders by changing userId!
return orderRepository.findByUserId(userId);
}
// FIXED: Check authorization
@GetMapping("/api/users/{userId}/orders")
@PreAuthorize("#userId == authentication.principal.id or hasRole('ADMIN')")
public List<Order> getUserOrders(@PathVariable String userId) {
return orderRepository.findByUserId(userId);
}
// VULNERABLE: Insecure direct object reference (IDOR)
@GetMapping("/documents/{id}")
public Document getDocument(@PathVariable Long id) {
return documentRepository.findById(id); // No ownership check!
}
// FIXED: Verify ownership
@GetMapping("/documents/{id}")
public Document getDocument(@PathVariable Long id) {
Document doc = documentRepository.findById(id);
if (!doc.getOwnerId().equals(getCurrentUserId())) {
throw new AccessDeniedException("Not your document");
}
return doc;
}
// PREVENTION:
// • Deny by default
// • Implement access control at server-side
// • Log access control failures
// • Rate limit API calls
// • Invalidate sessions after logout
A02-A03: Crypto & Injection¶
// A02: CRYPTOGRAPHIC FAILURES
// VULNERABLE: Weak hashing
String hash = MD5.hash(password); // MD5 is broken!
// FIXED: Use bcrypt
String hash = BCrypt.hashpw(password, BCrypt.gensalt(12));
// VULNERABLE: Sensitive data in URL
GET /api/users?ssn=123-45-6789
// FIXED: Use POST body or encrypt
POST /api/users
{ "ssn": "encrypted_value" }
// PREVENTION:
// • Use TLS 1.2+ for data in transit
// • Use strong algorithms (AES-256, RSA-2048+)
// • Use bcrypt/scrypt/Argon2 for passwords
// • Don't store sensitive data unnecessarily
// A03: INJECTION
// VULNERABLE: SQL Injection
String query = "SELECT * FROM users WHERE name = '" + userInput + "'";
// Input: ' OR '1'='1' -- → Returns all users!
// FIXED: Parameterized queries
PreparedStatement stmt = conn.prepareStatement(
"SELECT * FROM users WHERE name = ?"
);
stmt.setString(1, userInput);
// VULNERABLE: Command injection
Runtime.getRuntime().exec("ping " + userInput);
// Input: google.com; rm -rf /
// FIXED: Avoid shell commands, validate input
ProcessBuilder pb = new ProcessBuilder("ping", "-c", "1", hostname);
if (!hostname.matches("^[a-zA-Z0-9.-]+$")) {
throw new IllegalArgumentException("Invalid hostname");
}
// PREVENTION:
// • Use parameterized queries/ORMs
// • Validate and sanitize all input
// • Escape output for context (HTML, SQL, etc.)
// • Use allowlists, not blocklists
A04-A06: Design & Config¶
// A04: INSECURE DESIGN
// Problem: Flawed architecture, not just bugs
// Example: Password reset via security questions (weak by design)
// PREVENTION:
// • Threat modeling during design
// • Security requirements in user stories
// • Use secure design patterns
// • Limit resource consumption (rate limiting)
// A05: SECURITY MISCONFIGURATION
// VULNERABLE configurations:
// - Default credentials (admin/admin)
// - Unnecessary features enabled
// - Detailed error messages in production
// - Missing security headers
// FIXED: Proper configuration
@Configuration
class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'"))
.frameOptions(frame -> frame.deny())
.xssProtection(xss -> xss.enable())
)
.csrf(csrf -> csrf.enable());
return http.build();
}
}
// Security headers to add:
// X-Content-Type-Options: nosniff
// X-Frame-Options: DENY
// Content-Security-Policy: default-src 'self'
// Strict-Transport-Security: max-age=31536000
// A06: VULNERABLE COMPONENTS
// Check dependencies for vulnerabilities
// Maven: mvn dependency-check:check
// Gradle: ./gradlew dependencyCheckAnalyze
// npm: npm audit
// PREVENTION:
// • Regular dependency updates
// • Automated vulnerability scanning (Dependabot, Snyk)
// • Remove unused dependencies
// • Only use trusted sources
A07-A10: Auth & More¶
// A07: AUTHENTICATION FAILURES
// VULNERABLE: Weak password policy
if (password.length() >= 6) { /* allow */ }
// FIXED: Strong password requirements
PasswordPolicy policy = new PasswordPolicy();
policy.setMinLength(12);
policy.setRequireUppercase(true);
policy.setRequireLowercase(true);
policy.setRequireDigit(true);
policy.setRequireSpecial(true);
// VULNERABLE: No brute force protection
// Unlimited login attempts
// FIXED: Rate limiting and lockout
@RateLimiter(name = "login", fallbackMethod = "loginFallback")
public Token login(Credentials creds) {
if (failedAttempts.get(creds.getUsername()) > 5) {
throw new AccountLockedException();
}
// ...
}
// A08: SOFTWARE AND DATA INTEGRITY FAILURES
// VULNERABLE: Unsigned updates, insecure deserialization
ObjectInputStream ois = new ObjectInputStream(untrustedData);
Object obj = ois.readObject(); // Remote code execution!
// FIXED: Avoid Java serialization, use allowlists
// Use signed packages, verify checksums
// CI/CD pipeline integrity checks
// A09: LOGGING AND MONITORING FAILURES
// See Logging best practices file
// A10: SERVER-SIDE REQUEST FORGERY (SSRF)
// VULNERABLE: Fetching arbitrary URLs
@GetMapping("/fetch")
public String fetch(@RequestParam String url) {
return httpClient.get(url); // Can access internal services!
}
// Attack: /fetch?url=http://169.254.169.254/metadata
// FIXED: Validate URLs, use allowlist
private static final Set<String> ALLOWED_HOSTS = Set.of("api.example.com");
public String fetch(String url) {
URL parsed = new URL(url);
if (!ALLOWED_HOSTS.contains(parsed.getHost())) {
throw new SecurityException("Host not allowed");
}
// Also check for internal IPs, redirects, etc.
}
Tips & Tricks¶
Interview Tips¶
- Know the top 10 categories
- Give examples of each vulnerability
- Explain prevention techniques
- Discuss defense in depth
Common Questions¶
- "What is SQL injection? How do you prevent it?"
- "What are the OWASP Top 10?"
- "How do you secure a web application?"
- "What security headers should you use?"
Security Principles¶
- Defense in depth (multiple layers)
- Principle of least privilege
- Fail securely (deny by default)
- Don't trust user input
- Keep security simple
Quick Prevention Checklist¶
- [ ] Input validation
- [ ] Output encoding
- [ ] Parameterized queries
- [ ] Strong authentication
- [ ] Authorization checks
- [ ] HTTPS everywhere
- [ ] Security headers
- [ ] Dependency scanning
Key Insight: Most attacks exploit known vulnerabilities. Follow the OWASP guidelines to prevent 95% of attacks.
- *