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.core;
017
018/**
019 * Comprehensive enumeration of security failure types for URL validation.
020 * Each failure type represents a specific class of security violation that
021 * can occur during URL processing and validation.
022 *
023 * <h3>Design Principles</h3>
024 * <ul>
025 *   <li><strong>Comprehensive Coverage</strong> - Covers all major URL security attack vectors</li>
026 *   <li><strong>Clear Categorization</strong> - Groups related failure types for easier handling</li>
027 *   <li><strong>Descriptive Names</strong> - Self-documenting enum values</li>
028 *   <li><strong>Immutable Design</strong> - Thread-safe for concurrent validation</li>
029 * </ul>
030 *
031 * <h3>Usage Example</h3>
032 * <pre>
033 * if (containsPathTraversal(path)) {
034 *     throw UrlSecurityException.builder()
035 *         .failureType(UrlSecurityFailureType.PATH_TRAVERSAL_DETECTED)
036 *         .input(path)
037 *         .build();
038 * }
039 * </pre>
040 *
041 * Implements: Task B1 from HTTP verification specification
042 *
043 * @since 1.0
044 */
045public enum UrlSecurityFailureType {
046
047    // === Encoding Issues ===
048
049    /** Invalid URL encoding sequences detected (e.g., incomplete percent encoding) */
050    INVALID_ENCODING("Invalid URL encoding detected"),
051
052    /** Double URL encoding patterns detected (e.g., %252e for double-encoded '.') */
053    DOUBLE_ENCODING("Double URL encoding detected"),
054
055    /** Unicode normalization changed the input, potentially bypassing security checks */
056    UNICODE_NORMALIZATION_CHANGED("Unicode normalization altered input"),
057
058    // === Path Traversal Attacks ===
059
060    /** Path traversal patterns like "../" or equivalent encodings detected */
061    PATH_TRAVERSAL_DETECTED("Path traversal pattern detected"),
062
063    /** Attempt to escape from allowed directory structure detected */
064    DIRECTORY_ESCAPE_ATTEMPT("Directory escape attempt detected"),
065
066    // === Character-Based Attacks ===
067
068    /** Invalid or dangerous characters found in URL */
069    INVALID_CHARACTER("Invalid character detected"),
070
071    /** Null byte injection attack detected (e.g., \u0000) */
072    NULL_BYTE_INJECTION("Null byte injection detected"),
073
074    /** Control characters that could manipulate processing detected */
075    CONTROL_CHARACTERS("Control characters detected"),
076
077    // === Size and Length Violations ===
078
079    /** Path exceeds configured maximum length limits */
080    PATH_TOO_LONG("Path exceeds maximum length"),
081
082    /** Input exceeds configured maximum length limits */
083    INPUT_TOO_LONG("Input exceeds maximum length"),
084
085    /** Excessive directory nesting depth detected */
086    EXCESSIVE_NESTING("Excessive directory nesting"),
087
088    // === Pattern-Based Detection ===
089
090    /** Suspicious patterns that match attack signatures */
091    SUSPICIOUS_PATTERN_DETECTED("Suspicious pattern detected"),
092
093    /** Suspicious parameter name commonly used in attacks */
094    SUSPICIOUS_PARAMETER_NAME("Suspicious parameter name detected"),
095
096    /** Known attack signatures from security databases */
097    KNOWN_ATTACK_SIGNATURE("Known attack signature detected"),
098
099    // XSS detection removed - application layer responsibility.
100    // Application layers have proper context for HTML/JS escaping and validation.
101
102    // === Structural Issues ===
103
104    /** Input structure is malformed or corrupted */
105    MALFORMED_INPUT("Malformed input structure"),
106
107    /** Input structure violates expected format */
108    INVALID_STRUCTURE("Invalid input structure"),
109
110    // === Protocol Violations ===
111
112    /** General protocol specification violation */
113    PROTOCOL_VIOLATION("Protocol specification violation"),
114
115    /** RFC specification violation (HTTP, URI, etc.) */
116    RFC_VIOLATION("RFC specification violation"),
117
118    // === IPv6 and Host-Based Attacks ===
119
120    /** Invalid IPv6 address format detected */
121    INVALID_IPV6_FORMAT("Invalid IPv6 address format"),
122
123    /** Malformed URL structure detected */
124    MALFORMED_URL("Malformed URL structure"),
125
126    /** Invalid host format detected */
127    INVALID_HOST_FORMAT("Invalid host format"),
128
129    /** Invalid URL format detected */
130    INVALID_URL_FORMAT("Invalid URL format");
131
132    private final String description;
133
134    /**
135     * Creates a new failure type with the specified description.
136     *
137     * @param description Human-readable description of this failure type
138     */
139    UrlSecurityFailureType(String description) {
140        this.description = description;
141    }
142
143    /**
144     * Returns the human-readable description of this failure type.
145     *
146     * @return Description text suitable for logging and error reporting
147     */
148    public String getDescription() {
149        return description;
150    }
151
152    /**
153     * Indicates whether this failure type represents an encoding-related issue.
154     *
155     * @return true if this is an encoding-related failure type
156     */
157    public boolean isEncodingIssue() {
158        return this == INVALID_ENCODING ||
159                this == DOUBLE_ENCODING ||
160                this == UNICODE_NORMALIZATION_CHANGED;
161    }
162
163    /**
164     * Indicates whether this failure type represents a path traversal attack.
165     *
166     * @return true if this is a path traversal-related failure type
167     */
168    public boolean isPathTraversalAttack() {
169        return this == PATH_TRAVERSAL_DETECTED ||
170                this == DIRECTORY_ESCAPE_ATTEMPT;
171    }
172
173    /**
174     * Indicates whether this failure type represents a character-based attack.
175     *
176     * @return true if this is a character-based failure type
177     */
178    public boolean isCharacterAttack() {
179        return this == INVALID_CHARACTER ||
180                this == NULL_BYTE_INJECTION ||
181                this == CONTROL_CHARACTERS;
182    }
183
184    /**
185     * Indicates whether this failure type represents a size or length violation.
186     *
187     * @return true if this is a size/length-related failure type
188     */
189    public boolean isSizeViolation() {
190        return this == PATH_TOO_LONG ||
191                this == INPUT_TOO_LONG ||
192                this == EXCESSIVE_NESTING;
193    }
194
195    /**
196     * Indicates whether this failure type represents a pattern-based detection.
197     *
198     * @return true if this is a pattern-based failure type
199     */
200    public boolean isPatternBased() {
201        return this == SUSPICIOUS_PATTERN_DETECTED ||
202                this == SUSPICIOUS_PARAMETER_NAME ||
203                this == KNOWN_ATTACK_SIGNATURE;
204    }
205
206    // XSS attack detection removed - application layer responsibility.
207    // Application layers have proper context for HTML/JS escaping and validation.
208
209    /**
210     * Indicates whether this failure type represents a structural issue.
211     *
212     * @return true if this is a structural failure type
213     */
214    public boolean isStructuralIssue() {
215        return this == MALFORMED_INPUT ||
216                this == INVALID_STRUCTURE;
217    }
218
219    /**
220     * Indicates whether this failure type represents a protocol violation.
221     *
222     * @return true if this is a protocol-related failure type
223     */
224    public boolean isProtocolViolation() {
225        return this == PROTOCOL_VIOLATION ||
226                this == RFC_VIOLATION;
227    }
228
229    /**
230     * Indicates whether this failure type represents an IPv6 or host-based attack.
231     *
232     * @return true if this is an IPv6/host-related failure type
233     */
234    public boolean isIPv6HostAttack() {
235        return this == INVALID_IPV6_FORMAT ||
236                this == MALFORMED_URL ||
237                this == INVALID_HOST_FORMAT ||
238                this == INVALID_URL_FORMAT;
239    }
240}