Skip to content
Open
Changes from 1 commit
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
10 changes: 8 additions & 2 deletions lib/adyen/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

module Adyen
class Client
attr_accessor :ws_user, :ws_password, :api_key, :oauth_token, :client, :adapter
attr_accessor :ws_user, :ws_password, :api_key, :oauth_token, :client, :adapter, :logger
attr_reader :env, :connection_options, :adapter_options, :terminal_region

def initialize(ws_user: nil, ws_password: nil, api_key: nil, oauth_token: nil, env: :live, adapter: nil, mock_port: 3001,
live_url_prefix: nil, mock_service_url_base: nil, connection_options: nil, adapter_options: nil, terminal_region: nil)
logger: nil, live_url_prefix: nil, mock_service_url_base: nil, connection_options: nil, adapter_options: nil,
terminal_region: nil)
@ws_user = ws_user
@ws_password = ws_password
@api_key = api_key
Expand All @@ -32,6 +33,7 @@ def initialize(ws_user: nil, ws_password: nil, api_key: nil, oauth_token: nil, e
end
@mock_service_url_base = mock_service_url_base || "http://localhost:#{mock_port}"
@live_url_prefix = live_url_prefix
@logger = logger
if RUBY_VERSION >= '3.2'
# set default timeouts
@connection_options = connection_options || Faraday::ConnectionOptions.new(
Expand Down Expand Up @@ -162,6 +164,10 @@ def call_adyen_api(service, action, request_data, headers, version, _with_applic
# add library headers
faraday.headers['adyen-library-name'] = Adyen::NAME
faraday.headers['adyen-library-version'] = Adyen::VERSION

if @logger
faraday.response :logger, @logger, bodies: true
end
Comment on lines 168 to 171

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Enabling body logging with bodies: true introduces a critical security risk. It will log raw request and response bodies, which can contain sensitive PCI data like card numbers (number) and security codes (cvc). This data should never be stored in logs.

To mitigate this, the logger should filter out sensitive information before writing to the log. I suggest wrapping the provided logger in a decorator that filters the log messages before they are processed. This approach ensures that even if a plain logger is passed in, the library takes responsibility for filtering sensitive data, making it secure by default.

Here is a potential implementation using SimpleDelegator from Ruby's standard library. This wrapper will intercept log messages and apply a regex to redact sensitive fields, based on the fields already identified as sensitive in Adyen::AdyenError.

require 'delegate' unless defined?(SimpleDelegator)

if @logger
  # A logger wrapper that filters sensitive data from log messages.
  # This prevents accidental logging of card numbers, CVCs, etc.
  filtering_logger_class = Class.new(SimpleDelegator) do
    SENSITIVE_FIELDS = %w[
      number cvc expiryMonth expiryYear encryptedCardNumber
      encryptedExpiryMonth encryptedExpiryYear encryptedSecurityCode
    ].freeze
    # Regex to find sensitive fields in a JSON string and replace their values.
    FILTER_REGEX = /"(#{SENSITIVE_FIELDS.join('|')})":\s*".*?"/i.freeze

    def info(msg)
      __getobj__.info(filter(msg))
    end

    def debug(msg)
      __getobj__.debug(filter(msg))
    end

    private

    def filter(msg)
      msg.is_a?(String) ? msg.gsub(FILTER_REGEX, '"\1":"***"') : msg
    end
  end

  faraday.response :logger, filtering_logger_class.new(@logger), bodies: true
end

end
# if json string convert to hash
# needed to add applicationInfo
Expand Down