How must sanitized modifiers match between parent and override methods?
← Security and Sanitization · Ref: Q686
The 'sanitized' modifier on parameters must match EXACTLY between a parent method and its override. This prevents security gaps caused by polymorphic dispatch.
EXACT MATCH REQUIRED (E07940)
If the parent declares a parameter as sanitized, the override must also declare it as sanitized. Removing sanitized from an override creates a vulnerability: callers expecting sanitization would get unsanitized processing through polymorphism.
ADDING SANITIZED ALSO PROHIBITED (E07930)
If the parent does NOT use sanitized, the override cannot add it. Adding sanitized changes the method contract (data gets modified before use), violating Liskov Substitution.
WHY THIS MATTERS
handler <- getHandler() // Could be Base or Derived handler.process(userInput) // Is input sanitized or not?
Without matching, security depends on which runtime type is active.
SAFE COPY PATTERN
Inside methods with sanitized parameters, create a safe copy before processing:
safeCopy <- String(inputText) result: transform(safeCopy)
See Q663 for override sanitized match details. See Q661 for sanitized parameter basics. See Q662 for safe copy patterns.
Example
defines module qa.sanitizeddeep.overridematch defines class <?- Base class with sanitized parameter. All overrides must maintain the sanitized modifier. -?> InputHandler as open processInput() -> userInput as sanitized String <- cleanResult as String: "" safeCopy <- String(userInput) cleanResult: "Handled: " + safeCopy default operator ? <?- Correct override: sanitized matches the parent. Security contract is maintained through polymorphism. -?> StrictHandler extends InputHandler override processInput() -> userInput as sanitized String <- cleanResult as String: "" safeCopy <- String(userInput) cleanResult: "Strict: " + safeCopy default operator ? <?- Second correct override demonstrating consistent sanitized. -?> LoggingHandler extends InputHandler override processInput() -> userInput as sanitized String <- cleanResult as String: "" safeCopy <- String(userInput) cleanResult: "Logged: " + safeCopy default operator ? defines program SanitizedOverrideMatchDemo() stdout <- Stdout() handlers <- List() of InputHandler handlers += StrictHandler() handlers += LoggingHandler() for handler in handlers result <- handler.processInput("user <script> input") stdout.println(result)
Common mistakes
E07930 — Direct assignment from a sanitized parameter creates hidden aliasing where both variables share the same sanitized copy. Use String(param) copy constructor for an independent copy. See ek9 -h E07930 for details.
Incorrect:
safeCopy <- userInput
Correct:
safeCopy <- String(userInput)
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
result <- handler.processInput("user <script> input").toUpperCase()
Correct:
result <- handler.processInput("user <script> input")
Other ways to ask this
- What is E07930 sanitized parameter error?
- Why must parent and child sanitized modifiers agree?
- Must sanitized match exactly when overriding a method?
- What happens if I remove sanitized from an override?
Coming from another language?
Java: no compiler enforcement, overrides can change validation. Python: no enforcement. Go: no inheritance. Rust: trait implementations must match. Kotlin: no sanitized concept. EK9: compiler enforces sanitized matching in overrides for Liskov compliance.
Keywords: LSP, Liskov, open, match, visitor, abstract, virtual, handler, sanitize, override, validate, function, sealed, sanitized, E07930, E07940, polymorphism, security