Skip to content

1.6.0: execute_ruby sandbox hardening + dependency & security updates

Choose a tag to compare

@mariochavez mariochavez released this 04 Aug 16:05
· 4 commits to main since this release
5cf6e88

Maintenance and security release. Drops Ruby 3.2, bumps core dependencies (clearing several HIGH advisories), hardens the execute_ruby sandbox, and fixes version-manager Ruby resolution and namespaced-model resolution.

Added

  • Namespaced model resolution in analyze_models: Module-namespaced models now resolve from every input form — Namespace::Model, the file path namespace/model, the flattened NamespaceModel, and the bare leaf Model — independent of the app's custom inflections. Previously namespaced models could be reported as "not found".

Changed

  • Dropped Ruby 3.2 support (breaking): The minimum supported Ruby is now 3.3 (required_ruby_version >= 3.3.0), and the CI matrix tests Ruby 3.3 and 3.4. Dependency updates pull in transitive gems (dry-configurable 1.4.0, parallel 2.1.0) that require Ruby >= 3.3.
  • Dependency updates: Bumped project dependencies, including major upgrades to puma (> 8.0), minitest (> 6.0) and mocha (~> 3.0), plus activesupport 8.1.3.1, addressable 2.9.0, rubocop 1.88.2, standard 1.56.0 and other transitive gems.
  • Deterministic linting: Added .standard.yml pinning ruby_version: 3.3 to match the gemspec's minimum supported Ruby, so Standard/RuboCop target the supported floor regardless of the local or CI Ruby.

Fixed

  • Version-manager Ruby resolution for Rails-runner tools (mise/asdf/rbenv agnostic): Tools that shell out to bin/rails (execute_ruby, get_schema, and the introspection half of analyze_models / analyze_controller_views) no longer fall back to the system Ruby on machines managed by mise or asdf. It now prepends the active manager's shims directory (honoring MISE_DATA_DIR/XDG_DATA_HOME/ASDF_DATA_DIR/RBENV_ROOT) to the subprocess PATH and runs a non-login shell, so the project's Ruby is used. rvm (which has no shims) is still sourced when present.
  • analyze_models introspection constant: The introspection runner now derives the canonical constant from the resolved model file (loaded via Object.const_get) instead of interpolating the raw user input, fixing invalid-Ruby / NameError failures for path and flattened inputs and removing an unvalidated-input injection surface.
  • Analyzer errors no longer swallowed: The analyzer runner path dropped 2>/dev/null, so a Rails boot failure now surfaces the real error instead of a blank "Error executing Rails command".
  • execute_ruby timezone data access: The sandbox now allows read-only access to system timezone directories (/usr/share/zoneinfo, /usr/share/lib/zoneinfo, /etc/zoneinfo, /var/db/timezone), so code touching Time.zone no longer fails with a spurious PATH ERROR. Writes and all other out-of-project reads remain blocked.

Security

  • execute_ruby sandbox hardening: Closed several read-path bypasses and added defense-in-depth layers.
    • File-read coverage: IO.read/readlines/binread/foreach and File.readlines/binread/foreach are now sandboxed too (previously IO.read('/etc/passwd') and File.readlines bypassed path validation). The raw native readers are no longer exposed as public File.original_read-style aliases.
    • Symlink resolution: path validation now resolves symlinks (realpath) before checking, so a link inside the project can't point outside it.
    • Broader ENV block: the static scan now rejects all ENV access (ENV.to_h, ENV.values_at, ENV.each, …), not just ENV[]/ENV.fetch.
    • Database writes rolled back: user code runs inside a transaction that is always rolled back, so accidental delete_all/update/save/raw DML are undone. (Harm reduction — DDL may auto-commit on some adapters and after_commit callbacks are suppressed.)
    • Timeout actually stops runaway code: the execution timeout now kills the entire process group.
    • Confirmation for dual-use constructs: send, public_send, const_get, and Kernel#open are no longer run implicitly; callers must opt in with the new confirm_risky: true parameter after a human reviews the code.
  • Puma advisories resolved: Upgrading to puma 8.0.2 addresses CVE-2026-47736 and CVE-2026-47737 (both HIGH). Dependency updates also clear the concurrent-ruby ReadWriteLock advisory (GHSA-6wx8-w4f5-wwcr). bundler-audit now reports no vulnerabilities.

Full changelog: https://github.com/maquina-app/rails-mcp-server/blob/v1.6.0/CHANGELOG.md