Skip to content

Commit 03ac203

Browse files
authored
Redact password from query_options (#1334)
Redact password from query_options to avoid leaking credentials in exceptions via #inspect. Minor refactor to make RuboCop happy about client.rb complexity. Closes #1049
1 parent f0c5d11 commit 03ac203

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

.rubocop_todo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Metrics/BlockNesting:
4545
# Offense count: 1
4646
# Configuration parameters: CountComments, CountAsOne.
4747
Metrics/ClassLength:
48-
Max: 135
48+
Max: 141
4949

5050
# Offense count: 3
5151
# Configuration parameters: IgnoredMethods.

lib/mysql2/client.rb

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,7 @@ def initialize(opts = {})
7171
# SSL verify is a connection flag rather than a mysql_ssl_set option
7272
flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify]
7373

74-
if %i[user pass hostname dbname db sock].any? { |k| @query_options.key?(k) }
75-
warn "============= WARNING FROM mysql2 ============="
76-
warn "The options :user, :pass, :hostname, :dbname, :db, and :sock are deprecated and will be removed at some point in the future."
77-
warn "Instead, please use :username, :password, :host, :port, :database, :socket, :flags for the options."
78-
warn "============= END WARNING FROM mysql2 ========="
79-
end
74+
check_and_clean_query_options
8075

8176
user = opts[:username] || opts[:user]
8277
pass = opts[:password] || opts[:pass]
@@ -165,6 +160,21 @@ def info
165160
self.class.info
166161
end
167162

163+
private
164+
165+
def check_and_clean_query_options
166+
if %i[user pass hostname dbname db sock].any? { |k| @query_options.key?(k) }
167+
warn "============= WARNING FROM mysql2 ============="
168+
warn "The options :user, :pass, :hostname, :dbname, :db, and :sock are deprecated and will be removed at some point in the future."
169+
warn "Instead, please use :username, :password, :host, :port, :database, :socket, :flags for the options."
170+
warn "============= END WARNING FROM mysql2 ========="
171+
end
172+
173+
# avoid logging sensitive data via #inspect
174+
@query_options.delete(:password)
175+
@query_options.delete(:pass)
176+
end
177+
168178
class << self
169179
private
170180

spec/mysql2/client_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,4 +1195,22 @@ def run_gc
11951195
it "should respond to #encoding" do
11961196
expect(@client).to respond_to(:encoding)
11971197
end
1198+
1199+
it "should not include the password in the output of #inspect" do
1200+
client_class = Class.new(Mysql2::Client) do
1201+
def connect(*args); end
1202+
end
1203+
1204+
client = client_class.new(password: "secretsecret")
1205+
1206+
expect(client.inspect).not_to include("password")
1207+
expect(client.inspect).not_to include("secretsecret")
1208+
1209+
expect do
1210+
client = client_class.new(pass: "secretsecret")
1211+
end.to output(/WARNING/).to_stderr
1212+
1213+
expect(client.inspect).not_to include("pass")
1214+
expect(client.inspect).not_to include("secretsecret")
1215+
end
11981216
end

spec/mysql2/statement_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def stmt_count
320320
result = @client.prepare("SELECT 1 UNION SELECT 2").execute(stream: true, cache_rows: false)
321321
expect do
322322
result.each {}
323-
result.each {} # rubocop:disable Style/CombinableLoops
323+
result.each {}
324324
end.to raise_exception(Mysql2::Error)
325325
end
326326
end

0 commit comments

Comments
 (0)