001/* 002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package de.cuioss.http.security.config; 017 018import java.util.Set; 019 020/** 021 * Comprehensive collection of default values and constants for HTTP security configuration. 022 * 023 * <p>This class provides centralized constants for all security-related configuration values, 024 * making it easy to reference standard limits, common patterns, and recommended settings 025 * across the HTTP security validation system.</p> 026 * 027 * <h3>Design Principles</h3> 028 * <ul> 029 * <li><strong>Centralized Constants</strong> - Single source of truth for all defaults</li> 030 * <li><strong>Security-First</strong> - Defaults prioritize security while maintaining usability</li> 031 * <li><strong>Industry Standards</strong> - Based on RFC specifications and best practices</li> 032 * <li><strong>Categorized</strong> - Organized by HTTP component type for easy navigation</li> 033 * </ul> 034 * 035 * <h3>Constant Categories</h3> 036 * <ul> 037 * <li><strong>Length Limits</strong> - Maximum sizes for various HTTP components</li> 038 * <li><strong>Count Limits</strong> - Maximum quantities for collections</li> 039 * <li><strong>Security Patterns</strong> - Common attack patterns to detect</li> 040 * <li><strong>Content Types</strong> - Standard MIME types and their security implications</li> 041 * <li><strong>Character Sets</strong> - Character validation patterns</li> 042 * <li><strong>Configuration Presets</strong> - Pre-built configurations for common scenarios</li> 043 * </ul> 044 * 045 * <h3>Usage Examples</h3> 046 * <pre> 047 * // Use constants in configuration 048 * SecurityConfiguration config = SecurityConfiguration.builder() 049 * .maxPathLength(SecurityDefaults.MAX_PATH_LENGTH_DEFAULT) 050 * .maxParameterCount(SecurityDefaults.MAX_PARAMETER_COUNT_DEFAULT) 051 * .blockedContentTypes(SecurityDefaults.DANGEROUS_CONTENT_TYPES) 052 * .build(); 053 * 054 * // Check against limits 055 * if (path.length() > SecurityDefaults.MAX_PATH_LENGTH_STRICT) { 056 * throw new UrlSecurityException(...); 057 * } 058 * 059 * // Use pattern constants 060 * if (SecurityDefaults.PATH_TRAVERSAL_PATTERNS.stream().anyMatch(input::contains)) { 061 * // Handle path traversal attempt 062 * } 063 * </pre> 064 * 065 * Implements: Task C3 from HTTP verification specification 066 * 067 * @since 1.0 068 * @see SecurityConfiguration 069 * @see SecurityConfigurationBuilder 070 */ 071public final class SecurityDefaults { 072 073 /** 074 * Private constructor to prevent instantiation. 075 */ 076 private SecurityDefaults() { 077 // Utility class - no instances 078 } 079 080 // ========== PATH SECURITY CONSTANTS ========== 081 082 /** Maximum path length for strict security configurations */ 083 public static final int MAX_PATH_LENGTH_STRICT = 1024; 084 085 /** Maximum path length for default security configurations */ 086 public static final int MAX_PATH_LENGTH_DEFAULT = 4096; 087 088 /** Maximum path length for lenient security configurations */ 089 public static final int MAX_PATH_LENGTH_LENIENT = 8192; 090 091 /** Common path traversal patterns to detect */ 092 public static final Set<String> PATH_TRAVERSAL_PATTERNS = Set.of( 093 // Basic patterns 094 "../", "..\\", "..\\/", 095 096 // URL encoded patterns 097 "..%2F", "..%5C", "%2E%2E/", "%2e%2e/", "%2E%2E%2F", "%2e%2e%2f", 098 "%2e%2e%5c", "%2E%2E%5C", "%2f%2e%2e", "%5c%2e%2e", 099 100 // Double encoded patterns 101 "%252e%252e%252f", "%252e%252e%255c", "%252e%252e/", "%252e%252e\\", 102 103 // Mixed patterns 104 "....//", "....\\\\", ".%2E/", ".%2e/", "..//", "..\\\\", 105 "%2e%2e//", "%2e%2e\\\\", "..%2f/", "..%5c\\", "..%2f", "..%5c", "/%2e%2e/", 106 107 // UTF-8 overlong encodings (common bypass attempts) 108 "..%c0%af", "..%c1%9c", "%c0%ae%c0%ae%c0%af", "%c1%8s%c1%8s%c1%81" 109 ); 110 111 /** Patterns indicating potential directory traversal attempts and protocol handler attacks */ 112 public static final Set<String> SUSPICIOUS_PATH_PATTERNS = Set.of( 113 "/etc/", "/proc/", "/sys/", "/dev/", "/boot/", "/root/", 114 "\\windows\\", "\\system32\\", "\\users\\", "\\program files\\", 115 "web.xml", "web.config", ".env", ".htaccess", ".htpasswd", 116 "javascript:", "vbscript:", "data:", "file:" 117 ); 118 119 // ========== PARAMETER SECURITY CONSTANTS ========== 120 121 /** Maximum parameter count for strict security configurations */ 122 public static final int MAX_PARAMETER_COUNT_STRICT = 20; 123 124 /** Maximum parameter count for default security configurations */ 125 public static final int MAX_PARAMETER_COUNT_DEFAULT = 100; 126 127 /** Maximum parameter count for lenient security configurations */ 128 public static final int MAX_PARAMETER_COUNT_LENIENT = 500; 129 130 /** Maximum parameter name length for strict configurations */ 131 public static final int MAX_PARAMETER_NAME_LENGTH_STRICT = 64; 132 133 /** Maximum parameter name length for default configurations */ 134 public static final int MAX_PARAMETER_NAME_LENGTH_DEFAULT = 128; 135 136 /** Maximum parameter name length for lenient configurations */ 137 public static final int MAX_PARAMETER_NAME_LENGTH_LENIENT = 256; 138 139 /** Maximum parameter value length for strict configurations */ 140 public static final int MAX_PARAMETER_VALUE_LENGTH_STRICT = 1024; 141 142 /** Maximum parameter value length for default configurations */ 143 public static final int MAX_PARAMETER_VALUE_LENGTH_DEFAULT = 2048; 144 145 /** Maximum parameter value length for lenient configurations */ 146 public static final int MAX_PARAMETER_VALUE_LENGTH_LENIENT = 8192; 147 148 /** Parameter names that are commonly used in HTTP-layer attacks */ 149 public static final Set<String> SUSPICIOUS_PARAMETER_NAMES = Set.of( 150 "script", "include", "require", "file", "path", "url", "redirect", "forward" 151 ); 152 153 // ========== HEADER SECURITY CONSTANTS ========== 154 155 /** Maximum header count for strict security configurations */ 156 public static final int MAX_HEADER_COUNT_STRICT = 20; 157 158 /** Maximum header count for default security configurations */ 159 public static final int MAX_HEADER_COUNT_DEFAULT = 50; 160 161 /** Maximum header count for lenient security configurations */ 162 public static final int MAX_HEADER_COUNT_LENIENT = 100; 163 164 /** Maximum header name length for strict configurations */ 165 public static final int MAX_HEADER_NAME_LENGTH_STRICT = 64; 166 167 /** Maximum header name length for default configurations */ 168 public static final int MAX_HEADER_NAME_LENGTH_DEFAULT = 128; 169 170 /** Maximum header name length for lenient configurations */ 171 public static final int MAX_HEADER_NAME_LENGTH_LENIENT = 256; 172 173 /** Maximum header value length for strict configurations */ 174 public static final int MAX_HEADER_VALUE_LENGTH_STRICT = 1024; 175 176 /** Maximum header value length for default configurations */ 177 public static final int MAX_HEADER_VALUE_LENGTH_DEFAULT = 2048; 178 179 /** Maximum header value length for lenient configurations */ 180 public static final int MAX_HEADER_VALUE_LENGTH_LENIENT = 8192; 181 182 /** Headers that should typically be blocked for security */ 183 public static final Set<String> DANGEROUS_HEADER_NAMES = Set.of( 184 "X-Debug", "X-Test", "X-Development", "X-Admin", 185 "X-Execute", "X-Command", "X-Shell", "X-Eval", 186 "Proxy-Authorization", "Proxy-Connection" 187 ); 188 189 /** Headers commonly used for debugging that may expose sensitive information */ 190 public static final Set<String> DEBUG_HEADER_NAMES = Set.of( 191 "X-Debug", "X-Trace", "X-Profile", "X-Test-Mode", 192 "X-Development", "X-Internal", "X-System-Info" 193 ); 194 195 // ========== COOKIE SECURITY CONSTANTS ========== 196 197 /** Maximum cookie count for strict security configurations */ 198 public static final int MAX_COOKIE_COUNT_STRICT = 10; 199 200 /** Maximum cookie count for default security configurations */ 201 public static final int MAX_COOKIE_COUNT_DEFAULT = 20; 202 203 /** Maximum cookie count for lenient security configurations */ 204 public static final int MAX_COOKIE_COUNT_LENIENT = 50; 205 206 /** Maximum cookie name length for strict configurations */ 207 public static final int MAX_COOKIE_NAME_LENGTH_STRICT = 64; 208 209 /** Maximum cookie name length for default configurations */ 210 public static final int MAX_COOKIE_NAME_LENGTH_DEFAULT = 128; 211 212 /** Maximum cookie name length for lenient configurations */ 213 public static final int MAX_COOKIE_NAME_LENGTH_LENIENT = 256; 214 215 /** Maximum cookie value length for strict configurations */ 216 public static final int MAX_COOKIE_VALUE_LENGTH_STRICT = 1024; 217 218 /** Maximum cookie value length for default configurations */ 219 public static final int MAX_COOKIE_VALUE_LENGTH_DEFAULT = 2048; 220 221 /** Maximum cookie value length for lenient configurations */ 222 public static final int MAX_COOKIE_VALUE_LENGTH_LENIENT = 8192; 223 224 /** Cookie names that may indicate security issues */ 225 public static final Set<String> SUSPICIOUS_COOKIE_NAMES = Set.of( 226 "debug", "test", "admin", "root", "system", "internal", 227 "password", "secret", "token", "key", "auth", "session" 228 ); 229 230 // ========== BODY SECURITY CONSTANTS ========== 231 232 /** Maximum body size for strict security configurations (1MB) */ 233 public static final long MAX_BODY_SIZE_STRICT = 1024L * 1024; 234 235 /** Maximum body size for default security configurations (5MB) */ 236 public static final long MAX_BODY_SIZE_DEFAULT = 5L * 1024 * 1024; 237 238 /** Maximum body size for lenient security configurations (10MB) */ 239 public static final long MAX_BODY_SIZE_LENIENT = 10L * 1024 * 1024; 240 241 /** Content types that are generally safe for most applications */ 242 public static final Set<String> SAFE_CONTENT_TYPES = Set.of( 243 "application/json", "application/xml", "text/plain", "text/html", 244 "application/x-www-form-urlencoded", "multipart/form-data", 245 "text/css", "text/javascript", "application/javascript" 246 ); 247 248 /** Content types that may pose security risks */ 249 public static final Set<String> DANGEROUS_CONTENT_TYPES = Set.of( 250 "application/octet-stream", "application/x-executable", 251 "application/x-msdownload", "application/x-msdos-program", 252 "application/x-java-archive", "application/java-archive", 253 "text/x-script", "text/x-shellscript", "application/x-sh" 254 ); 255 256 /** Content types used for file uploads */ 257 public static final Set<String> UPLOAD_CONTENT_TYPES = Set.of( 258 "multipart/form-data", "application/octet-stream", 259 "image/jpeg", "image/png", "image/gif", "image/webp", 260 "application/pdf", "text/csv", "application/zip" 261 ); 262 263 // ========== CHARACTER SECURITY CONSTANTS ========== 264 265 /** Null byte character */ 266 public static final char NULL_BYTE = '\0'; 267 268 /** Common control characters that may be problematic */ 269 public static final Set<Character> PROBLEMATIC_CONTROL_CHARS = Set.of( 270 '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7', 271 '\b', '\f', '\016', '\017', '\020', '\021', '\022', 272 '\023', '\024', '\025', '\026', '\027', '\030', '\031' 273 ); 274 275 /** Characters commonly used in injection attacks */ 276 public static final Set<Character> INJECTION_CHARACTERS = Set.of( 277 '<', '>', '\'', '"', '&', ';', '|', '`', '$', '(', ')', '{', '}' 278 ); 279 280 281 // XSS patterns removed - application layer responsibility. 282 // Application layers have proper context for HTML escaping and validation. 283 284 // ========== ENCODING CONSTANTS ========== 285 286 /** Common double-encoding patterns */ 287 public static final Set<String> DOUBLE_ENCODING_PATTERNS = Set.of( 288 "%25", "%2525", "%252e", "%252f", "%255c", 289 "%2e%2e", "%2f%2e%2e", "%5c%2e%2e" 290 ); 291 292 /** Unicode normalization forms that should be checked */ 293 public static final Set<String> UNICODE_NORMALIZATION_FORMS = Set.of( 294 "NFC", "NFD", "NFKC", "NFKD" 295 ); 296 297 // ========== SIZE LIMITS FOR DIFFERENT SECURITY LEVELS ========== 298 299 /** Configuration preset for strict security requirements */ 300 public static final SecurityConfiguration STRICT_CONFIGURATION = SecurityConfiguration.builder() 301 .maxPathLength(MAX_PATH_LENGTH_STRICT) 302 .allowPathTraversal(false) 303 .allowDoubleEncoding(false) 304 .maxParameterCount(MAX_PARAMETER_COUNT_STRICT) 305 .maxParameterNameLength(MAX_PARAMETER_NAME_LENGTH_STRICT) 306 .maxParameterValueLength(MAX_PARAMETER_VALUE_LENGTH_STRICT) 307 .maxHeaderCount(MAX_HEADER_COUNT_STRICT) 308 .maxHeaderNameLength(MAX_HEADER_NAME_LENGTH_STRICT) 309 .maxHeaderValueLength(MAX_HEADER_VALUE_LENGTH_STRICT) 310 .blockedHeaderNames(DANGEROUS_HEADER_NAMES) 311 .maxCookieCount(MAX_COOKIE_COUNT_STRICT) 312 .maxCookieNameLength(MAX_COOKIE_NAME_LENGTH_STRICT) 313 .maxCookieValueLength(MAX_COOKIE_VALUE_LENGTH_STRICT) 314 .requireSecureCookies(true) 315 .requireHttpOnlyCookies(true) 316 .maxBodySize(MAX_BODY_SIZE_STRICT) 317 .allowedContentTypes(SAFE_CONTENT_TYPES) 318 .allowNullBytes(false) 319 .allowControlCharacters(false) 320 .allowExtendedAscii(false) 321 .normalizeUnicode(true) 322 .caseSensitiveComparison(true) 323 .failOnSuspiciousPatterns(true) 324 .logSecurityViolations(true) 325 .build(); 326 327 /** Configuration preset for balanced security and usability */ 328 public static final SecurityConfiguration DEFAULT_CONFIGURATION = SecurityConfiguration.builder() 329 .maxPathLength(MAX_PATH_LENGTH_DEFAULT) 330 .allowPathTraversal(false) 331 .allowDoubleEncoding(false) 332 .maxParameterCount(MAX_PARAMETER_COUNT_DEFAULT) 333 .maxParameterNameLength(MAX_PARAMETER_NAME_LENGTH_DEFAULT) 334 .maxParameterValueLength(MAX_PARAMETER_VALUE_LENGTH_DEFAULT) 335 .maxHeaderCount(MAX_HEADER_COUNT_DEFAULT) 336 .maxHeaderNameLength(MAX_HEADER_NAME_LENGTH_DEFAULT) 337 .maxHeaderValueLength(MAX_HEADER_VALUE_LENGTH_DEFAULT) 338 .blockedHeaderNames(DEBUG_HEADER_NAMES) 339 .maxCookieCount(MAX_COOKIE_COUNT_DEFAULT) 340 .maxCookieNameLength(MAX_COOKIE_NAME_LENGTH_DEFAULT) 341 .maxCookieValueLength(MAX_COOKIE_VALUE_LENGTH_DEFAULT) 342 .requireSecureCookies(false) 343 .requireHttpOnlyCookies(false) 344 .maxBodySize(MAX_BODY_SIZE_DEFAULT) 345 .blockedContentTypes(DANGEROUS_CONTENT_TYPES) 346 .allowNullBytes(false) 347 .allowControlCharacters(false) 348 .allowExtendedAscii(true) 349 .normalizeUnicode(false) 350 .caseSensitiveComparison(false) 351 .failOnSuspiciousPatterns(false) 352 .logSecurityViolations(true) 353 .build(); 354 355 /** Configuration preset for maximum compatibility */ 356 public static final SecurityConfiguration LENIENT_CONFIGURATION = SecurityConfiguration.builder() 357 .maxPathLength(MAX_PATH_LENGTH_LENIENT) 358 .allowPathTraversal(false) // Still don't allow this 359 .allowDoubleEncoding(true) 360 .maxParameterCount(MAX_PARAMETER_COUNT_LENIENT) 361 .maxParameterNameLength(MAX_PARAMETER_NAME_LENGTH_LENIENT) 362 .maxParameterValueLength(MAX_PARAMETER_VALUE_LENGTH_LENIENT) 363 .maxHeaderCount(MAX_HEADER_COUNT_LENIENT) 364 .maxHeaderNameLength(MAX_HEADER_NAME_LENGTH_LENIENT) 365 .maxHeaderValueLength(MAX_HEADER_VALUE_LENGTH_LENIENT) 366 // No blocked headers in lenient mode 367 .maxCookieCount(MAX_COOKIE_COUNT_LENIENT) 368 .maxCookieNameLength(MAX_COOKIE_NAME_LENGTH_LENIENT) 369 .maxCookieValueLength(MAX_COOKIE_VALUE_LENGTH_LENIENT) 370 .requireSecureCookies(false) 371 .requireHttpOnlyCookies(false) 372 .maxBodySize(MAX_BODY_SIZE_LENIENT) 373 // Only block the most dangerous content types 374 .blockedContentTypes(Set.of("application/x-executable", "application/x-msdos-program")) 375 .allowNullBytes(false) // Still don't allow this 376 .allowControlCharacters(true) 377 .allowExtendedAscii(true) 378 .normalizeUnicode(false) 379 .caseSensitiveComparison(false) 380 .failOnSuspiciousPatterns(false) 381 .logSecurityViolations(true) 382 .build(); 383}