OWASP Top 10: Preventing the Most Critical Web Application Security Risks

20 novembre 2024 · CodeMatic Team

OWASP Top 10

The OWASP Top 10 represents the most critical security risks to web applications. Understanding and preventing these vulnerabilities is essential for building secure applications. This guide covers each risk with practical prevention strategies.

A01:2021 – Broken Access Control

Broken access control allows attackers to access resources or perform actions they shouldn't be able to.

Prevention

// ✅ Always verify permissions
async function getPost(req: Request, res: Response) {
  const postId = req.params.id;
  const userId = req.user.id;
  
  const post = await db.posts.findUnique({
    where: { id: postId },
  });
  
  // Verify ownership or permissions
  if (post.userId !== userId && !userHasPermission(userId, 'read:all-posts')) {
    return res.status(403).json({ error: 'Access denied' });
  }
  
  res.json(post);
}

// ✅ Use middleware for authorization
function requireOwnership(resource: string) {
  return async (req: Request, res: Response, next: NextFunction) => {
    const resource = await getResource(req.params.id);
    
    if (resource.userId !== req.user.id) {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    next();
  };
}

A02:2021 – Cryptographic Failures

Previously "Sensitive Data Exposure" – failures related to cryptography or lack thereof.

Prevention

// ✅ Encrypt sensitive data at rest
import crypto from 'crypto';

const algorithm = 'aes-256-gcm';
const key = crypto.scryptSync(process.env.ENCRYPTION_KEY!, 'salt', 32);

function encrypt(text: string): { encrypted: string; iv: string; tag: string } {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  const tag = cipher.getAuthTag();
  
  return { encrypted, iv: iv.toString('hex'), tag: tag.toString('hex') };
}

// ✅ Use HTTPS for all communications
// ✅ Hash passwords with bcrypt/argon2
// ✅ Never log sensitive data
// ✅ Use environment variables for secrets

A03:2021 – Injection

SQL, NoSQL, OS command, and LDAP injection vulnerabilities.

SQL Injection Prevention

// ❌ VULNERABLE
const query = `SELECT * FROM users WHERE email = '${email}'`;

// ✅ SAFE - Parameterized queries
const query = 'SELECT * FROM users WHERE email = $1';
db.query(query, [email]);

// ✅ SAFE - ORM
const user = await prisma.user.findUnique({
  where: { email },
});

NoSQL Injection Prevention

// ❌ VULNERABLE
const user = await User.findOne({
  email: req.body.email,
  password: req.body.password,
});

// ✅ SAFE - Validate and sanitize
const email = sanitizeInput(req.body.email);
const password = await hashPassword(req.body.password);

const user = await User.findOne({ email });
if (user && await verifyPassword(req.body.password, user.password)) {
  // Authenticated
}

A04:2021 – Insecure Design

Security flaws in design and architecture.

Prevention

  • Threat modeling during design phase
  • Security requirements definition
  • Secure design patterns
  • Security architecture reviews
  • Least privilege principle

A05:2021 – Security Misconfiguration

Insecure default configurations, incomplete configurations, or exposed cloud storage.

Prevention Checklist

  • Remove default accounts and passwords
  • Disable unnecessary features
  • Use security headers
  • Keep software updated
  • Secure error handling (don't expose stack traces)
  • Use secure configurations
  • Regular security audits

A06:2021 – Vulnerable and Outdated Components

Using components with known vulnerabilities.

Prevention

// Regular dependency scanning
npm audit
npm audit fix

// Automated updates with Dependabot
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10

// Use Snyk or similar tools
// Monitor security advisories
// Test updates before deploying

A07:2021 – Identification and Authentication Failures

Previously "Broken Authentication" – failures in authentication mechanisms.

Prevention

  • Implement MFA
  • Use strong password requirements
  • Implement account lockout
  • Use secure session management
  • Protect against credential stuffing
  • Use password hashing (bcrypt, argon2)
  • Implement secure password reset

A08:2021 – Software and Data Integrity Failures

Failures related to CI/CD pipelines, insecure deserialization, and software updates.

Prevention

// Secure deserialization
// ❌ VULNERABLE
const data = JSON.parse(userInput); // Can be exploited

// ✅ SAFE - Validate structure
const schema = z.object({
  name: z.string(),
  age: z.number(),
});

const data = schema.parse(JSON.parse(userInput));

// CI/CD Security
// - Sign code commits
// - Verify dependencies
// - Use secure pipelines
// - Implement code reviews
// - Scan for secrets in code

A09:2021 – Security Logging and Monitoring Failures

Insufficient logging and monitoring leading to delayed detection of security incidents.

Prevention

// Comprehensive logging
import winston from 'winston';

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

// Log security events
function logSecurityEvent(event: string, details: any) {
  logger.warn('Security Event', {
    event,
    details,
    timestamp: new Date().toISOString(),
    ip: req.ip,
    userAgent: req.get('user-agent'),
  });
}

// Monitor for:
// - Failed login attempts
// - Unauthorized access attempts
// - Suspicious patterns
// - Rate limit violations
// - Unusual API usage

A10:2021 – Server-Side Request Forgery (SSRF)

Forcing the server to make requests to unintended locations.

Prevention

// ✅ Validate and whitelist URLs
function validateURL(url: string): boolean {
  try {
    const parsed = new URL(url);
    
    // Only allow specific protocols
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return false;
    }
    
    // Whitelist allowed domains
    const allowedDomains = ['api.example.com', 'cdn.example.com'];
    if (!allowedDomains.includes(parsed.hostname)) {
      return false;
    }
    
    // Block private IPs
    if (isPrivateIP(parsed.hostname)) {
      return false;
    }
    
    return true;
  } catch {
    return false;
  }
}

// Use allowlists instead of blocklists
// Implement network segmentation
// Use URL parsing libraries carefully

Security Testing Checklist

  • ✅ Static Application Security Testing (SAST)
  • ✅ Dynamic Application Security Testing (DAST)
  • ✅ Dependency scanning
  • ✅ Penetration testing
  • ✅ Code reviews focused on security
  • ✅ Security architecture reviews
  • ✅ Regular security audits

Conclusion

The OWASP Top 10 provides a framework for understanding and preventing the most critical security risks. Implement defense in depth, validate all inputs, use secure coding practices, keep dependencies updated, and implement comprehensive logging and monitoring. Security is an ongoing process that requires vigilance and continuous improvement.