java.lang.Object
de.cuioss.http.security.validation.CharacterValidationStage
- All Implemented Interfaces:
HttpSecurityValidator
Character validation stage that enforces RFC-compliant character sets for HTTP components.
This stage validates input characters against component-specific allowed character sets, ensuring compliance with HTTP specifications and preventing character-based security attacks. It performs comprehensive character validation including null byte detection, control character filtering, and percent-encoding validation.
Design Principles
- RFC Compliance - Enforces RFC 3986 (URI) and RFC 7230 (HTTP) character rules
- Security First - Rejects dangerous characters before any processing
- Context Aware - Different character sets for different HTTP components
- Performance Optimized - Uses BitSet for O(1) character lookups
- Configurable - Allows fine-tuning of character validation rules
Character Validation Rules
- URL Paths - RFC 3986 unreserved + path-specific characters
- Parameters - RFC 3986 query characters with percent-encoding support
- Headers - RFC 7230 visible ASCII minus delimiters
- Cookies - Restricted character set for cookie safety
- Bodies - Content-type specific character validation
Security Features
- Null Byte Detection - Prevents null byte injection attacks
- Control Character Filtering - Blocks dangerous control characters
- Percent Encoding Validation - Validates hex digit sequences
- High-Bit Character Control - Configurable handling of non-ASCII characters
Usage Examples
// Create character validation stage
SecurityConfiguration config = SecurityConfiguration.defaults();
CharacterValidationStage validator = new CharacterValidationStage(config, ValidationType.URL_PATH);
// Validate URL path characters
try {
validator.validate("/api/users/123"); // Valid path characters
validator.validate("/api/../etc/passwd"); // May contain invalid traversal patterns
} catch (UrlSecurityException e) {
logger.warn("Invalid characters detected: {}", e.getFailureType());
}
// Validate parameter with percent encoding
CharacterValidationStage paramValidator = new CharacterValidationStage(config, ValidationType.PARAMETER_VALUE);
try {
paramValidator.validate("hello%20world"); // Valid percent-encoded space
paramValidator.validate("hello%00world"); // Null byte - will be rejected
} catch (UrlSecurityException e) {
logger.warn("Character validation failed: {}", e.getDetail());
}
Configuration Options
- allowNullBytes - Whether to permit null bytes (default: false)
- allowControlCharacters - Whether to permit control characters (default: false)
- allowExtendedAscii - Whether to permit extended ASCII characters (128-255).
- For URL paths and parameters: Allows characters 128-255 when enabled
- For header names and cookies: Always rejected per RFC (setting ignored)
- For header values and body: Enables both extended ASCII and Unicode support
- Note: Unicode beyond 255 is always rejected for URLs per RFC 3986
Performance Characteristics
- O(n) time complexity where n is input length
- O(1) character lookup using BitSet
- Early termination on first invalid character
- Minimal memory allocation during validation
- Since:
- 1.0
- See Also:
-
Constructor Details
-
CharacterValidationStage
-
-
Method Details
-
validate
Description copied from interface:HttpSecurityValidatorValidates the input string and returns the sanitized/normalized version.This method should examine the input for security violations and either:
- Return the input unchanged if it's safe
- Return a sanitized/normalized version if safe transformations are possible
- Return Optional.empty() if the input was null
- Throw UrlSecurityException if the input represents a security threat
The decision between sanitization and rejection depends on the specific validator and security requirements. Critical security validators should prefer rejection over sanitization to avoid bypasses.
- Specified by:
validatein interfaceHttpSecurityValidator- Parameters:
value- The input to validate. May be null.- Returns:
- The validated, potentially sanitized or normalized value wrapped in Optional. Returns Optional.empty() if the input was null.
- Throws:
UrlSecurityException- If the input represents a security violation that cannot be safely sanitized. The exception should include detailed context about the failure for logging and debugging purposes.
-