Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions app/repositories/app_event_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,20 @@ def app_audit_hash(request_attrs)
changes[censored] = Presenters::Censorship::PRIVATE_DATA_HIDDEN if changes.key?(censored)
end

v2_buildpack = changes.key?('buildpack')
v3_buildpack = changes.key?('lifecycle') && changes['lifecycle'].key?('data') && changes['lifecycle']['data'].key?('buildpack')

if v2_buildpack
buildpack_attr = changes['buildpack']
changes['buildpack'] = CloudController::UrlSecretObfuscator.obfuscate(buildpack_attr) if buildpack_attr
elsif v3_buildpack
buildpack_attr = changes['lifecycle']['data']['buildpack']
changes['lifecycle']['data']['buildpack'] = CloudController::UrlSecretObfuscator.obfuscate(buildpack_attr) if buildpack_attr
end
obfuscate_buildpack_urls(changes)
end
end

def obfuscate_buildpack_urls(changes)
# Top-level 'buildpack' is v2-only; remove with the v2 API.
changes['buildpack'] = CloudController::UrlSecretObfuscator.obfuscate(changes['buildpack']) if changes['buildpack']

lifecycle_data = changes['lifecycle']['data'] if changes.key?('lifecycle') && changes['lifecycle'].key?('data')
return unless lifecycle_data

lifecycle_data['buildpack'] = CloudController::UrlSecretObfuscator.obfuscate(lifecycle_data['buildpack']) if lifecycle_data['buildpack']
lifecycle_data['buildpacks'] = lifecycle_data['buildpacks'].map { |b| CloudController::UrlSecretObfuscator.obfuscate(b) } if lifecycle_data['buildpacks']
end
end
end
end
12 changes: 11 additions & 1 deletion app/repositories/service_event_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def record_service_instance_event(event, service_instance, params=nil)
end

def record_user_provided_service_instance_event(event, service_instance, params=nil)
metadata = { request: with_credentials_redacted(params) }
metadata = { request: with_url_credentials_obfuscated(with_credentials_redacted(params)) }

create_service_instance_event(
'user_provided_service_instance',
Expand Down Expand Up @@ -218,6 +218,16 @@ def with_credentials_redacted(request_data)
redact(request_data, for_key: 'credentials', with: Presenters::Censorship::REDACTED)
end

def with_url_credentials_obfuscated(request_data)
return request_data unless request_data.respond_to?(:[]=)

request_data.dup.tap do |data|
%w[syslog_drain_url route_service_url].each do |url_key|
data[url_key] = CloudController::UrlSecretObfuscator.obfuscate(data[url_key]) if data[url_key]
end
end
end

def redact(
params,
for_key:,
Expand Down
54 changes: 54 additions & 0 deletions spec/unit/repositories/app_event_repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,60 @@ module Repositories
end
end
end

context 'v3 with a buildpacks array' do
let(:app) { create(:app_model) }
let(:attrs) do
{
'lifecycle' => {
'type' => 'buildpack',
'data' => { 'buildpacks' => buildpacks }
}
}
end

context 'when the buildpacks are not nil' do
let(:buildpacks) do
[
'https://user:password@example.com/first.git',
'https://user:password@example.com/second.git'
]
end

it 'obfuscates each buildpack url' do
event = app_event_repository.record_app_update(app, space, user_audit_info, attrs).reload

expect(event.metadata.dig('request', 'lifecycle', 'data', 'buildpacks')).to eq(
[
'https://***:***@example.com/first.git',
'https://***:***@example.com/second.git'
]
)
end

it 'calls out to UrlSecretObfuscator once per buildpack' do
allow(CloudController::UrlSecretObfuscator).to receive(:obfuscate)
app_event_repository.record_app_update(app, space, user_audit_info, attrs)
expect(CloudController::UrlSecretObfuscator).to have_received(:obfuscate).exactly :twice
end
end

context 'when the buildpacks are nil' do
let(:buildpacks) { nil }

it 'does nothing' do
event = app_event_repository.record_app_update(app, space, user_audit_info, attrs).reload

expected_request = {
'lifecycle' => {
'type' => 'buildpack',
'data' => { 'buildpacks' => nil }
}
}
expect(event.metadata.fetch('request')).to eq expected_request
end
end
end
end

context 'with a v3 app' do
Expand Down
25 changes: 25 additions & 0 deletions spec/unit/repositories/service_event_repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,31 @@ module Repositories
})
end
end

context 'when the params contain urls with credentials' do
let(:params) do
{
'name' => 'my-upsi',
'space_guid' => instance.space.guid,
'syslog_drain_url' => 'https://drain-user:drain-password@drain.example.com/logs',
'route_service_url' => 'https://route-user:route-password@route.example.com/proxy'
}
end

it 'obfuscates the credentials in the syslog_drain_url' do
repository.record_user_provided_service_instance_event(:create, instance, params)
event = Event.first(type: 'audit.user_provided_service_instance.create')

expect(event.metadata.dig('request', 'syslog_drain_url')).to eq('https://***:***@drain.example.com/logs')
end

it 'obfuscates the credentials in the route_service_url' do
repository.record_user_provided_service_instance_event(:create, instance, params)
event = Event.first(type: 'audit.user_provided_service_instance.create')

expect(event.metadata.dig('request', 'route_service_url')).to eq('https://***:***@route.example.com/proxy')
end
end
end

describe '#record_service_key_event' do
Expand Down
Loading