nyx/docs/rules/ruby.md
Eli Peter 1bbe4b1cfb
Phase 1 (#33)
* chore: Exclude CLAUDE.md from Cargo.toml

* feat: add callgraph module and integrate into main analysis flow

* feat: enhance CLI with new severity filtering and analysis modes

* feat: update CHANGELOG with recent enhancements and fixes to severity filtering and output handling

* feat: implement state-model dataflow analysis for resource lifecycle and auth state

* feat: enhance diagnostic output formatting and add evidence structure

* feat: implement attack surface ranking for diagnostics with scoring and sorting

* feat: add comprehensive documentation for installation, usage, and rules reference

* feat: add multiple language support for command execution and evaluation endpoints

* feat: implement inline suppression for findings using `nyx:ignore` comments

* feat: add confidence levels to AST patterns and update output structure

* feat: implement low-noise prioritization system with category filtering, rollup grouping, and configurable budgets

* feat: bump version to 0.4.0 and update changelog with new features and improvements

* feat: add dead code allowances to various functions in mod.rs and real_world_tests.rs
2026-02-25 21:16:36 -05:00

3.5 KiB

Ruby Rules

Nyx detects Ruby vulnerabilities through AST patterns and taint analysis, covering code execution, command injection, deserialization, reflection, SSRF, and weak crypto.

Taint Labels

Ruby has moderate taint label coverage. Sources, sinks, and sanitizers are defined in src/labels/ruby.rs.

Sources

Matcher Cap
ENV, gets all
params all

Note: Ruby's params[:cmd] subscript access is detected via element_reference node handling in the CFG. Sinatra/Rails do...end blocks are walked as function scopes.

Sanitizers

Matcher Cap
CGI.escapeHTML, ERB::Util.html_escape HTML_ESCAPE
Shellwords.escape, Shellwords.shellescape SHELL_ESCAPE

Sinks

Matcher Cap
system, exec SHELL_ESCAPE
eval SHELL_ESCAPE
puts, print HTML_ESCAPE

AST Pattern Rules

Code Execution

Rule ID Severity Tier Description
rb.code_exec.eval High A Kernel#eval — dynamic code execution
rb.code_exec.instance_eval High A instance_eval — evaluates string in object context
rb.code_exec.class_eval High A class_eval / module_eval — evaluates string in class context

Command Execution

Rule ID Severity Tier Description
rb.cmdi.backtick High A Backtick shell execution (`cmd`)
rb.cmdi.system_interp High A system/exec call — command execution risk

Deserialization

Rule ID Severity Tier Description
rb.deser.yaml_load High A YAML.load — arbitrary object deserialization
rb.deser.marshal_load High A Marshal.load — arbitrary Ruby object deserialization

Reflection

Rule ID Severity Tier Description
rb.reflection.send_dynamic Medium B send() with non-symbol argument — arbitrary method dispatch
rb.reflection.constantize Medium A constantize / safe_constantize — dynamic class resolution

SSRF

Rule ID Severity Tier Description
rb.ssrf.open_uri Medium A Kernel#open with HTTP URL — SSRF via open-uri

Weak Crypto

Rule ID Severity Tier Description
rb.crypto.md5 Low A Digest::MD5 — weak hash algorithm

Examples

rb.deser.yaml_load — Unsafe YAML deserialization

Vulnerable:

data = YAML.load(params[:config])  # Arbitrary object instantiation

Safe alternative:

data = YAML.safe_load(params[:config])  # Only basic Ruby types

rb.cmdi.backtick — Backtick shell execution

Vulnerable:

output = `ls #{user_dir}`  # Command injection via interpolation

Safe alternative:

require 'open3'
output, status = Open3.capture2('ls', user_dir)

rb.reflection.send_dynamic — Dynamic method dispatch

Vulnerable:

obj.send(params[:method], params[:arg])  # Arbitrary method invocation

Safe alternative:

allowed = %w[name email phone]
if allowed.include?(params[:method])
  obj.send(params[:method])
end

rb.deser.marshal_load — Marshal deserialization

Vulnerable:

obj = Marshal.load(request.body.read)

Safe alternative:

data = JSON.parse(request.body.read)