Skip to content

Commit

Permalink
Redact short and known private tokens
Browse files Browse the repository at this point in the history
Prior this commit very short private tokens (< 4 chars) triggered:
ArgumentError: negative argument

Also, if private token was a term which was part of the inspected string
only the first occurrence was redacted.
  • Loading branch information
splattael committed Jul 4, 2024
1 parent 0766442 commit 1024223
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lib/gitlab/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class Client < API
# @return [String]
def inspect
inspected = super
inspected.sub! @private_token, only_show_last_four_chars(@private_token) if @private_token
inspected = redact_private_token(inspected, @private_token) if @private_token
inspected
end

Expand All @@ -91,7 +91,14 @@ def url_encode(url)

private

def redact_private_token(inspected, private_token)
redacted = only_show_last_four_chars(private_token)
inspected.sub %(@private_token="#{private_token}"), %(@private_token="#{redacted}")
end

def only_show_last_four_chars(token)
return '****' if token.size <= 4

"#{'*' * (token.size - 4)}#{token[-4..]}"
end
end
Expand Down
42 changes: 42 additions & 0 deletions spec/gitlab/client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Client do
subject(:client) { described_class.new(options) }

describe '#inspect' do
subject { client.inspect }

context 'without private token' do
let(:options) { { private_token: nil } }

it { is_expected.not_to include('@private_token=') }
end

context 'with a some lengthy private token' do
let(:options) { { private_token: 'some token' } }

it { is_expected.to include('@private_token="******oken"') }
end

context 'with a known private token' do
let(:options) { { private_token: 'endpoint' } }

it { is_expected.to include('@private_token="****oint"') }
it { is_expected.to include('@endpoint=') }
end

context 'with empty private token' do
let(:options) { { private_token: '' } }

it { is_expected.to include('@private_token="****"') }
end

context 'with short private token' do
let(:options) { { private_token: 'abcd' } }

it { is_expected.to include('@private_token="****"') }
end
end
end

0 comments on commit 1024223

Please sign in to comment.