contrast-agent 3.13.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/contrast_service +1 -7
- data/ext/cs__assess_active_record_named/cs__active_record_named.c +8 -7
- data/ext/cs__assess_array/cs__assess_array.c +6 -5
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +5 -5
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +2 -1
- data/ext/cs__assess_hash/cs__assess_hash.c +18 -17
- data/ext/cs__assess_hash/cs__assess_hash.h +2 -1
- data/ext/cs__assess_kernel/cs__assess_kernel.c +7 -8
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +18 -16
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +1 -0
- data/ext/cs__assess_module/cs__assess_module.c +6 -6
- data/ext/cs__assess_regexp/cs__assess_regexp.c +4 -4
- data/ext/cs__assess_string/cs__assess_string.c +31 -16
- data/ext/cs__assess_string/cs__assess_string.h +6 -1
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +4 -2
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +2 -2
- data/ext/cs__common/cs__common.c +48 -39
- data/ext/cs__common/cs__common.h +16 -21
- data/ext/cs__contrast_patch/cs__contrast_patch.c +27 -25
- data/ext/cs__contrast_patch/cs__contrast_patch.h +5 -7
- data/ext/cs__protect_kernel/cs__protect_kernel.c +11 -12
- data/ext/cs__protect_kernel/cs__protect_kernel.h +2 -2
- data/lib/contrast-agent.rb +1 -1
- data/lib/contrast.rb +13 -23
- data/lib/contrast/agent.rb +39 -47
- data/lib/contrast/agent/assess.rb +12 -12
- data/lib/contrast/agent/assess/contrast_event.rb +151 -85
- data/lib/contrast/agent/assess/events/event_factory.rb +2 -2
- data/lib/contrast/agent/assess/events/source_event.rb +3 -3
- data/lib/contrast/agent/assess/finalizers/freeze.rb +15 -0
- data/lib/contrast/agent/assess/finalizers/hash.rb +97 -0
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +11 -4
- data/lib/contrast/agent/assess/policy/patcher.rb +6 -6
- data/lib/contrast/agent/assess/policy/policy.rb +9 -11
- data/lib/contrast/agent/assess/policy/policy_node.rb +17 -12
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +21 -5
- data/lib/contrast/agent/assess/policy/preshift.rb +13 -7
- data/lib/contrast/agent/assess/policy/propagation_method.rb +64 -44
- data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator.rb +18 -18
- data/lib/contrast/agent/assess/policy/propagator/append.rb +8 -5
- data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/center.rb +9 -5
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +6 -4
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +7 -4
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +4 -1
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +7 -9
- data/lib/contrast/agent/assess/policy/propagator/next.rb +7 -5
- data/lib/contrast/agent/assess/policy/propagator/prepend.rb +13 -5
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +8 -4
- data/lib/contrast/agent/assess/policy/propagator/replace.rb +5 -2
- data/lib/contrast/agent/assess/policy/propagator/reverse.rb +7 -5
- data/lib/contrast/agent/assess/policy/propagator/select.rb +13 -7
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +10 -9
- data/lib/contrast/agent/assess/policy/propagator/split.rb +27 -22
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +52 -35
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +11 -5
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +5 -5
- data/lib/contrast/agent/assess/policy/source_method.rb +90 -72
- data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +1 -1
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +16 -12
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +2 -2
- data/lib/contrast/agent/assess/policy/trigger_method.rb +81 -33
- data/lib/contrast/agent/assess/policy/trigger_node.rb +41 -46
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -1
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +2 -2
- data/lib/contrast/agent/assess/properties.rb +15 -5
- data/lib/contrast/agent/assess/property/evented.rb +7 -20
- data/lib/contrast/agent/assess/property/tagged.rb +13 -7
- data/lib/contrast/agent/assess/property/updated.rb +131 -0
- data/lib/contrast/agent/assess/rule.rb +2 -2
- data/lib/contrast/agent/assess/rule/base.rb +3 -4
- data/lib/contrast/agent/assess/rule/provider.rb +3 -3
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +58 -5
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +24 -9
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +85 -16
- data/lib/contrast/agent/assess/tag.rb +1 -1
- data/lib/contrast/agent/assess/tracker.rb +66 -0
- data/lib/contrast/agent/at_exit_hook.rb +6 -6
- data/lib/contrast/agent/class_reopener.rb +14 -11
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +1 -1
- data/lib/contrast/agent/deadzone/policy/policy.rb +2 -2
- data/lib/contrast/agent/disable_reaction.rb +1 -1
- data/lib/contrast/agent/exclusion_matcher.rb +1 -1
- data/lib/contrast/agent/inventory.rb +15 -0
- data/lib/contrast/agent/inventory/dependencies.rb +50 -0
- data/lib/contrast/agent/inventory/dependency_analysis.rb +37 -0
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +104 -0
- data/lib/contrast/agent/inventory/gemfile_digest_cache.rb +38 -0
- data/lib/contrast/agent/inventory/policy/datastores.rb +2 -2
- data/lib/contrast/agent/inventory/policy/policy.rb +3 -3
- data/lib/contrast/agent/inventory/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/middleware.rb +33 -34
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +9 -9
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +23 -22
- data/lib/contrast/agent/patching/policy/module_policy.rb +11 -11
- data/lib/contrast/agent/patching/policy/patch.rb +15 -15
- data/lib/contrast/agent/patching/policy/patcher.rb +43 -44
- data/lib/contrast/agent/patching/policy/policy.rb +23 -12
- data/lib/contrast/agent/patching/policy/policy_node.rb +1 -1
- data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +6 -8
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +7 -6
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +2 -2
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +4 -4
- data/lib/contrast/agent/protect/policy/policy.rb +8 -8
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +1 -1
- data/lib/contrast/agent/protect/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/protect/rule.rb +18 -18
- data/lib/contrast/agent/protect/rule/base.rb +4 -3
- data/lib/contrast/agent/protect/rule/base_service.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +5 -5
- data/lib/contrast/agent/protect/rule/deserialization.rb +1 -1
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +1 -1
- data/lib/contrast/agent/protect/rule/no_sqli.rb +1 -1
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -0
- data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -5
- data/lib/contrast/agent/protect/rule/sqli.rb +2 -2
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
- data/lib/contrast/agent/protect/rule/xss.rb +1 -1
- data/lib/contrast/agent/protect/rule/xxe.rb +3 -5
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +2 -2
- data/lib/contrast/agent/railtie.rb +1 -1
- data/lib/contrast/agent/reaction_processor.rb +2 -2
- data/lib/contrast/agent/request.rb +45 -43
- data/lib/contrast/agent/request_context.rb +10 -6
- data/lib/contrast/agent/request_handler.rb +1 -1
- data/lib/contrast/agent/response.rb +23 -12
- data/lib/contrast/agent/rewriter.rb +6 -9
- data/lib/contrast/agent/service_heartbeat.rb +2 -2
- data/lib/contrast/agent/static_analysis.rb +9 -9
- data/lib/contrast/agent/thread.rb +1 -1
- data/lib/contrast/agent/thread_watcher.rb +2 -2
- data/lib/contrast/agent/tracepoint_hook.rb +2 -2
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api.rb +4 -4
- data/lib/contrast/api/communication.rb +9 -9
- data/lib/contrast/api/communication/messaging_queue.rb +3 -6
- data/lib/contrast/api/communication/response_processor.rb +1 -1
- data/lib/contrast/api/communication/socket_client.rb +41 -6
- data/lib/contrast/api/communication/speedracer.rb +1 -1
- data/lib/contrast/api/communication/tcp_socket.rb +1 -1
- data/lib/contrast/api/communication/unix_socket.rb +1 -1
- data/lib/contrast/api/decorators.rb +17 -14
- data/lib/contrast/api/decorators/address.rb +20 -20
- data/lib/contrast/api/decorators/application_settings.rb +3 -2
- data/lib/contrast/api/decorators/application_update.rb +7 -8
- data/lib/contrast/api/decorators/http_request.rb +13 -12
- data/lib/contrast/api/decorators/input_analysis.rb +3 -2
- data/lib/contrast/api/decorators/library.rb +53 -0
- data/lib/contrast/api/decorators/library_usage_update.rb +30 -0
- data/lib/contrast/api/decorators/message.rb +4 -2
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +2 -1
- data/lib/contrast/api/decorators/route_coverage.rb +3 -2
- data/lib/contrast/api/decorators/server_features.rb +3 -2
- data/lib/contrast/api/decorators/trace_event.rb +28 -25
- data/lib/contrast/api/decorators/trace_event_object.rb +6 -5
- data/lib/contrast/api/decorators/trace_event_signature.rb +5 -4
- data/lib/contrast/api/decorators/trace_taint_range.rb +4 -3
- data/lib/contrast/api/decorators/user_input.rb +4 -4
- data/lib/contrast/common_agent_configuration.rb +2 -2
- data/lib/contrast/components/agent.rb +8 -7
- data/lib/contrast/components/app_context.rb +50 -39
- data/lib/contrast/components/config.rb +32 -50
- data/lib/contrast/components/contrast_service.rb +10 -10
- data/lib/contrast/components/interface.rb +39 -17
- data/lib/contrast/components/inventory.rb +6 -1
- data/lib/contrast/components/logger.rb +1 -1
- data/lib/contrast/components/scope.rb +3 -3
- data/lib/contrast/components/settings.rb +20 -23
- data/lib/contrast/config.rb +18 -18
- data/lib/contrast/config/application_configuration.rb +5 -2
- data/lib/contrast/config/base_configuration.rb +2 -2
- data/lib/contrast/config/inventory_configuration.rb +2 -2
- data/lib/contrast/config/protect_rule_configuration.rb +1 -1
- data/lib/contrast/config/service_configuration.rb +8 -0
- data/lib/contrast/configuration.rb +93 -52
- data/lib/contrast/extension/assess.rb +21 -22
- data/lib/contrast/extension/assess/array.rb +18 -11
- data/lib/contrast/extension/assess/erb.rb +11 -3
- data/lib/contrast/extension/assess/eval_trigger.rb +7 -7
- data/lib/contrast/extension/assess/exec_trigger.rb +2 -2
- data/lib/contrast/extension/assess/fiber.rb +14 -14
- data/lib/contrast/extension/assess/hash.rb +7 -6
- data/lib/contrast/extension/assess/kernel.rb +34 -28
- data/lib/contrast/extension/assess/marshal.rb +67 -0
- data/lib/contrast/extension/assess/regexp.rb +10 -9
- data/lib/contrast/extension/assess/string.rb +23 -23
- data/lib/contrast/extension/inventory.rb +4 -4
- data/lib/contrast/extension/kernel.rb +1 -1
- data/lib/contrast/extension/module.rb +1 -1
- data/lib/contrast/extension/protect.rb +3 -3
- data/lib/contrast/extension/protect/kernel.rb +4 -4
- data/lib/contrast/extension/protect/psych.rb +2 -2
- data/lib/contrast/framework/base_support.rb +1 -1
- data/lib/contrast/framework/manager.rb +10 -11
- data/lib/contrast/framework/rack/patch/session_cookie.rb +22 -28
- data/lib/contrast/framework/rack/patch/support.rb +1 -1
- data/lib/contrast/framework/rack/support.rb +2 -2
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +13 -13
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +6 -12
- data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +11 -11
- data/lib/contrast/framework/rails/patch/support.rb +4 -4
- data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +11 -11
- data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +12 -12
- data/lib/contrast/framework/rails/rewrite/active_record_named.rb +4 -4
- data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +12 -12
- data/lib/contrast/framework/rails/support.rb +67 -14
- data/lib/contrast/framework/sinatra/patch/base.rb +12 -12
- data/lib/contrast/framework/sinatra/patch/support.rb +1 -1
- data/lib/contrast/framework/sinatra/support.rb +6 -6
- data/lib/contrast/funchook/funchook.rb +1 -1
- data/lib/contrast/logger/application.rb +13 -5
- data/lib/contrast/logger/format.rb +22 -9
- data/lib/contrast/logger/log.rb +17 -10
- data/lib/contrast/logger/request.rb +30 -0
- data/lib/contrast/tasks/config.rb +1 -1
- data/lib/contrast/tasks/service.rb +2 -2
- data/lib/contrast/utils/assess/sampling_util.rb +2 -2
- data/lib/contrast/utils/assess/tracking_util.rb +49 -4
- data/lib/contrast/utils/class_util.rb +2 -2
- data/lib/contrast/utils/duck_utils.rb +0 -10
- data/lib/contrast/utils/env_configuration_item.rb +2 -1
- data/lib/contrast/utils/hash_digest.rb +2 -1
- data/lib/contrast/utils/heap_dump_util.rb +2 -2
- data/lib/contrast/utils/invalid_configuration_util.rb +21 -22
- data/lib/contrast/utils/inventory_util.rb +3 -10
- data/lib/contrast/utils/io_util.rb +1 -1
- data/lib/contrast/utils/os.rb +1 -1
- data/lib/contrast/utils/ruby_ast_rewriter.rb +1 -1
- data/lib/contrast/utils/sha256_builder.rb +2 -14
- data/lib/contrast/utils/stack_trace_utils.rb +2 -2
- data/lib/contrast/utils/string_utils.rb +11 -6
- data/resources/assess/policy.json +31 -22
- data/resources/deadzone/policy.json +5 -0
- data/ruby-agent.gemspec +21 -19
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +73 -30
- data/lib/contrast/agent/assess/insulator.rb +0 -49
- data/lib/contrast/agent/require_state.rb +0 -61
- data/lib/contrast/extension/assess/assess_extension.rb +0 -147
- data/lib/contrast/utils/boolean_util.rb +0 -30
- data/lib/contrast/utils/freeze_util.rb +0 -32
- data/lib/contrast/utils/gemfile_reader.rb +0 -193
@@ -1,22 +1,22 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
require 'contrast/agent/assess/policy/trigger_method'
|
5
|
+
require 'contrast/components/interface'
|
6
|
+
require 'contrast/extension/module'
|
6
7
|
|
7
8
|
module Contrast
|
8
9
|
module Agent
|
9
10
|
module Assess
|
10
11
|
module Rule
|
11
12
|
module Provider
|
12
|
-
# Hardcoded rules detect if any secret value has been written
|
13
|
-
# sourcecode of the application. To use this base
|
14
|
-
# implement
|
13
|
+
# Hardcoded rules detect if any secret value has been written
|
14
|
+
# directly into the sourcecode of the application. To use this base
|
15
|
+
# class, a provider must implement three methods:
|
15
16
|
# 1) name_passes? : does the constant name match a given value set
|
16
|
-
# 2)
|
17
|
-
#
|
18
|
-
# 3)
|
19
|
-
# 4) redacted_marker : the value to plug in for the obfuscated value
|
17
|
+
# 2) value_node_passes? : does the value of the constant match a
|
18
|
+
# given value set
|
19
|
+
# 3) redacted_marker : the value to plug in for the obfuscated value
|
20
20
|
module HardcodedValueRule
|
21
21
|
include Contrast::Components::Interface
|
22
22
|
access_component :analysis, :app_context, :logging
|
@@ -25,6 +25,7 @@ module Contrast
|
|
25
25
|
!ASSESS.enabled? || ASSESS.rule_disabled?(rule_id)
|
26
26
|
end
|
27
27
|
|
28
|
+
# TODO: RUBY-1014 - remove `#analyze`
|
28
29
|
COMMON_CONSTANTS = %i[
|
29
30
|
CONTRAST_ASSESS_POLICY_STATUS
|
30
31
|
VERSION
|
@@ -69,10 +70,31 @@ module Contrast
|
|
69
70
|
# if it looks like a placeholder / pointer to a config, skip it
|
70
71
|
next unless value_passes?(value)
|
71
72
|
|
72
|
-
|
73
|
+
build_finding(clazz, constant_string)
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
77
|
+
# Parse the file pertaining to the given TracePoint to walk its AST
|
78
|
+
# to determine if a Constant is hardcoded. For our purposes, this
|
79
|
+
# hard coding means directly set rather than as an interpolated
|
80
|
+
# String or through a method call.
|
81
|
+
#
|
82
|
+
# Note: This is a top layer check, we make no assertions about what
|
83
|
+
# the methods or interpolations do. Their presence, even if only
|
84
|
+
# calling a hardcoded thing, causes this check to not report.
|
85
|
+
#
|
86
|
+
# @param trace_point [TracePoint] the TracePoint event created on
|
87
|
+
# the :end of a Module being loaded
|
88
|
+
# @param ast [RubyVM::AbstractSyntaxTree::Node] the abstract syntax
|
89
|
+
# tree of the Module defined in the TracePoint end event
|
90
|
+
def parse trace_point, ast
|
91
|
+
return if disabled?
|
92
|
+
|
93
|
+
parse_ast(trace_point.self, ast)
|
94
|
+
rescue StandardError => e
|
95
|
+
logger.error('Unable to parse AST for hardcoded keys', e, module: trace_point.self)
|
96
|
+
end
|
97
|
+
|
76
98
|
# Constants can be variable or classes defined in the given
|
77
99
|
# class. We ONLY want the variables, which should be defined in
|
78
100
|
# the MACRO_CASE (upper case & underscore format)
|
@@ -90,7 +112,57 @@ module Contrast
|
|
90
112
|
|
91
113
|
private
|
92
114
|
|
93
|
-
|
115
|
+
# @param mod [Module] the module to which this AST pertains
|
116
|
+
# @param ast [RubyVM::AbstractSyntaxTree::Node, Object] a node
|
117
|
+
# within the AST, which may be a leaf, so any Object
|
118
|
+
def parse_ast mod, ast
|
119
|
+
return unless ast.cs__is_a?(RubyVM::AbstractSyntaxTree::Node)
|
120
|
+
return unless ast.cs__respond_to?(:children)
|
121
|
+
|
122
|
+
children = ast.children
|
123
|
+
return unless children.any?
|
124
|
+
|
125
|
+
ast.children.each do |child|
|
126
|
+
parse_ast(mod, child)
|
127
|
+
end
|
128
|
+
|
129
|
+
# https://www.rubydoc.info/gems/ruby-internal/Node/CDECL
|
130
|
+
return unless ast.type == :CDECL
|
131
|
+
|
132
|
+
# The CDECL Node has two children, the first being the Constant
|
133
|
+
# name as a symbol, the second as the value to assign to that
|
134
|
+
# constant
|
135
|
+
children = ast.children
|
136
|
+
name = children[0].to_s
|
137
|
+
# If that constant name doesn't pass our checks, move on.
|
138
|
+
return unless name_passes?(name)
|
139
|
+
|
140
|
+
value = children[1]
|
141
|
+
# The assignment node could be a direct value or a call of some
|
142
|
+
# sort. We leave it to each rule to properly handle these nodes.
|
143
|
+
return unless value_node_passes?(value)
|
144
|
+
|
145
|
+
build_finding(mod, name)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Constants can be set as frozen directly. We need to account for
|
149
|
+
# this change as it means the Node given to the :CDECL call will be
|
150
|
+
# a :CALL, not a constant.
|
151
|
+
#
|
152
|
+
# @param value_node [RubyVM::AbstractSyntaxTree::Node] the node to
|
153
|
+
# evaluate
|
154
|
+
# @return [Boolean] is this a freeze call or not
|
155
|
+
def freeze_call? value_node
|
156
|
+
return false unless value_node.type == :CALL
|
157
|
+
|
158
|
+
children = value_node.children
|
159
|
+
return false unless children
|
160
|
+
return false unless children.length >= 2
|
161
|
+
|
162
|
+
children[1] == :freeze
|
163
|
+
end
|
164
|
+
|
165
|
+
def build_finding clazz, constant_string
|
94
166
|
class_name = clazz.cs__name
|
95
167
|
|
96
168
|
finding = Contrast::Api::Dtm::Finding.new
|
@@ -104,13 +176,10 @@ module Contrast
|
|
104
176
|
hash = Contrast::Utils::HashDigest.generate_class_scanning_hash(finding)
|
105
177
|
finding.hash_code = Contrast::Utils::StringUtils.protobuf_safe_string(hash)
|
106
178
|
finding.preflight = Contrast::Utils::PreflightUtil.create_preflight(finding)
|
107
|
-
|
108
|
-
activity = Contrast::Api::Dtm::Activity.new
|
109
|
-
activity.findings << finding
|
110
|
-
|
111
|
-
Contrast::Agent.messaging_queue.send_event_eventually(activity)
|
179
|
+
Contrast::Agent::Assess::Policy::TriggerMethod.report_finding(finding)
|
112
180
|
rescue StandardError => e
|
113
181
|
logger.error('Unable to build a finding for Hardcoded Rule', e)
|
182
|
+
nil
|
114
183
|
end
|
115
184
|
end
|
116
185
|
end
|
@@ -14,7 +14,7 @@ module Contrast
|
|
14
14
|
|
15
15
|
# Initialize a new tag
|
16
16
|
#
|
17
|
-
# @param label [String] the
|
17
|
+
# @param label [String] the label of the tag
|
18
18
|
# @param length [Integer] the length of the string described with this
|
19
19
|
# tag
|
20
20
|
# @param start_idx [Integer] (0) the starting position in the string for
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/assess/finalizers/hash'
|
5
|
+
|
6
|
+
module Contrast
|
7
|
+
module Agent
|
8
|
+
module Assess
|
9
|
+
# How we track the Assess properties attached to objects
|
10
|
+
#
|
11
|
+
# Finalized objects should run through this class as the Finalizers
|
12
|
+
# have tightly coupled dependencies on each other.
|
13
|
+
class Tracker
|
14
|
+
PROPERTIES_HASH = Contrast::Agent::Assess::Finalizers::Hash.new
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def properties source
|
18
|
+
return unless trackable?(source)
|
19
|
+
|
20
|
+
PROPERTIES_HASH[source] ||= Contrast::Agent::Assess::Properties.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def trackable? source
|
24
|
+
PROPERTIES_HASH.trackable?(source)
|
25
|
+
end
|
26
|
+
|
27
|
+
def tracked? source
|
28
|
+
PROPERTIES_HASH.tracked?(source)
|
29
|
+
end
|
30
|
+
|
31
|
+
def pre_freeze source
|
32
|
+
PROPERTIES_HASH.pre_freeze(source)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Copy the properties from one object to the next, assuming the
|
36
|
+
# target does not already have its own properties.
|
37
|
+
#
|
38
|
+
# @param source [Object] the instance from which to copy properties
|
39
|
+
# @param target [Object] the instance to which to copy properties
|
40
|
+
def copy source, target
|
41
|
+
PROPERTIES_HASH[target] ||= properties(source).dup
|
42
|
+
end
|
43
|
+
|
44
|
+
# Duplicate the given object, returning the duplicate after copying
|
45
|
+
# the properties of the original and storing them as the properties
|
46
|
+
# of the duplicate.
|
47
|
+
#
|
48
|
+
# @param source [Object] the thing to duplicate
|
49
|
+
# @return [Object] the duplicate of the original, or the original if
|
50
|
+
# it does not respond to duplication
|
51
|
+
def duplicate source
|
52
|
+
return source unless source
|
53
|
+
|
54
|
+
duplicate = source.dup
|
55
|
+
PROPERTIES_HASH[duplicate] ||= PROPERTIES_HASH[source].dup
|
56
|
+
duplicate
|
57
|
+
rescue StandardError
|
58
|
+
source
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
require 'contrast/agent/assess/finalizers/freeze'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
require 'contrast/components/interface'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -11,11 +11,11 @@ module Contrast
|
|
11
11
|
access_component :logging
|
12
12
|
def self.exit_hook
|
13
13
|
@_exit_hook ||= begin
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
at_exit do
|
15
|
+
on_exit
|
16
|
+
end
|
17
|
+
true
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
21
|
# Actions to take when a process exits. Typically called from our
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
require 'ripper'
|
5
|
+
require 'contrast/extension/module'
|
6
|
+
require 'contrast/components/interface'
|
7
|
+
require 'contrast/logger/log'
|
8
8
|
|
9
9
|
# This method is left purposefully at the top level namespace. Moving it
|
10
10
|
# elsewhere will break functionality as it executes evaluations against the
|
@@ -37,7 +37,7 @@ module Contrast
|
|
37
37
|
# being phased out with support for those language versions.
|
38
38
|
class ClassReopener
|
39
39
|
include Contrast::Components::Interface
|
40
|
-
access_component :logging
|
40
|
+
access_component :logging, :scope
|
41
41
|
|
42
42
|
END_NEW_LINE = "end\n"
|
43
43
|
PROTECTED_WITH_NEW_LINE = "protected\n"
|
@@ -101,11 +101,13 @@ module Contrast
|
|
101
101
|
# Evaluate the patches that have been staged for this class, replacing
|
102
102
|
# the method definitions with those our rewrite.
|
103
103
|
def commit_patches
|
104
|
-
|
104
|
+
with_contrast_scope do
|
105
|
+
return unless staged_changes?
|
105
106
|
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
content = build_content
|
108
|
+
valid = Ripper.sexp(content)
|
109
|
+
unbound_eval(class_name, content) if !!valid && !class_name.empty?
|
110
|
+
end
|
109
111
|
end
|
110
112
|
|
111
113
|
# Find the sourcecode of the method at the given location and return it
|
@@ -164,9 +166,10 @@ module Contrast
|
|
164
166
|
next unless defined
|
165
167
|
|
166
168
|
current = current ? current.cs__const_get(chunk) : Module.cs__const_get(chunk)
|
167
|
-
|
169
|
+
case current
|
170
|
+
when Class
|
168
171
|
name_space << [chunk, Class]
|
169
|
-
|
172
|
+
when Module
|
170
173
|
name_space << [chunk, Module]
|
171
174
|
end
|
172
175
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
require 'contrast/agent/patching/policy/policy_node'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
require 'contrast/agent/deadzone/policy/deadzone_node'
|
5
|
+
require 'contrast/agent/patching/policy/policy'
|
6
6
|
|
7
7
|
module Contrast
|
8
8
|
module Agent
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
require 'contrast/components/interface'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
require 'contrast/components/interface'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
# Namespace used for inventory behavior
|
7
|
+
module Inventory
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'contrast/agent/inventory/dependencies'
|
13
|
+
require 'contrast/agent/inventory/gemfile_digest_cache'
|
14
|
+
require 'contrast/agent/inventory/dependency_usage_analysis'
|
15
|
+
require 'contrast/agent/inventory/dependency_analysis'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Contrast
|
5
|
+
module Agent
|
6
|
+
module Inventory
|
7
|
+
# this module is included in classes that need access to the applications dependencies
|
8
|
+
module Dependencies
|
9
|
+
CONTRAST_AGENT = 'contrast-agent'
|
10
|
+
|
11
|
+
# the #clone is necessary here, as a require in another thread could
|
12
|
+
# potentially result in adding a key to the loaded_specs hash during
|
13
|
+
# iteration. (as in RUBY-330)
|
14
|
+
# this takes care of filtering out contrast-only dependencies
|
15
|
+
def loaded_specs
|
16
|
+
specs = Gem.loaded_specs.clone
|
17
|
+
specs.delete_if { |name, _v| contrast?(name) }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def contrast_gems
|
23
|
+
@_contrast_gems ||= find_contrast_gems
|
24
|
+
end
|
25
|
+
|
26
|
+
def contrast? name
|
27
|
+
contrast_gems.include?(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Go through all dependents, given as a pair from the DependencyList: `dependency`
|
31
|
+
# is the dependency itself, filled with all its specs. `dependents` is the array of reverse
|
32
|
+
# dependencies for the aforementioned dependency. If the dependency is also in contrast_dep_set,
|
33
|
+
# then contrast depends on it. If its array of dependents is 1, then contrast is the
|
34
|
+
# only dependency in that list. Since only contrast depends on it, we should ignore it.
|
35
|
+
def find_contrast_gems
|
36
|
+
ignore = Set.new([CONTRAST_AGENT])
|
37
|
+
contrast_specs = Gem::DependencyList.from_specs.specs.find do |dependency|
|
38
|
+
dependency.name == CONTRAST_AGENT
|
39
|
+
end
|
40
|
+
contrast_dep_set = contrast_specs.dependencies.map(&:name).to_set
|
41
|
+
|
42
|
+
Gem::DependencyList.from_specs.spec_predecessors.each_pair do |dependency, dependents|
|
43
|
+
ignore.add(dependency.name) if contrast_dep_set.include?(dependency.name) && dependents.length == 1
|
44
|
+
end
|
45
|
+
ignore
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'contrast/agent/inventory/dependencies'
|
5
|
+
require 'contrast/components/interface'
|
6
|
+
require 'contrast/utils/object_share'
|
7
|
+
|
8
|
+
module Contrast
|
9
|
+
module Agent
|
10
|
+
module Inventory
|
11
|
+
# Used to collect dependencies of the application for reporting
|
12
|
+
class DependencyAnalysis
|
13
|
+
include Singleton
|
14
|
+
include Contrast::Agent::Inventory::Dependencies
|
15
|
+
include Contrast::Components::Interface
|
16
|
+
|
17
|
+
access_component :analysis
|
18
|
+
|
19
|
+
# Report the dependencies of this application
|
20
|
+
#
|
21
|
+
# @return [Array<Contrast::Api::Dtm::Library>] protobuf form of the
|
22
|
+
# Gem::Specification that have been loaded for this application.
|
23
|
+
def library_pb_list
|
24
|
+
return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless INVENTORY.enabled?
|
25
|
+
return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless INVENTORY.analyze_libraries?
|
26
|
+
|
27
|
+
loaded_specs.each_with_object([]) do |(_name, spec), reported_lib_list|
|
28
|
+
next unless spec
|
29
|
+
next unless (digest = Contrast::Utils::Sha256Builder.instance.build_from_spec(spec))
|
30
|
+
|
31
|
+
reported_lib_list << Contrast::Api::Dtm::Library.build(digest, spec)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|