How does the 'sanitized' parameter modifier work in EK9?

← Security and Sanitization · Ref: Q215

The 'sanitized' modifier on parameters tells the compiler to track input that needs careful handling. It enables compile-time input validation tracking.

SANITIZED PARAMETER

Mark a parameter as sanitized:

  processInput() as pure
    -> input as sanitized String

The compiler knows this parameter contains external, potentially dangerous data.

COPY CONSTRUCTOR PATTERN

In pure contexts, create a safe local copy:

  localCopy <- String(input)

This breaks any reference aliasing and creates independent data.

NON-PURE CONTEXT

In non-pure functions, use :=: or :~: on initialized variables:

  safeCopy <- String(sql)
  result: ""
  result :=: safeCopy

DIRECT USE IN EXPRESSIONS

Using sanitized parameters in expressions is safe because it creates new values:

  output: "Processed: " + input

See Q216 for threat detection. See Q217 for pure function interaction. See Q49 for function basics. See Q54 for pure functions. See Q269 for input validation. See Q271 for secrets and environment variables. See Q272 for defense in depth.

See Q661 for sanitized parameter restrictions. See Q662 for safe copy patterns. See Q663 for override matching.

Example

defines module qa.security.sanitized

  defines function

    // Pure function with sanitized parameter
    pureProcess() as pure
      -> input as sanitized String
      <- result as String?

      // Copy constructor creates safe local copy
      localCopy <- String(input)
      result: "Processed: " + localCopy

    // Non-pure function with sanitized parameter
    queryProcess()
      -> sql as sanitized String
      <- result as String?

      // Copy constructor first
      safeCopy <- String(sql)
      result: ""
      result :=: safeCopy

    // Direct expression use is safe
    logInput() as pure
      -> userInput as sanitized String
      <- output as String?

      // Concatenation creates new string
      output: "Log: " + userInput

  defines program

    SanitizedParameterDemo()
      stdout <- Stdout()

      // === PURE FUNCTION WITH SANITIZED ===

      query <- "SELECT * FROM users"
      result1 <- pureProcess(query)
      if result1?
        stdout.println(result1)

      // === NON-PURE WITH COPY ===

      result2 <- queryProcess(query)
      if result2?
        stdout.println("Query: " + result2)

      // === DIRECT EXPRESSION ===

      result3 <- logInput("user data")
      if result3?
        stdout.println(result3)

Common mistakes

E50060 — String does not have a clone() method. Use the copy constructor String(value) to create a defensive copy. Calling a non-existent method triggers E50060 — method not resolved. See ek9 -h E50060 for details.

Incorrect:

localCopy <- input.clone()

Correct:

localCopy <- String(input)
Other ways to ask this
  • How do I mark parameters as sanitized in EK9?
  • How does EK9 track tainted input?
  • How do I handle user input safely in EK9?

Coming from another language?

Java: no language-level sanitization, relies on OWASP libraries. Python: no built-in taint tracking. Rust: newtype pattern for manual tracking. Go: no taint tracking. Kotlin: no sanitization modifier. EK9: 'sanitized' keyword on parameters enables compile-time tracking of tainted data.

Keywords: tainted, safe, input, compile-time, copy, validation, sanitized, protect, injection, security