--- # CodeQL Custom Model - SSRF Protection Sanitizers # This file declares functions that sanitize user-controlled input for SSRF protection. # # Architecture: 4-Layer Defense-in-Depth # Layer 1: Format Validation (utils.ValidateURL) # Layer 2: Security Validation (security.ValidateExternalURL) - DNS resolution + IP blocking # Layer 3: Connection-Time Validation (ssrfSafeDialer) - Re-resolve DNS, re-validate IPs # Layer 4: Request Execution (TestURLConnectivity) - HEAD request, 5s timeout, max 2 redirects # # Blocked IP Ranges (13+ CIDR blocks): # - RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 # - Loopback: 127.0.0.0/8, ::1/128 # - Link-Local: 169.254.0.0/16 (AWS/GCP/Azure metadata), fe80::/10 # - Reserved: 0.0.0.0/8, 240.0.0.0/4, 255.255.255.255/32 # - IPv6 Unique Local: fc00::/7 # # Reference: /docs/plans/current_spec.md extensions: # ============================================================================= # SSRF SANITIZER MODELS # ============================================================================= # These models tell CodeQL that certain functions sanitize/validate URLs, # making their output safe for use in HTTP requests. # # IMPORTANT: For SSRF protection, we use 'sinkModel' with 'request-forgery' # to mark inputs as sanitized sinks, AND 'neutralModel' to prevent taint # propagation through validation functions. # ============================================================================= # Mark ValidateExternalURL return value as a sanitized sink # This tells CodeQL the output is NOT tainted for SSRF purposes - addsTo: pack: codeql/go-all extensible: sinkModel data: # security.ValidateExternalURL validates and sanitizes URLs by: # 1. Validating URL format and scheme # 2. Performing DNS resolution with timeout # 3. Blocking private/reserved IP ranges (13+ CIDR blocks) # 4. Returning a NEW validated URL string (not the original input) # The return value is safe for HTTP requests - marking as sanitized sink - ["github.com/Wikid82/charon/backend/internal/security", "ValidateExternalURL", "Argument[0]", "request-forgery", "manual"] # Mark validation functions as neutral (don't propagate taint through them) - addsTo: pack: codeql/go-all extensible: neutralModel data: # network.IsPrivateIP is a validation function (neutral - doesn't propagate taint) - ["github.com/Wikid82/charon/backend/internal/network", "IsPrivateIP", "manual"] # TestURLConnectivity validates URLs internally via security.ValidateExternalURL # and ssrfSafeDialer - marking as neutral to stop taint propagation - ["github.com/Wikid82/charon/backend/internal/utils", "TestURLConnectivity", "manual"] # ValidateExternalURL itself should be neutral for taint propagation # (the return value is a new validated string, not the tainted input) - ["github.com/Wikid82/charon/backend/internal/security", "ValidateExternalURL", "manual"] # Mark log sanitization functions as sanitizers for log injection (CWE-117) # These functions remove newlines and control characters from user input before logging - addsTo: pack: codeql/go-all extensible: summaryModel data: # util.SanitizeForLog sanitizes strings by: # 1. Replacing \r\n and \n with spaces # 2. Removing all control characters [\x00-\x1F\x7F] # Input: Argument[0] (unsanitized string) # Output: ReturnValue[0] (sanitized string - safe for logging) - ["github.com/Wikid82/charon/backend/internal/util", "SanitizeForLog", "Argument[0]", "ReturnValue[0]", "taint", "manual"] # handlers.sanitizeForLog is a local sanitizer with same behavior - ["github.com/Wikid82/charon/backend/internal/api/handlers", "sanitizeForLog", "Argument[0]", "ReturnValue[0]", "taint", "manual"]