Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config.disable_sandbox option to Rails console #35723

Merged
merged 1 commit into from Mar 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions guides/source/configuring.md
Expand Up @@ -86,6 +86,8 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
end
```

* `config.disable_sandbox` controls whether or not someone could start a console in sandbox mode, as a long session of sandbox console could lead database server to run out of memory.

* `config.eager_load` when `true`, eager loads all registered `config.eager_load_namespaces`. This includes your application, engines, Rails frameworks, and any other registered namespace.

* `config.eager_load_namespaces` registers namespaces that are eager loaded when `config.eager_load` is `true`. All namespaces in the list must respond to the `eager_load!` method.
Expand Down
8 changes: 8 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,11 @@
* Add `config.disable_sandbox` option to Rails console.

This setting will disable `rails console --sandbox` mode, preventing
developer from accidentally starting a sandbox console, left it inactive,
and cause the database server to run out of memory.

*Prem Sichanugrist*

* Add `-e/--environment` option to `rails initializers`.

*Yuji Yaginuma*
Expand Down
4 changes: 3 additions & 1 deletion railties/lib/rails/application/configuration.rb
Expand Up @@ -18,7 +18,8 @@ class Configuration < ::Rails::Engine::Configuration
:session_options, :time_zone, :reload_classes_only_on_change,
:beginning_of_week, :filter_redirect, :x, :enable_dependency_loading,
:read_encrypted_secrets, :log_level, :content_security_policy_report_only,
:content_security_policy_nonce_generator, :require_master_key, :credentials
:content_security_policy_nonce_generator, :require_master_key, :credentials,
:disable_sandbox

attr_reader :encoding, :api_only, :loaded_config_version, :autoloader

Expand Down Expand Up @@ -65,6 +66,7 @@ def initialize(*)
@credentials.content_path = default_credentials_content_path
@credentials.key_path = default_credentials_key_path
@autoloader = :classic
@disable_sandbox = false
end

def load_defaults(target_version)
Expand Down
6 changes: 6 additions & 0 deletions railties/lib/rails/commands/console/console_command.rb
Expand Up @@ -26,6 +26,12 @@ def initialize(app, options = {})
@options = options

app.sandbox = sandbox?

if sandbox? && app.config.disable_sandbox
puts "Error: Unable to start console in sandbox mode as sandbox mode is disabled (config.disable_sandbox is true)."
exit 1
end

app.load_console

@console = app.config.console || IRB
Expand Down
16 changes: 16 additions & 0 deletions railties/test/application/configuration_test.rb
Expand Up @@ -2476,6 +2476,22 @@ class MyLogger < ::Logger
assert_includes Rails.application.config.hosts, ".localhost"
end

test "disable_sandbox is false by default" do
app "development"

assert_equal false, Rails.configuration.disable_sandbox
end

test "disable_sandbox can be overridden" do
add_to_config <<-RUBY
config.disable_sandbox = true
RUBY

app "development"

assert Rails.configuration.disable_sandbox
end

private
def force_lazy_load_hooks
yield # Tasty clarifying sugar, homie! We only need to reference a constant to load it.
Expand Down
21 changes: 18 additions & 3 deletions railties/test/application/console_test.rb
Expand Up @@ -123,13 +123,17 @@ def write_prompt(command, expected_output = nil)
assert_output "> ", @primary
end

def spawn_console(options)
Process.spawn(
def spawn_console(options, wait_for_prompt: true)
pid = Process.spawn(
"#{app_path}/bin/rails console #{options}",
in: @replica, out: @replica, err: @replica
)

assert_output "> ", @primary, 30
if wait_for_prompt
assert_output "> ", @primary, 30
end

pid
end

def test_sandbox
Expand All @@ -148,6 +152,17 @@ def test_sandbox
@primary.puts "quit"
end

def test_sandbox_when_sandbox_is_disabled
add_to_config <<-RUBY
config.disable_sandbox = true
RUBY

output = `#{app_path}/bin/rails console --sandbox`

assert_includes output, "sandbox mode is disabled"
assert_equal 1, $?.exitstatus
end

def test_environment_option_and_irb_option
spawn_console("-e test -- --verbose")

Expand Down
2 changes: 1 addition & 1 deletion railties/test/commands/console_test.rb
Expand Up @@ -129,7 +129,7 @@ def app
def build_app(console)
mocked_console = Class.new do
attr_accessor :sandbox
attr_reader :console
attr_reader :console, :disable_sandbox

def initialize(console)
@console = console
Expand Down