What are the security best practices in EK9?

← Security and Sanitization · Ref: Q218

EK9 provides multiple security features that work together. Following these best practices prevents common vulnerability classes.

SANITIZED PARAMETERS

Mark external input with 'sanitized':

  -> userInput as sanitized String

The compiler tracks tainted data flow.

COPY CONSTRUCTOR PATTERN

Always create defensive copies:

  localCopy <- String(userInput)

Prevents reference aliasing and injection.

PURE FUNCTIONS

Use pure functions for data processing:

  process() as pure

Purity prevents side effects and forces safe data handling.

REQUIRE VALIDATION

Use require for input validation:

  require input?
  require length input > 0

Fails fast on invalid input.

MUTEXLOCK FOR SHARED STATE

Protect shared data with a MutexLock held as a FIELD on a wrapping class (locals are rejected by E08256):

  SharedCache
    locked as MutexLock of Dict of (String, String): MutexLock(Dict() of (String, String))

The wrapping class's methods are the only API to the protected data; MutexKey callbacks define the critical sections. The field-rooted home enables compile-time data-race detection. See Q158.

TYPE SAFETY

EK9's strong typing prevents type confusion attacks. No implicit conversions, no null references.

See Q215 for sanitized parameters. See Q29 for unset variables. See Q158 for MutexLock.

See Q215 for sanitized parameters. See Q217 for sanitized and pure. See Q268 for OWASP vulnerability prevention. See Q272 for defense in depth.

Example

defines module qa.security.bestpractices

  defines function

    // Best practice: sanitized + pure + copy constructor
    secureProcess() as pure
      -> input as sanitized String
      <- result as String?

      // 1. Copy constructor for defensive copy
      cleanInput <- String(input)

      // 2. Validate with require
      require cleanInput?

      // 3. Process the clean copy
      result: "Secure: " + cleanInput

  defines program

    SecurityBestPracticesDemo()
      stdout <- Stdout()

      userInput <- "user input"

      // === SANITIZED + PURE + REQUIRE ===

      result <- secureProcess(userInput)
      if result?
        stdout.println(result)

      // === SECURITY FEATURES SUMMARY ===

      stdout.println("EK9 security best practices:")
      stdout.println("  1. sanitized on external input")
      stdout.println("  2. Copy constructor for defensive copies")
      stdout.println("  3. Pure functions for processing")
      stdout.println("  4. require for input validation")
      stdout.println("  5. MutexLock for shared state")
      stdout.println("  6. Strong typing prevents confusion")

Common mistakes

E50060 — String does not have a sanitize() method. Use the copy constructor String(value) to create a defensive copy. The sanitized modifier on the parameter is the security mechanism, not a method call. See ek9 -h E50060 for details.

Incorrect:

cleanInput <- input.sanitize()

Correct:

cleanInput <- String(input)
Other ways to ask this
  • How do I write secure code in EK9?
  • What security features does EK9 provide?
  • How do I prevent security vulnerabilities in EK9?

Coming from another language?

Java: OWASP guidelines, Spring Security, manual defensive coding. Python: input validation libraries, no compile-time safety. Rust: ownership model prevents many bugs. Go: manual security practices. Kotlin: null safety helps but no sanitization. EK9: sanitized keyword, pure functions, require validation, MutexLock, and strong typing provide layered security.

Keywords: type, side-effect, require, mutex, practices, security, sanitized, protect, immutable, best, pure, safe, safety