Skip to content

Commit 218117c

Browse files
committed
fix: redact auth headers case-insensitively (+ Proxy-Authorization)
HTTP header names are case-insensitive and HashWithIndifferentAccess does not normalize case, so a consumer-set 'authorization' (non-canonical case) leaked through Error#to_h. Match Authorization/Proxy-Authorization case-insensitively. HELDENPMI-132
1 parent 1a8189f commit 218117c

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

lib/nxt_http_client/error.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Error < StandardError
66
].freeze
77

88
REDACTED = '[REDACTED]'
9+
SENSITIVE_HEADERS = %w[Authorization Proxy-Authorization].freeze
910

1011
def self.from_response(response, message = nil)
1112
error_class_for(response).new(response, message)
@@ -132,9 +133,13 @@ def redact_credentials(options)
132133
end
133134

134135
def redact_authorization(headers)
135-
return headers unless headers.respond_to?(:key?) && headers.key?('Authorization')
136+
return headers unless headers.respond_to?(:keys)
136137

137-
headers.merge('Authorization' => REDACTED)
138+
# HTTP header names are case-insensitive, and HashWithIndifferentAccess does not normalize case.
139+
sensitive = headers.keys.select { |key| SENSITIVE_HEADERS.any? { |name| key.to_s.casecmp?(name) } }
140+
return headers if sensitive.empty?
141+
142+
headers.merge(sensitive.index_with { REDACTED })
138143
end
139144

140145
public

spec/error_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ def to_h_for(&setup)
163163

164164
expect(hash[:request_options]['userpwd']).to eq('[REDACTED]')
165165
end
166+
167+
it 'redacts a non-canonically-cased authorization header' do
168+
hash = to_h_for { |config| config.request_options = { headers: { 'authorization' => 'Bearer secret' } } }
169+
170+
expect(hash[:request_headers]['authorization']).to eq('[REDACTED]')
171+
end
166172
end
167173

168174
describe '.from_response' do

0 commit comments

Comments
 (0)