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