Securing Web Applications: OWASP Top 10 and Beyond

Web application security is critical in today's threat landscape. Understanding and mitigating the most common vulnerabilities is essential for protecting user data and maintaining trust.

OWASP Top 10 Overview

The Open Web Application Security Project (OWASP) maintains a list of the most critical web application security risks.

1. Broken Access Control

Prevent unauthorized access to resources:

// Proper authorization middleware
const requireRole = (role: string) => {
  return (ctx: Context) => {
    const user = getCurrentUser(ctx);
    if (!user || !user.roles.includes(role)) {
      ctx.response.status = 403;
      ctx.response.body = { error: "Forbidden" };
      return;
    }
  };
};

// Usage
router.get("/admin/users", requireRole("admin"), getUsersHandler);

2. Cryptographic Failures

Use strong encryption and proper key management:

import { createHash } from "crypto";

// Secure password hashing
export async function hashPassword(password: string): Promise<string> {
  const salt = crypto.randomBytes(32);
  const hash = await crypto.pbkdf2(password, salt, 100000, 64, "sha256");
  return `${salt.toString("hex")}:${hash.toString("hex")}`;
}

// Secure token generation
export function generateSecureToken(): string {
  return crypto.randomBytes(32).toString("hex");
}

3. Injection

Prevent SQL injection and other injection attacks:

// Safe parameterized queries
const getUserById = async (userId: string) => {
  const query = "SELECT * FROM users WHERE id = ?";
  const [rows] = await db.execute(query, [userId]);
  return rows[0];
};

// Input validation
import { z } from "zod";

const userSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2).max(100),
  age: z.number().min(0).max(150),
});

const validateUser = (data: unknown) => {
  return userSchema.parse(data);
};

4. Insecure Design

Implement security by design principles:

// Defense in depth
class SecurityService {
  async authenticateUser(credentials: LoginCredentials) {
    // 1. Rate limiting
    await this.checkRateLimit(credentials.email);

    // 2. Input validation
    this.validateCredentials(credentials);

    // 3. Credential verification
    const user = await this.verifyCredentials(credentials);

    // 4. Session creation
    const session = await this.createSecureSession(user);

    return session;
  }
}

5. Security Misconfiguration

Secure configuration management:

# production.yaml
security:
  headers:
    contentSecurityPolicy: "default-src 'self'"
    strictTransportSecurity: "max-age=31536000"
    xFrameOptions: "DENY"
    xContentTypeOptions: "nosniff"

database:
  ssl: true
  connectionPool:
    min: 2
    max: 10

authentication:
  jwt:
    secret: "${JWT_SECRET}"
    expiresIn: "1h"
  bcrypt:
    rounds: 12

Advanced Security Practices

Zero Trust Architecture

Never trust, always verify:

class ZeroTrustAuth {
  async authorizeRequest(request: Request): Promise<boolean> {
    // 1. Verify identity
    const identity = await this.verifyIdentity(request);

    // 2. Check context
    const context = await this.evaluateContext(request);

    // 3. Assess risk
    const risk = await this.assessRisk(identity, context);

    // 4. Make authorization decision
    return this.makeDecision(identity, context, risk);
  }
}

API Security

Secure your APIs with proper authentication and authorization:

// JWT authentication middleware
const authenticateJWT = async (ctx: Context, next: Next) => {
  const token = ctx.request.headers.get("Authorization")?.replace(
    "Bearer ",
    "",
  );

  if (!token) {
    ctx.response.status = 401;
    ctx.response.body = { error: "No token provided" };
    return;
  }

  try {
    const payload = await verifyJWT(token);
    ctx.state.user = payload;
    await next();
  } catch (error) {
    ctx.response.status = 401;
    ctx.response.body = { error: "Invalid token" };
  }
};

Rate Limiting

Protect against abuse and DoS attacks:

import { rateLimit } from "express-rate-limit";

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: "Too many requests from this IP, please try again later.",
  standardHeaders: true,
  legacyHeaders: false,
});

app.use("/api/", limiter);

Security Monitoring and Logging

Security Information and Event Management (SIEM)

Centralized security monitoring:

class SecurityLogger {
  async logSecurityEvent(event: SecurityEvent) {
    const logEntry = {
      timestamp: new Date(),
      level: "security",
      event: event.type,
      userId: event.userId,
      ip: event.ip,
      userAgent: event.userAgent,
      details: event.details,
    };

    // Send to SIEM system
    await this.siemClient.send(logEntry);

    // Alert on critical events
    if (event.severity === "critical") {
      await this.alertTeam(event);
    }
  }
}

Intrusion Detection

Monitor for suspicious activities:

class IntrusionDetector {
  async analyzeRequest(request: Request): Promise<RiskLevel> {
    const riskFactors = await Promise.all([
      this.checkIPReputation(request.ip),
      this.checkUserBehavior(request.userId),
      this.checkRequestPatterns(request),
      this.checkAnomalyDetection(request),
    ]);

    return this.calculateRiskLevel(riskFactors);
  }
}

Compliance and Auditing

GDPR Compliance

Handle personal data responsibly:

class GDPRCompliance {
  async handleDataSubjectRequest(request: DataSubjectRequest) {
    switch (request.type) {
      case "access":
        return await this.provideDataAccess(request.userId);
      case "rectification":
        return await this.rectifyData(request.userId, request.data);
      case "erasure":
        return await this.eraseData(request.userId);
      case "portability":
        return await this.exportData(request.userId);
    }
  }
}

Security Audits

Regular security assessments:

class SecurityAuditor {
  async performSecurityAudit() {
    const results = {
      vulnerabilityScan: await this.runVulnerabilityScan(),
      configurationReview: await this.reviewConfiguration(),
      accessControlAudit: await this.auditAccessControls(),
      complianceCheck: await this.checkCompliance(),
    };

    await this.generateReport(results);
    await this.notifyStakeholders(results);
  }
}

Incident Response

Incident Response Plan

Preparedness for security incidents:

class IncidentResponse {
  async handleSecurityIncident(incident: SecurityIncident) {
    // 1. Assess the situation
    const assessment = await this.assessIncident(incident);

    // 2. Contain the breach
    await this.containBreach(assessment);

    // 3. Investigate thoroughly
    const investigation = await this.investigateIncident(incident);

    // 4. Recover systems
    await this.recoverSystems(investigation);

    // 5. Learn and improve
    await this.postMortemAnalysis(incident, investigation);
  }
}

Conclusion

Web application security is an ongoing process that requires vigilance, regular updates, and a security-first mindset. Implementing the OWASP Top 10 protections and following security best practices will significantly reduce your application's attack surface.