class LogStash::Filters::Panfinder

Public Instance Methods

filter(event) click to toggle source
# File lib/logstash/filters/panfinder.rb, line 29
def filter(event)

  # this array will contain all numbers that satisfy the regex
  pans_maybe = []
  # this array will contain all pans which will be added to event
  pans_valid = []

  msg = event.get(@source)

  unless msg
    return
  end

  # match all elements from 14-19 numbers
  # https://baymard.com/checkout-usability/credit-card-patterns
  # https://regex101.com/r/nDQwVZ/1
  # following patterns match
  # 4-4-4-4
  # 4-4-4-4-3
  # 4-4-5
  # 4-5-6
  # 4-6-4
  # 4-6-5
  # and everythin with 13-19 digits without any special characters
  pans_maybe = msg.scan(/(\D|^)((\d{13,19})|(\d{4}\D{0,1}((\d{4}\D{0,1}\d{4}\D{0,1}\d{4}(\D{0,1}\d{3}|))|(\d{4}\D{0,1}\d{5})|(\d{5}\D{0,1}\d{6})|\d{6}\D{0,1}(\d{5}|\d{4}))))(\D|$)/)

  unless pans_maybe.empty?
    pans_maybe.each do |pan_number_match|
      pan_number = pan_number_match[1]
      # if luhn is enabled check the pan_number otherwise always add the pan_number
      if (not @luhn) || luhn_valid?(pan_number)
        pans_valid.append(pan_number)
        if @sanitize 
          msg = msg.gsub(pan_number, "###! sanitizeD PAN !###")
        end
      end
    end
    # if any pans where valid add them to the event
    unless pans_valid.empty?
      event.set("pans", pans_valid)
      if @sanitize
      event.set(@source, msg)
      end
    end
  end

  @logger.debug? && @logger.debug("PANs found: #{event.get("pans")}")

  # filter_matched should go in the last line of our successful code
  filter_matched(event)
end
register() click to toggle source
# File lib/logstash/filters/panfinder.rb, line 25
def register
end

Private Instance Methods

luhn_valid?(cc_number) click to toggle source

stackoverflow.com/questions/9188360/implementing-the-luhn-algorithm-in-ruby

# File lib/logstash/filters/panfinder.rb, line 83
def luhn_valid?(cc_number)
  number = cc_number.
    gsub(/\D/, ''). # remove non-digits
    reverse  # read from right to left

  sum, i = 0, 0

  number.each_char do |ch|
    n = ch.to_i

    # Step 1
    n *= 2 if i.odd?

    # Step 2
    n = 1 + (n - 10) if n >= 10

    sum += n
    i   += 1
  end

  # Step 3
  (sum % 10).zero?
end