contrast-agent 3.8.5 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/cs__assess_array/cs__assess_array.c +1 -1
- data/ext/cs__assess_module/cs__assess_module.c +0 -1
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +34 -0
- data/ext/cs__assess_yield_track/cs__assess_yield_track.h +12 -0
- data/ext/{cs__scope → cs__assess_yield_track}/extconf.rb +0 -0
- data/ext/cs__common/cs__common.c +6 -6
- data/ext/cs__common/cs__common.h +3 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.c +142 -119
- data/ext/cs__contrast_patch/cs__contrast_patch.h +3 -0
- data/funchook/autom4te.cache/requests +48 -48
- data/funchook/config.log +2 -2
- data/lib/contrast/agent.rb +15 -5
- data/lib/contrast/agent/assess.rb +0 -1
- data/lib/contrast/agent/assess/contrast_event.rb +9 -8
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +68 -18
- data/lib/contrast/agent/assess/policy/policy.rb +0 -14
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
- data/lib/contrast/agent/assess/policy/preshift.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagation_method.rb +4 -2
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator/split.rb +166 -1
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +1 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +199 -140
- data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +30 -0
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +36 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +238 -153
- data/lib/contrast/agent/assess/policy/trigger_node.rb +54 -9
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +13 -0
- data/lib/contrast/agent/assess/properties.rb +29 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +35 -31
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +1 -1
- data/lib/contrast/agent/class_reopener.rb +98 -55
- data/lib/contrast/agent/feature_state.rb +1 -1
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/logger_manager.rb +2 -2
- data/lib/contrast/agent/middleware.rb +1 -3
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +40 -4
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +33 -8
- data/lib/contrast/agent/patching/policy/method_policy.rb +20 -7
- data/lib/contrast/agent/patching/policy/patch.rb +54 -23
- data/lib/contrast/agent/patching/policy/patch_status.rb +0 -2
- data/lib/contrast/agent/patching/policy/patcher.rb +10 -11
- data/lib/contrast/agent/patching/policy/policy.rb +4 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +14 -1
- data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -1
- data/lib/contrast/agent/protect/policy/policy.rb +6 -6
- data/lib/contrast/agent/protect/rule/base.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +3 -25
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/railtie.rb +11 -5
- data/lib/contrast/agent/request.rb +1 -19
- data/lib/contrast/agent/request_context.rb +1 -1
- data/lib/contrast/agent/rewriter.rb +4 -3
- data/lib/contrast/agent/scope.rb +116 -19
- data/lib/contrast/agent/service_heartbeat.rb +5 -2
- data/lib/contrast/agent/settings_state.rb +12 -8
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api.rb +1 -0
- data/lib/contrast/api/speedracer.rb +2 -2
- data/lib/contrast/components/agent.rb +26 -7
- data/lib/contrast/components/app_context.rb +8 -45
- data/lib/contrast/components/contrast_service.rb +3 -4
- data/lib/contrast/components/interface.rb +1 -1
- data/lib/contrast/components/scope.rb +56 -26
- data/lib/contrast/config/ruby_configuration.rb +8 -3
- data/lib/contrast/delegators.rb +9 -0
- data/lib/contrast/delegators/application_update.rb +32 -0
- data/lib/contrast/extensions/framework/rack/cookie.rb +24 -0
- data/lib/contrast/extensions/framework/rack/request.rb +24 -0
- data/lib/contrast/extensions/framework/rack/response.rb +23 -0
- data/lib/contrast/extensions/framework/rails/action_controller_railties_helper_inherited.rb +20 -0
- data/lib/contrast/extensions/framework/rails/active_record.rb +26 -0
- data/lib/contrast/extensions/framework/rails/active_record_named.rb +53 -0
- data/lib/contrast/extensions/framework/rails/active_record_time_zone_inherited.rb +21 -0
- data/lib/contrast/extensions/framework/rails/buffer.rb +28 -0
- data/lib/contrast/extensions/framework/rails/configuration.rb +27 -0
- data/lib/contrast/extensions/framework/sinatra/base.rb +59 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess.rb +12 -11
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/array.rb +4 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/assess_extension.rb +0 -2
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/basic_object.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/erb.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/exec_trigger.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/fiber.rb +3 -4
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/hash.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/kernel.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/module.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/regexp.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/string.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/tilt_template_trigger.rb +0 -0
- data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +40 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/delegator.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/eval_trigger.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory/datastores.rb +1 -1
- data/lib/contrast/extensions/ruby_core/module.rb +17 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_command_injection_rule.rb +8 -6
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_deserialization_rule.rb +7 -5
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_no_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_path_traversal_rule.rb +31 -27
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_xxe_rule.rb +9 -7
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/kernel.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/psych.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/thread.rb +0 -0
- data/lib/contrast/framework/base_support.rb +63 -0
- data/lib/contrast/framework/manager.rb +109 -0
- data/lib/contrast/framework/platform_version.rb +21 -0
- data/lib/contrast/framework/rails_support.rb +88 -0
- data/lib/contrast/framework/sinatra_application_helper.rb +49 -0
- data/lib/contrast/framework/sinatra_support.rb +94 -0
- data/lib/contrast/framework/view_technologies_descriptor.rb +20 -0
- data/lib/contrast/utils/assess/tracking_util.rb +2 -4
- data/lib/contrast/utils/class_util.rb +92 -37
- data/lib/contrast/utils/duck_utils.rb +59 -39
- data/lib/contrast/utils/environment_util.rb +5 -75
- data/lib/contrast/utils/freeze_util.rb +3 -7
- data/lib/contrast/utils/invalid_configuration_util.rb +5 -5
- data/lib/contrast/utils/job_servers_running.rb +39 -0
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -2
- data/lib/contrast/utils/service_response_util.rb +0 -6
- data/lib/contrast/utils/sinatra_helper.rb +6 -0
- data/lib/contrast/utils/stack_trace_utils.rb +1 -1
- data/resources/assess/policy.json +74 -23
- data/resources/inventory/policy.json +1 -1
- data/resources/protect/policy.json +11 -9
- data/resources/rubocops/object/frozen_cop.rb +1 -1
- data/ruby-agent.gemspec +2 -0
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +94 -57
- data/ext/cs__scope/cs__scope.c +0 -96
- data/ext/cs__scope/cs__scope.h +0 -33
- data/lib/contrast/agent/assess/class_reverter.rb +0 -82
- data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +0 -28
- data/lib/contrast/core_extensions/module.rb +0 -42
- data/lib/contrast/core_extensions/object.rb +0 -27
- data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +0 -48
- data/lib/contrast/rails_extensions/assess/active_record.rb +0 -32
- data/lib/contrast/rails_extensions/assess/active_record_named.rb +0 -61
- data/lib/contrast/rails_extensions/assess/configuration.rb +0 -26
- data/lib/contrast/rails_extensions/buffer.rb +0 -30
- data/lib/contrast/rails_extensions/rack.rb +0 -45
- data/lib/contrast/sinatra_extensions/assess/cookie.rb +0 -26
- data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +0 -59
- data/lib/contrast/utils/operating_environment.rb +0 -38
- data/lib/contrast/utils/path_util.rb +0 -151
- data/lib/contrast/utils/scope_util.rb +0 -99
@@ -14,64 +14,64 @@
|
|
14
14
|
'configure.ac'
|
15
15
|
],
|
16
16
|
{
|
17
|
-
'
|
18
|
-
'
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'
|
22
|
-
'AC_CONFIG_SUBDIRS' => 1,
|
23
|
-
'AM_NLS' => 1,
|
24
|
-
'AC_FC_SRCEXT' => 1,
|
25
|
-
'LT_SUPPORTED_TAG' => 1,
|
26
|
-
'AC_LIBSOURCE' => 1,
|
17
|
+
'AC_CONFIG_LINKS' => 1,
|
18
|
+
'AC_INIT' => 1,
|
19
|
+
'AM_MAKEFILE_INCLUDE' => 1,
|
20
|
+
'_AM_SUBST_NOTMAKE' => 1,
|
21
|
+
'AM_SILENT_RULES' => 1,
|
27
22
|
'AC_CONFIG_LIBOBJ_DIR' => 1,
|
28
|
-
'
|
23
|
+
'AC_DEFINE_TRACE_LITERAL' => 1,
|
24
|
+
'AM_PROG_F77_C_O' => 1,
|
29
25
|
'_LT_AC_TAGCONFIG' => 1,
|
26
|
+
'AC_FC_SRCEXT' => 1,
|
30
27
|
'_AM_COND_ELSE' => 1,
|
31
|
-
'
|
32
|
-
'
|
33
|
-
'
|
34
|
-
'
|
35
|
-
'
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'AM_PROG_MOC' => 1,
|
39
|
-
'AH_OUTPUT' => 1,
|
40
|
-
'AC_FC_PP_SRCEXT' => 1,
|
41
|
-
'AM_MAINTAINER_MODE' => 1,
|
42
|
-
'AM_PROG_CC_C_O' => 1,
|
43
|
-
'AC_CONFIG_LINKS' => 1,
|
44
|
-
'_m4_warn' => 1,
|
45
|
-
'AM_PROG_CXX_C_O' => 1,
|
46
|
-
'LT_INIT' => 1,
|
47
|
-
'AM_PATH_GUILE' => 1,
|
48
|
-
'LT_CONFIG_LTDL_DIR' => 1,
|
28
|
+
'm4_pattern_forbid' => 1,
|
29
|
+
'_AM_MAKEFILE_INCLUDE' => 1,
|
30
|
+
'AM_INIT_AUTOMAKE' => 1,
|
31
|
+
'm4_pattern_allow' => 1,
|
32
|
+
'include' => 1,
|
33
|
+
'AM_ENABLE_MULTILIB' => 1,
|
34
|
+
'AC_CANONICAL_TARGET' => 1,
|
49
35
|
'AC_FC_FREEFORM' => 1,
|
50
|
-
'AM_XGETTEXT_OPTION' => 1,
|
51
36
|
'AM_AUTOMAKE_VERSION' => 1,
|
52
|
-
'
|
37
|
+
'AM_XGETTEXT_OPTION' => 1,
|
38
|
+
'AM_PATH_GUILE' => 1,
|
39
|
+
'm4_sinclude' => 1,
|
53
40
|
'AC_CANONICAL_SYSTEM' => 1,
|
54
|
-
'
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
58
|
-
'
|
41
|
+
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
|
42
|
+
'AC_SUBST' => 1,
|
43
|
+
'LT_INIT' => 1,
|
44
|
+
'AM_NLS' => 1,
|
45
|
+
'_AM_COND_IF' => 1,
|
46
|
+
'AM_GNU_GETTEXT' => 1,
|
59
47
|
'AC_FC_PP_DEFINE' => 1,
|
60
|
-
'
|
61
|
-
'
|
48
|
+
'AM_PROG_LIBTOOL' => 1,
|
49
|
+
'm4_include' => 1,
|
50
|
+
'AM_PROG_AR' => 1,
|
51
|
+
'AM_PROG_FC_C_O' => 1,
|
52
|
+
'AM_PROG_CXX_C_O' => 1,
|
53
|
+
'AM_PROG_CC_C_O' => 1,
|
54
|
+
'AC_CONFIG_SUBDIRS' => 1,
|
55
|
+
'AM_MAINTAINER_MODE' => 1,
|
56
|
+
'AC_PROG_LIBTOOL' => 1,
|
62
57
|
'AC_CANONICAL_BUILD' => 1,
|
63
|
-
'
|
58
|
+
'AM_PROG_MOC' => 1,
|
59
|
+
'AC_CANONICAL_HOST' => 1,
|
60
|
+
'LT_SUPPORTED_TAG' => 1,
|
61
|
+
'AC_CONFIG_HEADERS' => 1,
|
62
|
+
'LT_CONFIG_LTDL_DIR' => 1,
|
63
|
+
'AC_REQUIRE_AUX_FILE' => 1,
|
64
64
|
'AM_CONDITIONAL' => 1,
|
65
|
-
'
|
66
|
-
'
|
67
|
-
'
|
65
|
+
'AC_CONFIG_AUX_DIR' => 1,
|
66
|
+
'_AM_COND_ENDIF' => 1,
|
67
|
+
'_m4_warn' => 1,
|
68
|
+
'AC_LIBSOURCE' => 1,
|
69
|
+
'AC_CONFIG_FILES' => 1,
|
70
|
+
'AH_OUTPUT' => 1,
|
71
|
+
'AC_FC_PP_SRCEXT' => 1,
|
72
|
+
'AM_POT_TOOLS' => 1,
|
68
73
|
'AC_SUBST_TRACE' => 1,
|
69
|
-
'
|
70
|
-
'AC_CANONICAL_HOST' => 1,
|
71
|
-
'm4_pattern_allow' => 1,
|
72
|
-
'AM_GNU_GETTEXT' => 1,
|
73
|
-
'AC_CANONICAL_TARGET' => 1,
|
74
|
-
'AM_ENABLE_MULTILIB' => 1
|
74
|
+
'sinclude' => 1
|
75
75
|
}
|
76
76
|
], 'Autom4te::Request' )
|
77
77
|
);
|
data/funchook/config.log
CHANGED
@@ -10,7 +10,7 @@ generated by GNU Autoconf 2.69. Invocation command line was
|
|
10
10
|
## Platform. ##
|
11
11
|
## --------- ##
|
12
12
|
|
13
|
-
hostname =
|
13
|
+
hostname = b8012d0f-931d-4789-bc7a-4c5ac30dcded-9cnnv
|
14
14
|
uname -m = x86_64
|
15
15
|
uname -r = 4.19.95-flatcar
|
16
16
|
uname -s = Linux
|
@@ -326,7 +326,7 @@ generated by GNU Autoconf 2.69. Invocation command line was
|
|
326
326
|
CONFIG_COMMANDS =
|
327
327
|
$ ./config.status
|
328
328
|
|
329
|
-
on
|
329
|
+
on b8012d0f-931d-4789-bc7a-4c5ac30dcded-9cnnv
|
330
330
|
|
331
331
|
config.status:822: creating Makefile
|
332
332
|
config.status:822: creating src/Makefile
|
data/lib/contrast/agent.rb
CHANGED
@@ -6,9 +6,8 @@ cs__scoped_require 'English'
|
|
6
6
|
# This must precede other Contrast C extensions
|
7
7
|
cs__scoped_require 'cs__common/cs__common'
|
8
8
|
|
9
|
-
cs__scoped_require 'contrast/
|
10
|
-
cs__scoped_require 'contrast/
|
11
|
-
cs__scoped_require 'contrast/core_extensions/module'
|
9
|
+
cs__scoped_require 'contrast/extensions/ruby_core/delegator'
|
10
|
+
cs__scoped_require 'contrast/extensions/ruby_core/module'
|
12
11
|
|
13
12
|
cs__scoped_require 'contrast/utils/object_share'
|
14
13
|
cs__scoped_require 'contrast/utils/boolean_util'
|
@@ -32,16 +31,22 @@ cs__scoped_require 'contrast/api'
|
|
32
31
|
|
33
32
|
cs__scoped_require 'contrast/utils/resource_loader'
|
34
33
|
cs__scoped_require 'contrast/utils/duck_utils'
|
35
|
-
cs__scoped_require 'contrast/utils/scope_util'
|
36
34
|
cs__scoped_require 'contrast/agent/tracepoint_hook'
|
37
35
|
cs__scoped_require 'contrast/agent/at_exit_hook'
|
38
36
|
|
37
|
+
# Framework support
|
38
|
+
cs__scoped_require 'contrast/framework/manager'
|
39
|
+
|
39
40
|
module Contrast
|
40
41
|
# Top namespace of the Agent section. Holds tracking contexts that will be
|
41
42
|
# accessed throughout the Agent.
|
42
43
|
module Agent
|
43
44
|
# build a map for tracking the context of the current request
|
44
45
|
REQUEST_TRACKER = Contrast::Utils::ThreadTracker.new
|
46
|
+
|
47
|
+
def self.framework_manager
|
48
|
+
@_framework_manager ||= Contrast::Framework::Manager.new
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
@@ -67,7 +72,12 @@ cs__scoped_require 'contrast/agent/assess'
|
|
67
72
|
# These happen regardless of analysis mode, & should be lightweight.
|
68
73
|
cs__scoped_require 'contrast/utils/rack_assess_session_cookie'
|
69
74
|
cs__scoped_require 'contrast/utils/rails_assess_configuration'
|
70
|
-
|
75
|
+
# Also: should document the necessity of patching this ASAP.
|
76
|
+
# In Rails, session configuration occurs extremely early & only once.
|
77
|
+
# If we defer our patching of the rails session configuration too long
|
78
|
+
# (i.e., where we normally patch) we will miss the configuration
|
79
|
+
# and will never be able to report session misconfiguration rules.
|
80
|
+
cs__scoped_require 'contrast/extensions/framework/rails/configuration' if defined?(Rails)
|
71
81
|
|
72
82
|
# protect rules
|
73
83
|
cs__scoped_require 'contrast/agent/protect/rule'
|
@@ -8,7 +8,6 @@ module Contrast
|
|
8
8
|
# class under this namespace should be required here, providing a single
|
9
9
|
# point of require for this functionality.
|
10
10
|
module Assess
|
11
|
-
cs__scoped_require 'contrast/agent/assess/class_reverter'
|
12
11
|
cs__scoped_require 'contrast/agent/module_data'
|
13
12
|
cs__scoped_require 'contrast/agent/rewriter'
|
14
13
|
cs__scoped_require 'contrast/agent/assess/policy/preshift'
|
@@ -1,6 +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
|
+
cs__scoped_require 'contrast/utils/class_util'
|
4
5
|
cs__scoped_require 'contrast/utils/prevent_serialization'
|
5
6
|
|
6
7
|
module Contrast
|
@@ -23,7 +24,7 @@ module Contrast
|
|
23
24
|
rep << if arg.is_a?(Hash)
|
24
25
|
safe_arg_hash_representation(arg)
|
25
26
|
else
|
26
|
-
arg
|
27
|
+
Contrast::Utils::ClassUtil.to_contrast_string(arg)
|
27
28
|
end
|
28
29
|
end
|
29
30
|
rep
|
@@ -32,7 +33,7 @@ module Contrast
|
|
32
33
|
def safe_arg_hash_representation hash
|
33
34
|
# since this is the named hash for arguments, only the value is
|
34
35
|
# suspect here
|
35
|
-
hash.transform_values(
|
36
|
+
hash.transform_values { |v| Contrast::Utils::ClassUtil.to_contrast_string(v) }
|
36
37
|
end
|
37
38
|
|
38
39
|
# if given an object that can be duped, duplicate it. otherwise just
|
@@ -110,26 +111,26 @@ module Contrast
|
|
110
111
|
# being called. We'll save all the information, but nothing will be
|
111
112
|
# marked up, as nothing need be tracked
|
112
113
|
when nil
|
113
|
-
@object = object
|
114
|
+
@object = Contrast::Utils::ClassUtil.to_contrast_string(object)
|
114
115
|
@args = cs__class.safe_args_representation(args)
|
115
|
-
@ret = ret
|
116
|
+
@ret = Contrast::Utils::ClassUtil.to_contrast_string(ret)
|
116
117
|
# If the target is O, then we dup the O and safely represent the rest
|
117
118
|
when Contrast::Utils::ObjectShare::OBJECT_KEY
|
118
119
|
@object = cs__class.safe_dup(tagged)
|
119
120
|
@args = cs__class.safe_args_representation(args)
|
120
|
-
@ret = ret
|
121
|
+
@ret = Contrast::Utils::ClassUtil.to_contrast_string(ret)
|
121
122
|
# If the target is R, then we dup the R and safely represent the rest
|
122
123
|
when Contrast::Utils::ObjectShare::RETURN_KEY
|
123
|
-
@object = object
|
124
|
+
@object = Contrast::Utils::ClassUtil.to_contrast_string(object)
|
124
125
|
@args = cs__class.safe_args_representation(args)
|
125
126
|
@ret = cs__class.safe_dup(tagged)
|
126
127
|
# If the target is P*, then we need to dup things a differently. We
|
127
128
|
# need to find the true target inside so that we can mark it up
|
128
129
|
# later, but the other args should be represented as their safe form.
|
129
130
|
else
|
130
|
-
@object = object
|
131
|
+
@object = Contrast::Utils::ClassUtil.to_contrast_string(object)
|
131
132
|
@args = cs__class.safe_args_representation(args)
|
132
|
-
@ret = ret
|
133
|
+
@ret = Contrast::Utils::ClassUtil.to_contrast_string(ret)
|
133
134
|
save_target_arg(target, tagged)
|
134
135
|
end
|
135
136
|
end
|
@@ -15,26 +15,33 @@ module Contrast
|
|
15
15
|
READ_TABLE = 'readTable'
|
16
16
|
READ_COLUMN = 'readColumn'
|
17
17
|
class << self
|
18
|
+
# Given a Class representing a table in a Database and a map of
|
19
|
+
# methods representing columns, generate sources for each method
|
20
|
+
# such that calls to that method will result in a Source Event.
|
21
|
+
#
|
22
|
+
# @param klass [Class] the Class to taint
|
23
|
+
# @param tainted_columns [Hash<String, Contrast::Agent::Assess::Properties>]
|
24
|
+
# the name of the method to taint, mapped to the properties it
|
25
|
+
# should apply
|
18
26
|
def create_sources klass, tainted_columns
|
27
|
+
class_name = klass.cs__name
|
19
28
|
instance_methods = klass.instance_methods
|
20
29
|
instance_methods.concat(klass.private_instance_methods)
|
21
|
-
tainted_columns.each_pair do |field,
|
22
|
-
|
23
|
-
Contrast::Agent::Assess::Policy::Policy.instance.add_node(dynamic_source_node, :dynamic_source)
|
30
|
+
tainted_columns.each_pair do |field, properties|
|
31
|
+
next unless properties
|
24
32
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
method_policy.instance_method = true
|
29
|
-
method_policy.source_node = dynamic_source_node
|
30
|
-
Contrast::Agent::Patching::Policy::Patcher.patch_method(klass, instance_methods, method_policy)
|
33
|
+
method_name = field.to_sym
|
34
|
+
# Move on if we already know about this Dynamic Source
|
35
|
+
next if Contrast::Agent::Assess::Policy::Policy.instance.find_source_node(class_name, method_name, true)
|
31
36
|
|
37
|
+
dynamic_source_node = create_source_node(class_name, method_name, Set.new(properties.tag_keys))
|
38
|
+
Contrast::Agent::Assess::Policy::Policy.instance.add_node(dynamic_source_node, :dynamic_source)
|
39
|
+
method_policy = build_source_policy(method_name, dynamic_source_node)
|
40
|
+
Contrast::Agent::Patching::Policy::Patcher.patch_method(klass, instance_methods, method_policy)
|
32
41
|
current_context = Contrast::Agent::REQUEST_TRACKER.current
|
42
|
+
next unless current_context
|
33
43
|
|
34
|
-
|
35
|
-
|
36
|
-
dynamic_source = create_dynamic_source(current_context, dynamic_source_node, field, events)
|
37
|
-
|
44
|
+
dynamic_source = create_dynamic_source(current_context, dynamic_source_node, field, properties)
|
38
45
|
node_id = Contrast::Utils::StringUtils.force_utf8(dynamic_source_node.id)
|
39
46
|
current_context.activity.dynamic_sources[node_id] = dynamic_source
|
40
47
|
end
|
@@ -42,25 +49,68 @@ module Contrast
|
|
42
49
|
|
43
50
|
private
|
44
51
|
|
45
|
-
|
52
|
+
# Given a class and method, create a SourceNode for them that will
|
53
|
+
# add the given tags as well as properties required to construct a
|
54
|
+
# finding with a TAINTED_DATABASE source
|
55
|
+
#
|
56
|
+
# @param class_name [String] the name of the Class to patch
|
57
|
+
# @param method_name [Symbol] the name of the Method to patch
|
58
|
+
# @param tags [Set<String>] the tags this event should apply
|
59
|
+
# @return [Contrast::Agent::Assess::Policy::SourceNode]
|
60
|
+
def create_source_node class_name, method_name, tags
|
46
61
|
node = Contrast::Agent::Assess::Policy::SourceNode.new
|
47
|
-
node.class_name =
|
62
|
+
node.class_name = class_name
|
48
63
|
node.instance_method = true
|
49
|
-
node.method_name =
|
64
|
+
node.method_name = method_name
|
50
65
|
node.method_visibility = :public
|
51
66
|
node.target_string = Contrast::Utils::ObjectShare::RETURN_KEY
|
52
67
|
node.type = DB_SOURCE_TYPE
|
68
|
+
node.tags = tags
|
69
|
+
node.tags << 'DATABASE_WRITE'
|
53
70
|
node.add_property('dynamic_source_id', node.id)
|
71
|
+
node.add_property('dynamic_source_name', "#{ class_name }.#{ method_name }")
|
72
|
+
node.add_property(READ_TABLE, class_name)
|
73
|
+
node.add_property(READ_COLUMN, method_name)
|
74
|
+
node.add_property(WRITE_QUERY_TIME, Contrast::Utils::Timer.now_ms)
|
75
|
+
url = Contrast::Agent::REQUEST_TRACKER.current&.request&.normalized_uri
|
76
|
+
node.add_property(WRITE_QUERY_URL, url)
|
54
77
|
node
|
55
78
|
end
|
56
79
|
|
57
|
-
|
80
|
+
# @param method_name [Symbol] the name of the Method to which this
|
81
|
+
# method applies
|
82
|
+
# @param dynamic_source_node [Contrast::Api::Dtm::DynamicSource]
|
83
|
+
# the SourceNode that applies to this method
|
84
|
+
# @return [Contrast::Agent::Patching::Policy::MethodPolicy] the
|
85
|
+
# policy to apply to the given method
|
86
|
+
def build_source_policy method_name, dynamic_source_node
|
87
|
+
method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.new
|
88
|
+
method_policy.method_visibility = :public
|
89
|
+
method_policy.instance_method = true
|
90
|
+
method_policy.method_name = method_name
|
91
|
+
method_policy.source_node = dynamic_source_node
|
92
|
+
method_policy
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param current_context [Contrast::Agent::RequestContext] the
|
96
|
+
# context of the request in which this source is to be created.
|
97
|
+
# @param source_node [Contrast::Agent::Assess::Policy::SourceNode]
|
98
|
+
# the SourceNode that applies to this method
|
99
|
+
# @param field [String] the name of the method to which this source
|
100
|
+
# applies
|
101
|
+
# @param properties [Contrast::Agent::Assess::Properties] the
|
102
|
+
# properties which this source should relate to the data tracked
|
103
|
+
# as a result of this Source Method
|
104
|
+
# @return [Contrast::Api::Dtm::DynamicSource] the message to send
|
105
|
+
# to the Service to allow it to report the events leading up to
|
106
|
+
# the creation of the Dynamic Source
|
107
|
+
def create_dynamic_source current_context, source_node, field, properties
|
58
108
|
dynamic_source = Contrast::Api::Dtm::DynamicSource.new
|
59
109
|
dynamic_source.class_name = Contrast::Utils::StringUtils.force_utf8(source_node.class_name)
|
60
110
|
dynamic_source.method_name = Contrast::Utils::StringUtils.force_utf8(field)
|
61
111
|
dynamic_source.instance_method = source_node.instance_method?
|
62
112
|
dynamic_source.target = Contrast::Utils::StringUtils.force_utf8(source_node.target_string)
|
63
|
-
events.each do |event|
|
113
|
+
properties.events.each do |event|
|
64
114
|
dynamic_source.events << event.to_dtm_event
|
65
115
|
end
|
66
116
|
dynamic_source.properties[READ_TABLE] = Contrast::Utils::StringUtils.force_utf8(source_node.class_name)
|
@@ -95,20 +95,6 @@ module Contrast
|
|
95
95
|
Contrast::Agent::Assess::Rule::Provider::HardcodedKey,
|
96
96
|
Contrast::Agent::Assess::Rule::Provider::HardcodedPassword
|
97
97
|
].cs__freeze
|
98
|
-
|
99
|
-
# Handles updating the dynamic sources of this Application and indicates
|
100
|
-
# if doing so results in a state that requires repatching -- i.e. new
|
101
|
-
# dynamic sources have been discovered by agents monitoring other
|
102
|
-
# instances of this application
|
103
|
-
def update_dynamic_sources dynamic_sources_map
|
104
|
-
dynamic_sources_map.each do |key, dynamic_source|
|
105
|
-
# key is the dynamic source node id
|
106
|
-
next if sources.any? { |source| source.id == key }
|
107
|
-
|
108
|
-
dynamic_source_node = Contrast::Agent::Assess::Policy::SourceNode.build_dynamic_source(key, dynamic_source)
|
109
|
-
add_node(dynamic_source_node, :dynamic_source)
|
110
|
-
end
|
111
|
-
end
|
112
98
|
end
|
113
99
|
end
|
114
100
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
cs__scoped_require 'contrast/utils/object_share'
|
5
5
|
cs__scoped_require 'contrast/components/interface'
|
6
|
-
cs__scoped_require 'contrast/
|
6
|
+
cs__scoped_require 'contrast/extensions/ruby_core/assess/assess_extension'
|
7
7
|
|
8
8
|
module Contrast
|
9
9
|
module Agent
|
@@ -58,7 +58,7 @@ module Contrast
|
|
58
58
|
private
|
59
59
|
|
60
60
|
def unsafe_io_object? object, initializing
|
61
|
-
Contrast::Utils::DuckUtils.
|
61
|
+
Contrast::Utils::DuckUtils.closable_io?(object) && !initializing && object.closed?
|
62
62
|
end
|
63
63
|
|
64
64
|
def can_dup? initializing, object
|
@@ -98,9 +98,9 @@ module Contrast
|
|
98
98
|
"Propagator #{ propagation_node.id } detected: propagated to #{ target.__id__ }")
|
99
99
|
elsif Contrast::Utils::DuckUtils.quacks_to?(target, :cs__properties)
|
100
100
|
handle_cs_properties_propagation(propagation_node, preshift, target, object, ret, invoked, args, block)
|
101
|
-
elsif Contrast::Utils::DuckUtils.
|
101
|
+
elsif Contrast::Utils::DuckUtils.iterable_hash?(target)
|
102
102
|
handle_hash_propagation(propagation_node, preshift, target, object, ret, invoked, args, block)
|
103
|
-
elsif Contrast::Utils::DuckUtils.
|
103
|
+
elsif Contrast::Utils::DuckUtils.iterable_enumerable?(target)
|
104
104
|
handle_enumerable_propagation(propagation_node, preshift, target, object, ret, invoked, args, block)
|
105
105
|
end
|
106
106
|
rescue StandardError => e
|
@@ -227,6 +227,8 @@ module Contrast
|
|
227
227
|
ret = Contrast::Utils::FreezeUtil.unfreeze_dup(target)
|
228
228
|
target = ret
|
229
229
|
end
|
230
|
+
return if target.cs__properties == Contrast::Agent::Assess::Insulator.generate_frozen.properties
|
231
|
+
|
230
232
|
propagation_class.propagate(propagation_node, preshift, target)
|
231
233
|
|
232
234
|
# Once we've propagated, attempt to tag the target if there is a tag(s) to be applied
|
@@ -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
|
-
cs__scoped_require 'contrast/
|
4
|
+
cs__scoped_require 'contrast/extensions/ruby_core/module'
|
5
5
|
|
6
6
|
module Contrast
|
7
7
|
module Agent
|
@@ -36,7 +36,7 @@ module Contrast
|
|
36
36
|
value.cs__properties.build_event(propagation_node, value, preshift.object, target, preshift.args)
|
37
37
|
next unless tracked_value?(value)
|
38
38
|
|
39
|
-
tainted_columns[key] = value.cs__properties
|
39
|
+
tainted_columns[key] = value.cs__properties
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|