Record Class DecodingStage

java.lang.Object
java.lang.Record
de.cuioss.http.security.validation.DecodingStage
Record Components:
config - Security configuration controlling validation behavior.
validationType - Type of validation being performed (URL_PATH, PARAMETER_NAME, etc.).
All Implemented Interfaces:
HttpSecurityValidator

public record DecodingStage(SecurityConfiguration config, ValidationType validationType) extends Record implements HttpSecurityValidator
HTTP protocol-layer decoding validation stage with security checks.

This stage performs URL decoding with security validation to detect and prevent HTTP protocol-layer encoding attacks such as double encoding and overlong UTF-8 encoding. Architectural Scope: Limited to HTTP/URL protocol encodings only.

  1. Double Encoding Detection - Identifies %25XX patterns indicating double encoding
  2. Overlong UTF-8 Detection - Blocks malformed UTF-8 encoding attacks
  3. URL Decoding - Performs standard URL percent-decoding
  4. Unicode Normalization - Optionally normalizes Unicode and detects changes

Design Principles

  • Immutability - All fields are final, stage instances are immutable
  • Thread Safety - Safe for concurrent use across multiple threads
  • Performance - Uses pre-compiled patterns and efficient operations
  • Security First - Detects attacks before potentially dangerous decoding

Security Validations

  • Double Encoding - Detects %25XX patterns that could bypass filters
  • Overlong UTF-8 - Blocks malformed UTF-8 encoding attacks
  • Invalid Encoding - Catches malformed percent-encoded sequences
  • Unicode Normalization Attacks - Detects normalization changes that could alter meaning

Usage Examples

 // Create decoding stage for URL paths
 SecurityConfiguration config = SecurityConfiguration.defaults();
 DecodingStage pathDecoder = new DecodingStage(config, ValidationType.URL_PATH);

 // Validate and decode input
 try {
     String decoded = pathDecoder.validate("/api/users%2F123");
     // Returns: "/api/users/123"
 } catch (UrlSecurityException e) {
     // Handle security violation
     logger.warn("Encoding attack detected: {}", e.getFailureType());
 }

 // Double encoding detection
 try {
     pathDecoder.validate("/admin%252F../users"); // %25 = encoded %
     // Throws UrlSecurityException with DOUBLE_ENCODING failure type
 } catch (UrlSecurityException e) {
     // Attack blocked before decoding
 }
 

Performance Characteristics

  • O(n) time complexity where n is input length
  • Single pass through input for double encoding detection
  • Minimal memory allocation - reuses pattern instances
  • Early termination on security violations

Implements: Task V1 from HTTP verification specification

Since:
1.0
See Also:
  • Constructor Details

  • Method Details

    • validate

      public Optional<String> validate(@Nullable String value) throws UrlSecurityException
      Validates input through HTTP protocol-layer decoding with security checks.

      Architectural Boundary: This stage operates strictly at the HTTP protocol layer, handling URL-specific encoding schemes. Application-layer encodings (HTML entities, JS escapes) are handled by higher application layers where they have proper context.

      HTTP Protocol Processing stages:

      1. Double encoding detection - fails fast if %25XX patterns found
      2. UTF-8 overlong encoding detection - blocks malformed UTF-8 attack patterns
      3. URL decoding - converts percent-encoded sequences to characters
      4. Unicode normalization - optionally normalizes and detects changes
      Specified by:
      validate in interface HttpSecurityValidator
      Parameters:
      value - The input string to validate and decode
      Returns:
      The validated and decoded string wrapped in Optional, or Optional.empty() if input was null
      Throws:
      UrlSecurityException - if any security violations are detected:
      • DOUBLE_ENCODING - if double encoding patterns are found
      • INVALID_ENCODING - if URL decoding fails due to malformed input
      • UNICODE_NORMALIZATION_CHANGED - if Unicode normalization changes the string
    • when

      Creates a conditional validator that only processes non-null, non-empty inputs.
      Specified by:
      when in interface HttpSecurityValidator
      Parameters:
      condition - The condition under which to apply this validator
      Returns:
      A conditional HttpSecurityValidator that skips null/empty inputs
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared with Objects::equals(Object,Object).
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • config

      Returns the value of the config record component.
      Returns:
      the value of the config record component
    • validationType

      Returns the value of the validationType record component.
      Returns:
      the value of the validationType record component