Class CharacterValidationStage

java.lang.Object
de.cuioss.http.security.validation.CharacterValidationStage
All Implemented Interfaces:
HttpSecurityValidator

public final class CharacterValidationStage extends Object implements 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
    (default: false)

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

  • Method Details

    • validate

      public Optional<String> validate(@Nullable String value) throws UrlSecurityException
      Description copied from interface: HttpSecurityValidator
      Validates 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:
      validate in interface HttpSecurityValidator
      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.