SyntaxStudy
Sign Up
Web Security OWASP Top 10 2021: A09–A10 and Remediation Strategies
Web Security Beginner 1 min read

OWASP Top 10 2021: A09–A10 and Remediation Strategies

A09: Security Logging and Monitoring Failures was elevated in 2021 to reflect how often breaches go undetected for months because organisations lack adequate logging, alerting, and incident response capabilities. The average time to detect a breach is over 200 days. Effective security logging should record authentication events (successes, failures, lockouts), authorisation failures, input validation failures, and administrative actions. Logs must be protected from tampering, centralised in a SIEM, and have alerts configured for anomalous patterns. A10: Server-Side Request Forgery (SSRF) entered the Top 10 in 2021, driven by the explosion of cloud-native architectures. SSRF occurs when the server makes an HTTP request to a URL supplied by the user without validating the destination. An attacker can direct the server to fetch the cloud metadata endpoint (169.254.169.254 on AWS/GCP) to steal IAM credentials, scan internal services, or exfiltrate data through DNS. The Capital One breach (2019) was enabled in part by SSRF against AWS metadata. A holistic OWASP remediation programme integrates security across the SDLC. In design: threat modeling, security requirements. In development: SAST tools (SonarQube, Semgrep), pre-commit hooks, secure coding training. In testing: DAST with OWASP ZAP, penetration testing, dependency scanning. In deployment: infrastructure hardening, WAF, secrets management (Vault, AWS Secrets Manager). In operations: SIEM, vulnerability management, incident response plan. Security is a continuous process, not a checklist.
Example
<?php
// A09: Security Logging — structured log for authentication events

use Illuminate\Support\Facades\Log;

class AuthController extends Controller
{
    public function login(Request $request): JsonResponse
    {
        $ip       = $request->ip();
        $username = $request->input('username');

        if (!Auth::attempt($request->only('username', 'password'))) {
            // Log failure with structured context — ingest into SIEM
            Log::warning('authentication.failed', [
                'username'   => $username,
                'ip'         => $ip,
                'user_agent' => $request->userAgent(),
                'timestamp'  => now()->toIso8601String(),
            ]);
            return response()->json(['error' => 'Invalid credentials'], 401);
        }

        Log::info('authentication.success', [
            'user_id'    => Auth::id(),
            'ip'         => $ip,
            'user_agent' => $request->userAgent(),
        ]);

        return response()->json(['token' => Auth::user()->createToken('api')->plainTextToken]);
    }
}

// A10: SSRF — validate URLs before making server-side requests
function safeFetch(string $url): string
{
    $parsed = parse_url($url);
    if (!$parsed || !in_array($parsed['scheme'] ?? '', ['http', 'https'])) {
        throw new \InvalidArgumentException('Only HTTP/HTTPS URLs are allowed.');
    }
    $host = $parsed['host'] ?? '';
    // Block private/loopback/link-local addresses
    $ip = gethostbyname($host);
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
        throw new \InvalidArgumentException("Requests to private addresses are forbidden: {$ip}");
    }
    // Block AWS metadata endpoint specifically
    if ($ip === '169.254.169.254') {
        throw new \InvalidArgumentException('Access to metadata endpoint is forbidden.');
    }
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // don't follow redirects
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

This is the last lesson in this section.

Create a free account to earn a certificate