Information Disclosure via environment variable (DATABASE_URL) leakage in test environment
Description
The commit prevents an information disclosure vulnerability where the Rails test suite could leak the DATABASE_URL environment variable. Previously, tests were setting ENV['DATABASE_URL'] globally, which could propagate to child processes or logging, exposing sensitive database configuration. The fix removes the global ENV manipulation and scopes the DATABASE_URL value within a controlled block using with_env, and it also removes reliance on a global config/database.yml in those tests. This ensures that DATABASE_URL is not unintentionally exposed during test execution.
Proof of Concept
Proof of concept (Ruby) demonstrating leakage before vs after the fix:
BEFORE FIX (environment VARIABLE leaks to child processes):
# Global leak scenario (as in the pre-fix tests)
ENV['DATABASE_URL'] = 'sqlite3:/tmp/leaked_before.sqlite3'
puts "PARENT sees DATABASE_URL => #{ENV['DATABASE_URL']}"
# A child process started by the test (or rake task) would inherit the environment
# The child would also see the DATABASE_URL value
system("ruby -e 'puts \"CHILD sees DATABASE_URL=\" + ENV[\'DATABASE_URL\'].to_s'" )
AFTER FIX (scoped env, no leakage):
def with_env(key, value)
old = ENV[key]
ENV[key] = value
begin
yield
ensure
ENV[key] = old
end
end
with_env('DATABASE_URL','sqlite3:/tmp/leaked_after.sqlite3') do
# Inside this block, DATABASE_URL is set for the duration, but it is not visible to child processes launched outside
system("ruby -e 'puts \"CHILD sees DATABASE_URL=\" + (ENV[\'DATABASE_URL\'] || "").to_s'" )
end
# Outside the block, DATABASE_URL should be nil or unchanged
puts "PARENT after block sees DATABASE_URL => #{ENV['DATABASE_URL'].inspect }"
Commit Details
Author: zzak
Date: 2025-12-29 06:02 UTC
Message:
Don't leak DATABASE_URL to env in railties/dbs_schema_test
```
Failure:
ApplicationTests::RakeTests::RakeDbsSchemaTest#test_db:fixtures:load_with_database_url [/home/zzak/code/rails/tools/support/leak_checker.rb:22]:
Environment leak detected! DATABASE_URL
bin/test test/application/rake/dbs_schema_test.rb:259
Failure:
ApplicationTests::RakeTests::RakeDbsSchemaTest#test_db:migrate_and_db:migrate:status_with_database_url [/home/zzak/code/rails/tools/support/leak_checker.rb:22]:
Environment leak detected! DATABASE_URL
bin/test test/application/rake/dbs_schema_test.rb:44
Failure:
ApplicationTests::RakeTests::RakeDbsSchemaTest#test_db:schema:dump_with_database_url [/home/zzak/code/rails/tools/support/leak_checker.rb:22]:
Environment leak detected! DATABASE_URL
bin/test test/application/rake/dbs_schema_test.rb:134
```
Triage Assessment
Vulnerability Type: Information Disclosure
Confidence: HIGH
Reasoning:
Commit prevents leaking the DATABASE_URL environment variable during test execution by avoiding setting DATABASE_URL in the global ENV and instead scopes its value within a controlled block. This mitigates potential information disclosure of sensitive database configuration during test runs.
Verification Assessment
Vulnerability Type: Information Disclosure via environment variable (DATABASE_URL) leakage in test environment
Confidence: HIGH
Affected Versions: 8.1.x prior to this commit (pre-07f53df0a9b881ffc040fa57289b5e0316cc3d5d)
Code Diff
diff --git a/railties/test/application/rake/dbs_schema_test.rb b/railties/test/application/rake/dbs_schema_test.rb
index 6acd180a1d577..eb218b7e4c766 100644
--- a/railties/test/application/rake/dbs_schema_test.rb
+++ b/railties/test/application/rake/dbs_schema_test.rb
@@ -20,8 +20,7 @@ def database_url_db_name
"db/database_url_db.sqlite3"
end
- def set_database_url
- ENV["DATABASE_URL"] = "sqlite3:#{database_url_db_name}"
+ def delete_database_config!
# ensure it's using the DATABASE_URL
FileUtils.rm_rf("#{app_path}/config/database.yml")
end
@@ -42,8 +41,10 @@ def db_migrate_and_status(expected_database)
test "db:migrate and db:migrate:status with database_url" do
require "#{app_path}/config/environment"
- set_database_url
- db_migrate_and_status database_url_db_name
+ delete_database_config!
+ with_env DATABASE_URL: "sqlite3:#{database_url_db_name}" do
+ db_migrate_and_status database_url_db_name
+ end
end
test "db:migrate on new db loads schema" do
@@ -131,8 +132,10 @@ def db_schema_sql_dump
end
test "db:schema:dump with database_url" do
- set_database_url
- db_schema_dump
+ delete_database_config!
+ with_env DATABASE_URL: "sqlite3:#{database_url_db_name}" do
+ db_schema_dump
+ end
end
test "db:schema:dump with env as ruby" do
@@ -257,8 +260,10 @@ def db_fixtures_load(expected_database)
test "db:fixtures:load with database_url" do
require "#{app_path}/config/environment"
- set_database_url
- db_fixtures_load database_url_db_name
+ delete_database_config!
+ with_env DATABASE_URL: "sqlite3:#{database_url_db_name}" do
+ db_fixtures_load database_url_db_name
+ end
end
test "db:fixtures:load with namespaced fixture" do