Class: Datadog::AppSec::WAF::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/appsec/waf/context.rb

Overview

Constant Summary collapse

RESULT_CODE =
{
  ddwaf_ok: :ok,
  ddwaf_match: :match,
  ddwaf_err_internal: :err_internal,
  ddwaf_err_invalid_object: :err_invalid_object,
  ddwaf_err_invalid_argument: :err_invalid_argument
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(context_ptr) ⇒ Context

Returns a new instance of Context.



17
18
19
# File 'lib/datadog/appsec/waf/context.rb', line 17

def initialize(context_ptr)
  @context_ptr = context_ptr
end

Instance Method Details

#finalize!Object

Destroys the WAF context and sets the pointer to nil.

The instance becomes unusable after this method is called.



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/datadog/appsec/waf/context.rb', line 24

def finalize!
  context_ptr_to_destroy = @context_ptr
  @context_ptr = nil

  retained.each do |retained_obj|
    next unless retained_obj.is_a?(LibDDWAF::Object)

    LibDDWAF.ddwaf_object_free(retained_obj)
  end

  retained.clear
  LibDDWAF.ddwaf_context_destroy(context_ptr_to_destroy)
end

#run(persistent_data, ephemeral_data, timeout = LibDDWAF::DDWAF_RUN_TIMEOUT) ⇒ Result

Runs the WAF context with the given persistent and ephemeral data.

Returns:

  • (Result)

    the result of the WAF run

Raises:

  • (ConversionError)

    if the conversion of persistent or ephemeral data fails

  • (LibDDWAFError)

    if libddwaf could not create the result object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/datadog/appsec/waf/context.rb', line 44

def run(persistent_data, ephemeral_data, timeout = LibDDWAF::DDWAF_RUN_TIMEOUT)
  ensure_pointer_presence!

  persistent_data_obj = Converter.ruby_to_object(
    persistent_data,
    max_container_size: LibDDWAF::DDWAF_MAX_CONTAINER_SIZE,
    max_container_depth: LibDDWAF::DDWAF_MAX_CONTAINER_DEPTH,
    max_string_length: LibDDWAF::DDWAF_MAX_STRING_LENGTH,
    coerce: false
  )
  if persistent_data_obj.null?
    raise ConversionError, "Could not convert persistent data: #{persistent_data.inspect}"
  end

  # retain C objects in memory for subsequent calls to run
  retain(persistent_data_obj)

  ephemeral_data_obj = Converter.ruby_to_object(
    ephemeral_data,
    max_container_size: LibDDWAF::DDWAF_MAX_CONTAINER_SIZE,
    max_container_depth: LibDDWAF::DDWAF_MAX_CONTAINER_DEPTH,
    max_string_length: LibDDWAF::DDWAF_MAX_STRING_LENGTH,
    coerce: false
  )
  if ephemeral_data_obj.null?
    raise ConversionError, "Could not convert ephemeral data: #{ephemeral_data.inspect}"
  end

  result_obj = LibDDWAF::Result.new
  raise LibDDWAFError, "Could not create result object" if result_obj.null?

  code = LibDDWAF.ddwaf_run(@context_ptr, persistent_data_obj, ephemeral_data_obj, result_obj, timeout)

  result = Result.new(
    RESULT_CODE[code],
    Converter.object_to_ruby(result_obj[:events]),
    result_obj[:total_runtime],
    result_obj[:timeout],
    Converter.object_to_ruby(result_obj[:actions]),
    Converter.object_to_ruby(result_obj[:derivatives])
  )

  if persistent_data_obj.truncated? || ephemeral_data_obj.truncated?
    result.mark_input_truncated!
  end

  result
ensure
  LibDDWAF.ddwaf_result_free(result_obj) if result_obj
  LibDDWAF.ddwaf_object_free(ephemeral_data_obj) if ephemeral_data_obj
end