Skip to content

Commit

Permalink
Add patching for older rails versions
Browse files Browse the repository at this point in the history
  • Loading branch information
y9v committed Nov 22, 2024
1 parent 6a6d8b2 commit 353910f
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 124 deletions.
67 changes: 67 additions & 0 deletions lib/datadog/appsec/contrib/active_record/instrumentation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true

module Datadog
module AppSec
module Contrib
module ActiveRecord
# AppSec module that will be prepended to ActiveRecord adapter
module Instrumentation
module_function

def detect_sqli(sql, adapter_name)
scope = AppSec.active_scope
return unless scope

ephemeral_data = {
'server.db.statement' => sql,
'server.db.system' => adapter_name.downcase.gsub(/\d{1}\z/, '')
}

waf_timeout = Datadog.configuration.appsec.waf_timeout
result = scope.processor_context.run({}, ephemeral_data, waf_timeout)

if result.status == :match
Datadog::AppSec::Event.tag_and_keep!(scope, result)

event = {
waf_result: result,
trace: scope.trace,
span: scope.service_entry_span,
sql: sql,
actions: result.actions
}
scope.processor_context.events << event
end
end

# patch for all adapters in ActiveRecord >= 7.1
module InternalExecQueryAdapterPatch
def internal_exec_query(sql, *args, **rest)
Instrumentation.detect_sqli(sql, adapter_name)

super
end
end

# patch for postgres adapter in ActiveRecord < 7.1
module ExecuteAndClearAdapterPatch
def execute_and_clear(sql, *args, **rest)
Instrumentation.detect_sqli(sql, adapter_name)

super
end
end

# patch for mysql2 and sqlite3 adapters in ActiveRecord < 7.1
module ExecQueryAdapterPatch
def exec_query(sql, *args, **rest)
Instrumentation.detect_sqli(sql, adapter_name)

super
end
end
end
end
end
end
end
39 changes: 0 additions & 39 deletions lib/datadog/appsec/contrib/active_record/mysql2_adapter_patch.rb

This file was deleted.

20 changes: 14 additions & 6 deletions lib/datadog/appsec/contrib/active_record/patcher.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# frozen_string_literal: true

require_relative '../patcher'
require_relative 'sqlite3_adapter_patch'
require_relative 'postgresql_adapter_patch'
require_relative 'mysql2_adapter_patch'
require_relative 'instrumentation'

module Datadog
module AppSec
Expand All @@ -26,18 +24,28 @@ def target_version
def patch
ActiveSupport.on_load :active_record do
if defined? ::ActiveRecord::ConnectionAdapters::SQLite3Adapter
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(SQLite3AdapterPatch)
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(Patcher.prepended_class_name(:sqlite3))
end

if defined? ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapterPatch)
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(Patcher.prepended_class_name(:postgresql))
end

if defined? ::ActiveRecord::ConnectionAdapters::Mysql2Adapter
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(Mysql2AdapterPatch)
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(Patcher.prepended_class_name(:mysql2))
end
end
end

def prepended_class_name(adapter_name)
if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
Instrumentation::InternalExecQueryAdapterPatch
elsif adapter_name == :postgresql
Instrumentation::ExecuteAndClearAdapterPatch
else
Instrumentation::ExecQueryAdapterPatch
end
end
end
end
end
Expand Down

This file was deleted.

40 changes: 0 additions & 40 deletions lib/datadog/appsec/contrib/active_record/sqlite3_adapter_patch.rb

This file was deleted.

0 comments on commit 353910f

Please sign in to comment.