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}