Module: Datadog::AppSec::Contrib::RestClient::RequestSSRFDetectionPatch
- Defined in:
- lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb
Overview
Module that adds SSRF detection to RestClient::Request#execute
Constant Summary collapse
- REDIRECT_STATUS_CODES =
(300..399).freeze
Instance Method Summary collapse
Instance Method Details
#execute(&block) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb', line 17 def execute(&block) context = AppSec.active_context return super unless context && AppSec.rasp_enabled? headers = normalize_request_headers # @type var ephemeral_data: ::Datadog::AppSec::Context::input_data ephemeral_data = { 'server.io.net.url' => url, 'server.io.net.request.method' => method.to_s.upcase, 'server.io.net.request.headers' => headers } is_redirect = context.state[:downstream_redirect_url] == url if is_redirect context.state.delete(:downstream_redirect_url) sample_body = true else sample_body = mark_body_sampling!(context) end if !is_redirect && sample_body body = parse_body(payload.to_s, content_type: headers['content-type']) ephemeral_data['server.io.net.request.body'] = body if body end timeout = Datadog.configuration.appsec.waf_timeout result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, timeout, phase: Ext::RASP_REQUEST_PHASE) handle(result, context: context) if result.match? # NOTE: RestClient raises exceptions for non-2xx responses. For POST/PUT/PATCH # requests with 3xx redirects, RestClient raises instead of auto-following. # We rescue to process the response before re-raising. begin response = super rescue ::RestClient::Exception => e response = e.response process_response(response, sample_body: sample_body) if response raise end process_response(response, sample_body: sample_body) response end |
#process_response(response, sample_body:) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb', line 62 def process_response(response, sample_body:) context = AppSec.active_context return unless context headers = normalize_response_headers(response) # @type var ephemeral_data: ::Datadog::AppSec::Context::input_data ephemeral_data = { 'server.io.net.response.status' => response.code.to_s, 'server.io.net.response.headers' => headers } is_redirect = REDIRECT_STATUS_CODES.cover?(response.code.to_i) && headers.key?('location') context.state[:downstream_redirect_url] = URI.join(url, headers['location']).to_s if is_redirect && sample_body if sample_body && !is_redirect body = parse_body(response.body, content_type: headers['content-type']) ephemeral_data['server.io.net.response.body'] = body if body end timeout = Datadog.configuration.appsec.waf_timeout result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, timeout, phase: Ext::RASP_RESPONSE_PHASE) handle(result, context: context) if result.match? end |