Module: Contrast::Agent::Assess::Policy::TriggerMethod
- Extended by:
- Components::Logger::InstanceMethods, Utils::Assess::EventLimitUtils, Utils::Assess::TriggerMethodUtils
- Included in:
- Patching::Policy::Patch
- Defined in:
- lib/contrast/agent/assess/policy/trigger_method.rb
Overview
A trigger method is one which can perform a dangerous action, as described by the Contrast::Agent::Assess::Policy::TriggerNode class. Each such method will call to this module just after invocation in order to determine if the call was done safely. In those cases where it was not, a Finding report is issued to TeamServer.
Constant Summary collapse
- NON_REQUEST_RULES =
Rules that always exists outside of Request Context
[ 'hardcoded-password', # Contrast::Agent::Assess::Rule::Provider::HardcodedPassword.NAME, 'hardcoded-key' # Contrast::Agent::Assess::Rule::Provider::HardcodedKey.NAME ].cs__freeze
Class Method Summary collapse
- .apply_eval_trigger(trigger_node, source, object, ret, *args) ⇒ Object
-
.apply_trigger_rule(trigger_node, object, ret, args) ⇒ Object
This is called from within our woven proc.
-
.build_finding(trigger_node, source, object, ret, *args) ⇒ Contrast::Agent::Reporting::Finding?
This converts the source of the finding, and the events leading up to it into a Finding.
-
.report_finding(finding) ⇒ Object
Given a finding, append it to an activity message and send it to the TeamServer for processing.
Methods included from Components::Logger::InstanceMethods
Methods included from Utils::Assess::TriggerMethodUtils
apply_dataflow_rule, apply_regexp_rule, apply_trigger, find_event_request, find_request, reportable?
Methods included from Utils::Assess::EventLimitUtils
event_limit?, event_limit_for_rule?, increment_event_count
Class Method Details
.apply_eval_trigger(trigger_node, source, object, ret, *args) ⇒ Object
73 74 75 |
# File 'lib/contrast/agent/assess/policy/trigger_method.rb', line 73 def apply_eval_trigger trigger_node, source, object, ret, *args apply_trigger(trigger_node, source, object, ret, *args) end |
.apply_trigger_rule(trigger_node, object, ret, args) ⇒ Object
This is called from within our woven proc. It will be called as if it were inline in the Rack application.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/contrast/agent/assess/policy/trigger_method.rb', line 49 def apply_trigger_rule trigger_node, object, ret, args return if trigger_node.nil? return if event_limit_for_rule?(trigger_node.rule_id) context = Contrast::Agent::REQUEST_TRACKER.current # return if there is no context and the flag is set to default => false # we need to have request if the flag is default # else proceed, if the flag is true we don't need to check for context we # go as currently. # When outside of a request, only track when the feature is enabled return unless context || Contrast::ASSESS.non_request_tracking? || NON_REQUEST_RULES.include?(trigger_node.rule_id) if trigger_node.sources&.any? trigger_node.sources.each do |marker| source = determine_source(marker, object, ret, args) apply_trigger(trigger_node, source, object, ret, *args) end else apply_trigger(trigger_node, nil, object, ret, *args) end end |
.build_finding(trigger_node, source, object, ret, *args) ⇒ Contrast::Agent::Reporting::Finding?
This converts the source of the finding, and the events leading up to it into a Finding
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/contrast/agent/assess/policy/trigger_method.rb', line 86 def build_finding trigger_node, source, object, ret, *args content_type = Contrast::Agent::REQUEST_TRACKER.current&.response&.content_type if content_type.nil? && trigger_node.collectable? Contrast::Agent::FINDINGS.collect_finding(trigger_node, source, object, ret, *args) return end return unless Contrast::Agent::Assess::Policy::TriggerValidation.valid?(trigger_node, object, ret, args) request = find_request(source) return unless reportable?(request&.env) return if excluded_by_url_and_rule?(trigger_node.rule_id) finding = Contrast::Agent::Reporting::Finding.new(trigger_node.rule_id) finding.attach_data(trigger_node, source, object, ret, request, *args) return if excluded_by_input_and_rule?(finding, trigger_node.rule_id) finding.hash_code = Contrast::Utils::HashDigest.generate_event_hash(finding, source, request) check_for_stored_xss(finding) finding rescue StandardError => e logger.error('Unable to build a finding', e, rule: trigger_node.rule_id, node_id: trigger_node.id) nil end |
.report_finding(finding) ⇒ Object
Given a finding, append it to an activity message and send it to the TeamServer for processing. If an activity message does not exist, b/c we’re invoked outside of a request context, build an activity and immediately report it with the finding.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/contrast/agent/assess/policy/trigger_method.rb', line 115 def report_finding finding return unless finding preflight = Contrast::Agent::Reporting::BuildPreflight.generate(finding) return unless preflight preflight_data = preflight.[0].data return if Contrast::Agent::REQUEST_TRACKER.current&.reported_findings&.include?(preflight_data) Contrast::Agent::Reporting::ReportingStorage[preflight.[0].data] = finding if Contrast::Agent::REQUEST_TRACKER.current Contrast::Agent::REQUEST_TRACKER.current.reported_findings << preflight_data end Contrast::Agent.reporter&.send_event(preflight) end |