class QueryHandler
Public Class Methods
new(opts)
click to toggle source
# File lib/prevoty/query_handler.rb, line 10 def initialize(opts) @base = opts[:api_base] ||= 'https://api.prevoty.com' @client = ::Prevoty::Client.new(opts[:api_key], @base) @policy_key = opts[:policy_key] ||= '' @mode = opts[:mode] ||= 'monitor' @log_verbosity = opts[:log_verbosity] ||= 'incident' @reporting_milliseconds = opts[:reporting_milliseconds] ||= 10000 @reporting_count = opts[:reporting_count] ||= 50 @db_vendor = opts[:db_vendor] ||= '' @db_version = opts[:db_version] ||= '' @db_name = opts[:db_name] ||= '' @violation_mode = opts[:violation_mode] ||= 'block' @failure_mode = opts[:failure_mode] ||= 'continue' if @mode === 'monitor' @monitor = ::Prevoty::QueryMonitor.new(@client, opts) end end
Public Instance Methods
handle(name, start, finish, id, payload)
click to toggle source
# File lib/prevoty/query_handler.rb, line 29 def handle(name, start, finish, id, payload) # ActiveRecord does some wonky stuff on startup that causes a query to be # executed that doesn't seem to pass through the rack middleware so the # request_storage key doesn't exist. It's unclear if there are other # situations that also cause this but because of it we need to use try here # to ensure there are no nil pointer exceptions if Thread.current[:request_storage].try(:[], :skip_processing) return end unless payload[:name] =~ /SQL|Load/ return end case @mode when 'monitor' package = {vendor: @db_vendor, database: @db_name, version: @db_version, query: payload[:sql]} @monitor.process(package) when 'protect' begin resp = nil ActiveSupport::Notifications.instrument('prevoty:query:protect') do |resp_payload| resp = resp_payload[:response] = @client.analyze_query(payload[:sql], @policy_key) end # always log because we're either set to all or incident if resp.processed and not resp.compliant ::Prevoty::LOGGER << build_result(@mode, payload[:sql], resp).to_json + "\n" raise ::Prevoty::QueryViolation.new if @violation_mode === 'block' elsif resp.processed and resp.compliant # all good, only log if log verbosity is all if @log_verbosity === 'all' ::Prevoty::LOGGER << build_result(@mode, payload[:sql], resp).to_json + "\n" end elsif not resp.processed and not resp.compliant # query failure if @log_verbosity === 'all' ::Prevoty::LOGGER << build_result(@mode, payload[:sql], resp).to_json + "\n" end ActiveSupport::Notifications.instrument('prevoty:query:failure', response: resp) raise ::Prevoty::QueryFailure.new end rescue ::Prevoty::QueryViolation => e # need to catch and rethrow to catch other exceptions raise e rescue ::Prevoty::QueryFailure => e # need to catch and rethrow to catch other exceptions raise e rescue Exception => e Rails.logger.error e.message raise e if @failure_mode === 'block' end end end