From 227b8148ebb7a3a237395e24a69438739370d9cd Mon Sep 17 00:00:00 2001 From: Caleb Xu Date: Wed, 10 Nov 2021 08:59:53 -0500 Subject: [PATCH] system_command: redact secrets in stdout/stderr We already redact secrets when printing the command-line invocation itself. Make sure that stdout/stderr doesn't leak secrets either. --- Library/Homebrew/system_command.rb | 4 ++-- Library/Homebrew/test/system_command_spec.rb | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index a5f30806ad..17ff585d10 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -53,10 +53,10 @@ class SystemCommand each_output_line do |type, line| case type when :stdout - $stdout << line if print_stdout? + $stdout << redact_secrets(line, @secrets) if print_stdout? @output << [:stdout, line] when :stderr - $stderr << line if print_stderr? + $stderr << redact_secrets(line, @secrets) if print_stderr? @output << [:stderr, line] end end diff --git a/Library/Homebrew/test/system_command_spec.rb b/Library/Homebrew/test/system_command_spec.rb index a73cd7acfc..3a3f7b2ce0 100644 --- a/Library/Homebrew/test/system_command_spec.rb +++ b/Library/Homebrew/test/system_command_spec.rb @@ -282,6 +282,30 @@ describe SystemCommand do end end + context "when running a process that prints secrets" do + it "does not leak the secrets" do + redacted_msg = /#{Regexp.escape("username:******")}/ + expect { + described_class.run! "echo", + args: %w[username:hunter2], + verbose: true, + print_stdout: true, + secrets: %w[hunter2] + }.to output(redacted_msg).to_stdout + end + + it "does not leak the secrets set by environment" do + redacted_msg = /#{Regexp.escape("username:******")}/ + expect { + ENV["PASSWORD"] = "hunter2" + described_class.run! "echo", + args: %w[username:hunter2], + print_stdout: true, + verbose: true + }.to output(redacted_msg).to_stdout + end + end + context "when a `SIGINT` handler is set in the parent process" do it "is not interrupted" do start_time = Time.now