Code Injection Prevention

Avoid dangerous evaluation APIs, sanitize user input, and guard deserialization boundaries.

Beginner 1 min read

Code Injection Prevention

Ruby makes it easy to execute dynamic code. Guard those edges carefully—never evaluate user input, and always sanitise data crossing trust boundaries.

Avoid or sandbox these methods

  • `eval`, `instance_eval`, `class_eval`, `module_eval` – executing arbitrary strings as Ruby code.
  • `send`/`public_send` with user input – restrict to whitelisted method names.
  • `Kernel#open`, `open-uri` with external URLs – prefer HTTP clients or whitelist domains.
  • `YAML.load` – use `YAML.safe_load` with permitted classes.
  • Backticks and `system` – prefer `system(cmd, arg1, arg2)` array form to avoid shell interpolation.

Safer patterns

ALLOWED_FORMATTERS = %w[markdown plaintext] def render_body(format, content) raise ArgumentError unless ALLOWED_FORMATTERS.include?(format) public_send("render_\#{format}", content) end # Shell commands: use array form system('/usr/bin/env', 'bundle', 'exec', 'rubocop')

Prevention playbook

  1. Whitelist acceptable values (method names, template IDs) rather than dynamically building strings.
  2. Escape or parameterise user data in SQL, shell commands, and templating contexts.
  3. Run static analysis (Brakeman) to detect dangerous meta-programming usage.
  4. Review third-party gems for unsafe APIs before adopting them in production.