Module: Datadog::AppSec::Contrib::Sinatra::RoutePatch

Defined in:
lib/datadog/appsec/contrib/sinatra/patcher.rb

Overview

Hook into Base#route_eval, which path params are returned by pattern.params in process_route, then merged with normal params, so we get both

Instance Method Summary collapse

Instance Method Details

#process_routeObject



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/datadog/appsec/contrib/sinatra/patcher.rb', line 84

def process_route(*)
  env = @request.env

  context = env[Datadog::AppSec::Ext::SCOPE_KEY]

  return super unless context

  # process_route is called repeatedly until a route is found.
  # Until then, params has no route params.
  # Capture normal params.
  base_params = params

  super do |*args|
    # This block is called only once the route is found.
    # At this point params has both route params and normal params.
    route_params = params.each.with_object({}) { |(k, v), h| h[k] = v unless base_params.key?(k) }

    gateway_request = Gateway::Request.new(env)
    gateway_route_params = Gateway::RouteParams.new(route_params)

    _, request_response = Instrumentation.gateway.push(
      'sinatra.request.routed',
      [gateway_request, gateway_route_params]
    )

    if request_response
      blocked_event = request_response.find { |action, _options| action == :block }
      if blocked_event
        self.response = AppSec::Response.negotiate(env, blocked_event.last[:actions]).to_sinatra_response

        # interrupt request and return response to dispatch! for consistency
        throw(Datadog::AppSec::Contrib::Sinatra::Ext::ROUTE_INTERRUPT, response)
      end
    end

    yield(*args)
  end
end