Module: Contrast::Agent::Assess::Policy::TriggerValidation::SSRFValidator

Defined in:
lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb

Overview

Validator used to assert a SSRF finding is actually vulnerable before serializing that finding as a DTM to report to the TeamServer.

Constant Summary collapse

RULE_NAME =
'ssrf'
URL_PATTERN =

rubocop:disable Layout/LineLength

%r{(?<protocol>http|https|ftp|sftp|telnet|gopher|rtsp|rtsps|ssh|svn)://(?<host>[^/?]+)(?<path>/?[^?]*)(?<query_string>\?.*)?}i.cs__freeze
PATH_ONLY_PATCH_MARKER =

The Net::HTTP class validates host format on instantiation. Since our triggers for that class are on the instance, they already have this validation done for them. We do not need to apply the validation in this case.

'Assess:Trigger:Net::HTTP#'

Class Method Summary collapse

Class Method Details

.valid?(patcher, _object, _ret, args) ⇒ Boolean

A finding is valid for SSRF if the source of the trigger event is a valid URL in which the User controls a section prior to the querystring bitbucket.org/contrastsecurity/assess-specifications/src/master/rules/dataflow/server_side_request_forgery.md

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb', line 24

def self.valid? patcher, _object, _ret, args
  return true if patcher.id.to_s.start_with?(PATH_ONLY_PATCH_MARKER)

  url = args[0].to_s
  match = url.match(URL_PATTERN)
  return false unless match

  # It is dangerous for the user to control a section of the URL
  # between the start of the protocol and the beginning of the
  # querystring. If there is no path, then the entire URL is
  # dangerous for the User to control.
  start = match.begin(:protocol)
  finish = match.begin(:path)
  finish ||= url.length

  properties = Contrast::Agent::Assess::Tracker.properties(args[0])
  properties&.any_tags_between?(start, finish)
end