From e0b091dbf0588d07763eea3e85dc9eb04e35d225 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Tue, 12 Mar 2024 17:57:51 +0100 Subject: [PATCH] Don't leak passwords to the log (bsc#1221194) --- .../y2network/connection_config/wireless.rb | 24 ++++++++++ test/y2network/config_test.rb | 48 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/lib/y2network/connection_config/wireless.rb b/src/lib/y2network/connection_config/wireless.rb index d8a240247..9117227b6 100644 --- a/src/lib/y2network/connection_config/wireless.rb +++ b/src/lib/y2network/connection_config/wireless.rb @@ -78,6 +78,7 @@ class Wireless < Base attr_accessor :client_key # @return [String] client private key password attr_accessor :client_key_password + alias :super_inspect :inspect def initialize super @@ -113,6 +114,29 @@ def mode=(wireless_mode) def keys? !(keys || []).compact.all?(&:empty?) end + + # Return a clone of this object with all sensitive fields (passwords etc.) obscured. + # Use this for log output to avoid leaking passwords. + def sanitized + san = self.dup + # san.sanitize! + san.wpa_psk = sanitized_field(san.wpa_psk) + san.wpa_password = sanitized_field(san.wpa_password) + san.client_key_password = sanitized_field(san.client_key_password) + + san + end + + # Sanitize one field if it is non-nil and non-empty. + def sanitized_field(orig) + return orig if orig.nil? || orig.empty? + + "".freeze + end + + def inspect + sanitized.super_inspect + end end end end diff --git a/test/y2network/config_test.rb b/test/y2network/config_test.rb index e8212f864..be68ff9b6 100644 --- a/test/y2network/config_test.rb +++ b/test/y2network/config_test.rb @@ -604,4 +604,52 @@ expect(new_config.connections).to eq(updated_connections) end end + + describe "#sanitized" do + let(:conn) do + Y2Network::ConnectionConfig::Wireless.new.tap do |c| + c.wpa_psk = "s3cr3t" + c.wpa_password = "s3cr3t" + c.client_key_password = "s3cr3t" + end + end + + it "obscures the wpa_psk" do + expect(conn.wpa_psk).to eql("s3cr3t") + expect(conn.sanitized.wpa_psk).to eql("") + end + + it "obscures the wpa_password" do + expect(conn.wpa_password).to eql("s3cr3t") + expect(conn.sanitized.wpa_password).to eql("") + end + + it "obscures the client_key_password" do + expect(conn.client_key_password).to eql("s3cr3t") + expect(conn.sanitized.client_key_password).to eql("") + end + + it "leaves the original untouched" do + expect(conn.sanitized.wpa_psk).to eql("") + expect(conn.wpa_psk).to eql("s3cr3t") + end + end + + describe "#inspect" do + let(:conn) do + Y2Network::ConnectionConfig::Wireless.new.tap do |c| + c.wpa_psk = "s3cr3t" + c.wpa_password = "s3cr3t" + c.client_key_password = "s3cr3t" + end + end + + it "does not leak a password" do + expect(conn.inspect).to_not match(/s3cr3t/) + end + + it "contains instead of passwords" do + expect(conn.inspect).to match(//) + end + end end