contrast-agent 4.6.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +1 -1
  3. data/Rakefile +1 -2
  4. data/ext/build_funchook.rb +3 -3
  5. data/ext/extconf_common.rb +1 -5
  6. data/lib/contrast/agent/assess.rb +1 -1
  7. data/lib/contrast/agent/assess/contrast_object.rb +2 -2
  8. data/lib/contrast/agent/assess/events/event_factory.rb +2 -1
  9. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +6 -3
  10. data/lib/contrast/agent/assess/policy/patcher.rb +10 -17
  11. data/lib/contrast/agent/assess/policy/policy_node.rb +25 -33
  12. data/lib/contrast/agent/assess/policy/preshift.rb +3 -1
  13. data/lib/contrast/agent/assess/policy/propagation_method.rb +6 -15
  14. data/lib/contrast/agent/assess/policy/propagation_node.rb +19 -8
  15. data/lib/contrast/agent/assess/policy/propagator/center.rb +2 -1
  16. data/lib/contrast/agent/assess/policy/propagator/insert.rb +3 -1
  17. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -1
  18. data/lib/contrast/agent/assess/policy/propagator/select.rb +2 -12
  19. data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -7
  20. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -7
  21. data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -15
  22. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +6 -3
  23. data/lib/contrast/agent/assess/policy/source_method.rb +6 -6
  24. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -3
  25. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +5 -1
  26. data/lib/contrast/agent/assess/policy/trigger_method.rb +6 -15
  27. data/lib/contrast/agent/assess/policy/trigger_node.rb +2 -1
  28. data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +4 -3
  29. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +1 -2
  30. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +1 -8
  31. data/lib/contrast/agent/assess/property/evented.rb +8 -5
  32. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +11 -5
  33. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +4 -1
  34. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +3 -5
  35. data/lib/contrast/agent/class_reopener.rb +3 -1
  36. data/lib/contrast/agent/disable_reaction.rb +1 -3
  37. data/lib/contrast/agent/exclusion_matcher.rb +5 -11
  38. data/lib/contrast/agent/inventory/dependencies.rb +2 -0
  39. data/lib/contrast/agent/middleware.rb +3 -5
  40. data/lib/contrast/agent/module_data.rb +3 -3
  41. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +6 -5
  42. data/lib/contrast/agent/patching/policy/method_policy.rb +6 -2
  43. data/lib/contrast/agent/patching/policy/module_policy.rb +14 -7
  44. data/lib/contrast/agent/patching/policy/patch.rb +11 -16
  45. data/lib/contrast/agent/patching/policy/patch_status.rb +6 -7
  46. data/lib/contrast/agent/patching/policy/patcher.rb +15 -12
  47. data/lib/contrast/agent/patching/policy/policy_node.rb +14 -4
  48. data/lib/contrast/agent/patching/policy/trigger_node.rb +21 -8
  49. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
  50. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
  51. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
  52. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +2 -3
  53. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
  54. data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +5 -9
  55. data/lib/contrast/agent/protect/policy/rule_applicator.rb +5 -5
  56. data/lib/contrast/agent/protect/rule/base.rb +13 -16
  57. data/lib/contrast/agent/protect/rule/base_service.rb +9 -5
  58. data/lib/contrast/agent/protect/rule/cmd_injection.rb +14 -18
  59. data/lib/contrast/agent/protect/rule/deserialization.rb +6 -13
  60. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +3 -14
  61. data/lib/contrast/agent/protect/rule/no_sqli.rb +6 -2
  62. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -3
  63. data/lib/contrast/agent/protect/rule/path_traversal.rb +5 -5
  64. data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
  65. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
  66. data/lib/contrast/agent/protect/rule/xss.rb +1 -1
  67. data/lib/contrast/agent/protect/rule/xxe.rb +5 -12
  68. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +1 -2
  69. data/lib/contrast/agent/reaction_processor.rb +11 -10
  70. data/lib/contrast/agent/request.rb +23 -23
  71. data/lib/contrast/agent/request_context.rb +9 -14
  72. data/lib/contrast/agent/rewriter.rb +5 -3
  73. data/lib/contrast/agent/service_heartbeat.rb +2 -3
  74. data/lib/contrast/agent/tracepoint_hook.rb +1 -1
  75. data/lib/contrast/agent/version.rb +1 -1
  76. data/lib/contrast/api/communication/response_processor.rb +2 -4
  77. data/lib/contrast/api/communication/service_lifecycle.rb +4 -2
  78. data/lib/contrast/api/communication/socket_client.rb +8 -21
  79. data/lib/contrast/api/communication/speedracer.rb +3 -7
  80. data/lib/contrast/api/decorators/application_startup.rb +6 -2
  81. data/lib/contrast/api/decorators/library.rb +8 -6
  82. data/lib/contrast/api/decorators/message.rb +3 -3
  83. data/lib/contrast/api/decorators/trace_event.rb +3 -1
  84. data/lib/contrast/api/decorators/trace_event_object.rb +1 -3
  85. data/lib/contrast/api/decorators/trace_taint_range_tags.rb +1 -6
  86. data/lib/contrast/components/agent.rb +9 -4
  87. data/lib/contrast/components/app_context.rb +6 -6
  88. data/lib/contrast/components/config.rb +2 -1
  89. data/lib/contrast/components/contrast_service.rb +7 -8
  90. data/lib/contrast/components/interface.rb +3 -2
  91. data/lib/contrast/components/sampling.rb +8 -2
  92. data/lib/contrast/components/settings.rb +4 -2
  93. data/lib/contrast/config/assess_rules_configuration.rb +1 -3
  94. data/lib/contrast/config/base_configuration.rb +4 -5
  95. data/lib/contrast/config/exception_configuration.rb +1 -5
  96. data/lib/contrast/config/heap_dump_configuration.rb +12 -6
  97. data/lib/contrast/config/logger_configuration.rb +1 -5
  98. data/lib/contrast/configuration.rb +3 -14
  99. data/lib/contrast/extension/assess/array.rb +1 -6
  100. data/lib/contrast/extension/assess/erb.rb +1 -7
  101. data/lib/contrast/extension/assess/eval_trigger.rb +2 -6
  102. data/lib/contrast/extension/assess/exec_trigger.rb +3 -9
  103. data/lib/contrast/extension/assess/fiber.rb +2 -12
  104. data/lib/contrast/extension/assess/kernel.rb +2 -9
  105. data/lib/contrast/extension/assess/marshal.rb +2 -6
  106. data/lib/contrast/extension/assess/regexp.rb +1 -6
  107. data/lib/contrast/extension/assess/string.rb +3 -1
  108. data/lib/contrast/extension/kernel.rb +4 -2
  109. data/lib/contrast/framework/manager.rb +1 -2
  110. data/lib/contrast/framework/rack/patch/session_cookie.rb +5 -18
  111. data/lib/contrast/framework/rack/patch/support.rb +6 -4
  112. data/lib/contrast/framework/rails/patch/assess_configuration.rb +7 -2
  113. data/lib/contrast/framework/rails/patch/support.rb +4 -2
  114. data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +4 -1
  115. data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +2 -0
  116. data/lib/contrast/framework/rails/rewrite/active_record_named.rb +2 -0
  117. data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +2 -0
  118. data/lib/contrast/framework/rails/support.rb +2 -2
  119. data/lib/contrast/framework/sinatra/support.rb +3 -1
  120. data/lib/contrast/funchook/funchook.rb +1 -5
  121. data/lib/contrast/logger/application.rb +12 -9
  122. data/lib/contrast/logger/format.rb +2 -5
  123. data/lib/contrast/logger/log.rb +4 -3
  124. data/lib/contrast/logger/request.rb +1 -2
  125. data/lib/contrast/security_exception.rb +1 -1
  126. data/lib/contrast/tasks/service.rb +5 -1
  127. data/lib/contrast/utils/assess/tracking_util.rb +1 -2
  128. data/lib/contrast/utils/class_util.rb +0 -8
  129. data/lib/contrast/utils/hash_digest.rb +2 -5
  130. data/lib/contrast/utils/io_util.rb +1 -1
  131. data/lib/contrast/utils/job_servers_running.rb +9 -4
  132. data/lib/contrast/utils/os.rb +2 -1
  133. data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -1
  134. data/ruby-agent.gemspec +13 -14
  135. data/sonar-project.properties +9 -0
  136. metadata +37 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f9748bb3a9e7e6ce4722edc88dbb3bd8d3a59b11dd691f47ac29b3ee9e6a00ba
4
- data.tar.gz: d5b5ff651f2914bff6da5cbd2fdcdc28a2dd1a2ea8ad4eced6c416cbab72b632
3
+ metadata.gz: 8b3d1ce6b9794d3923d2054d9a20bd31989fd0c6b4df2883f81ad3e740c04de5
4
+ data.tar.gz: 894505c04e850858f83e2207c52cc944f738ce19183051d9530cfdaf09f72ab7
5
5
  SHA512:
6
- metadata.gz: 6e03ec0934d333e79f957515dfdc851861d395e9c768d09ffdfbf56b6e818d27361cffb2f010985f6da2182b1a4b070ef2291b86ccd9280fb117c4125611ae8f
7
- data.tar.gz: bb60224de8c19b547f311aca8d78a2b99593e329696ab6acbaf59336316109be5e9419d02e6e4cd06d0714627c0942fea6d1c0872a6c69faff531838e1dbc359
6
+ metadata.gz: 4df81e8b3d03efcdc952e9fce5330b34c6af6a965701ec7bbe02cf3dbd5b8a3c98d8d0745da91d7b0a43be6b03ac763ffb6e9eafb9f2b857bd2a76d325d10ad2
7
+ data.tar.gz: 0015e74007146cf741e6b7f6274460a948a147df54109de959856f0ff883262260685f74eff8767e6ae845847eaf3d8a17dfbd54061d5b9f561952a8c6b90fef
data/.gitmodules CHANGED
@@ -1,6 +1,6 @@
1
1
  [submodule "agent-service-api"]
2
2
  path = agent-service-api
3
- url = git@bitbucket.org:contrastsecurity/agent-service-api
3
+ url = git@github.com:Contrast-Security-Inc/agent-service-api.git
4
4
  [submodule "funchook"]
5
5
  path = funchook
6
6
  url = https://github.com/kubo/funchook.git
data/Rakefile CHANGED
@@ -23,8 +23,7 @@ task :contrast_pb_compile do
23
23
  # do some stuff before compile
24
24
 
25
25
  # Invoke the protobuf compile task with your sensible defaults
26
- ::Rake::Task['protobuf:compile'].invoke('lib',
27
- './agent-service-api/protobuf ./agent-service-api/protobuf/dtm.proto',
26
+ ::Rake::Task['protobuf:compile'].invoke('lib', './agent-service-api/protobuf ./agent-service-api/protobuf/dtm.proto',
28
27
  'lib/contrast/api',
29
28
  nil)
30
29
 
@@ -10,7 +10,8 @@ unless find_header('funchook.h', ext_path)
10
10
  COMMANDS = ['./autogen.sh', './configure', 'make clean', 'make'].freeze
11
11
  bundler_install_target_paths = []
12
12
 
13
- possible_gem_paths = Gem.path # .path and .paths diverge in their return type - .path returns strings, .paths returns PathSupports
13
+ # .path and .paths diverge in their return type - .path returns strings, .paths returns PathSupports
14
+ possible_gem_paths = Gem.path
14
15
  possible_gem_paths.each do |base_path|
15
16
  contrast_gem_dir_search = File.join(base_path, 'extensions', '**', '*', 'contrast-agent-*')
16
17
  extension_paths = Dir[contrast_gem_dir_search]
@@ -31,8 +32,7 @@ unless find_header('funchook.h', ext_path)
31
32
  end
32
33
 
33
34
  SOURCE_PATHS = [
34
- File.join('include', 'funchook.h'),
35
- File.join('src', 'libfunchook.dylib'),
35
+ File.join('include', 'funchook.h'), File.join('src', 'libfunchook.dylib'),
36
36
  File.join('src', 'libfunchook.so')
37
37
  ].freeze
38
38
 
@@ -4,12 +4,8 @@
4
4
  require 'mkmf'
5
5
  require_relative '../lib/contrast/agent/version'
6
6
 
7
- def name
8
- $TO_MAKE
9
- end
10
-
11
7
  def make!
12
- create_makefile "#{ name }/#{ name }"
8
+ create_makefile "#{ $TO_MAKE }/#{ $TO_MAKE }"
13
9
  end
14
10
 
15
11
  def ext_path
@@ -10,7 +10,7 @@ module Contrast
10
10
  module Assess
11
11
  require 'contrast/agent/assess/tracker'
12
12
  require 'contrast/agent/module_data'
13
- require 'contrast/agent/rewriter'
13
+ require 'contrast/agent/rewriter' if RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
14
14
  require 'contrast/agent/assess/policy/preshift'
15
15
 
16
16
  # Dynamic Sources
@@ -34,14 +34,14 @@ module Contrast
34
34
  def initialize object
35
35
  if object
36
36
  @object = Contrast::Utils::ClassUtil.to_contrast_string(object)
37
- @object_type = object.cs__class.name
37
+ @object_type = object.cs__class.cs__name
38
38
  # TODO: RUBY-1084 determine if we need to copy these tags to
39
39
  # restore immutability. For instance, if these tags were on a
40
40
  # String that was then #reverse!'d, would our tags be wrong?
41
41
  @tags = Contrast::Agent::Assess::Tracker.properties(object)&.tags
42
42
  else
43
43
  @object = Contrast::Utils::ObjectShare::NIL_STRING
44
- @object_type = nil.cs__class.name
44
+ @object_type = nil.cs__class.cs__name
45
45
  end
46
46
  end
47
47
 
@@ -13,7 +13,8 @@ module Contrast
13
13
  def self.build policy_node, tagged, object, ret, args, source_type = nil, source_name = nil
14
14
  case policy_node
15
15
  when Contrast::Agent::Assess::Policy::SourceNode
16
- Contrast::Agent::Assess::Events::SourceEvent.new(policy_node, tagged, object, ret, args, source_type, source_name)
16
+ Contrast::Agent::Assess::Events::SourceEvent.new(policy_node, tagged, object, ret, args, source_type,
17
+ source_name)
17
18
  when Contrast::Agent::Assess::Policy::PolicyNode
18
19
  Contrast::Agent::Assess::ContrastEvent.new(policy_node, tagged, object, ret, args)
19
20
  end
@@ -37,7 +37,8 @@ module Contrast
37
37
  # Move on if we already know about this Dynamic Source
38
38
  next if Contrast::Agent::Assess::Policy::Policy.instance.find_source_node(class_name, method_name, true)
39
39
 
40
- dynamic_source_node = create_source_node(class_name, method_name, Set.new(properties.tag_keys), current_request)
40
+ dynamic_source_node = create_source_node(class_name, method_name, Set.new(properties.tag_keys),
41
+ current_request)
41
42
  Contrast::Agent::Assess::Policy::Policy.instance.add_node(dynamic_source_node, :dynamic_source)
42
43
  method_policy = build_source_policy(method_name, dynamic_source_node)
43
44
  Contrast::Agent::Patching::Policy::Patcher.patch_method(klass, instance_methods, method_policy)
@@ -130,8 +131,10 @@ module Contrast
130
131
  def append_properties! dynamic_source, request, source_node, field
131
132
  dynamic_source.properties[READ_TABLE] = Contrast::Utils::StringUtils.force_utf8(source_node.class_name)
132
133
  dynamic_source.properties[READ_COLUMN] = Contrast::Utils::StringUtils.force_utf8(field)
133
- dynamic_source.properties[WRITE_QUERY_TIME] = Contrast::Utils::StringUtils.force_utf8(Contrast::Utils::Timer.now_ms)
134
- dynamic_source.properties[WRITE_QUERY_URL] = Contrast::Utils::StringUtils.force_utf8(request&.normalized_uri)
134
+ dynamic_source.properties[WRITE_QUERY_TIME] =
135
+ Contrast::Utils::StringUtils.force_utf8(Contrast::Utils::Timer.now_ms)
136
+ dynamic_source.properties[WRITE_QUERY_URL] =
137
+ Contrast::Utils::StringUtils.force_utf8(request&.normalized_uri)
135
138
  end
136
139
 
137
140
  def append_events! dynamic_source, event
@@ -39,19 +39,13 @@ module Contrast
39
39
 
40
40
  patcher.patch_specific_module(mod)
41
41
  rescue StandardError => e
42
- logger.warn(
43
- 'Unable to patch assess during eval',
44
- e,
45
- module: mod.cs__name)
42
+ logger.warn('Unable to patch assess during eval', e, module: mod.cs__name)
46
43
  end
47
44
 
48
45
  # Exposed so that methods can be dynamically patched on creation at
49
46
  # runtime, like those generated by
50
47
  # ActiveRecord::AttributeMethods::Read::ClassMethods#define_method_attribute
51
- CLASS_TYPES = [
52
- Contrast::Utils::ObjectShare::CLASS,
53
- Contrast::Utils::ObjectShare::MODULE
54
- ].cs__freeze
48
+ CLASS_TYPES = [Contrast::Utils::ObjectShare::CLASS, Contrast::Utils::ObjectShare::MODULE].cs__freeze
55
49
  def patch_assess_method mod, method_name
56
50
  # Module.define_method is called a lot in Class and Module. We
57
51
  # currently do not expect these define_methods to result in methods
@@ -62,7 +56,8 @@ module Contrast
62
56
  return if CLASS_TYPES.include?(class_name)
63
57
  return unless ASSESS.enabled?
64
58
 
65
- source_nodes = Contrast::Agent::Patching::Policy::ModulePolicy.nodes_for_module(policy.sources, class_name)
59
+ source_nodes = Contrast::Agent::Patching::Policy::ModulePolicy.nodes_for_module(policy.sources,
60
+ class_name)
66
61
  return if source_nodes.empty?
67
62
 
68
63
  method_array = []
@@ -70,17 +65,15 @@ module Contrast
70
65
  source_nodes.each do |source_node|
71
66
  next unless source_node.method_name.to_s == method_name
72
67
 
73
- method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.new(source_node: source_node,
74
- method_name: source_node.method_name,
75
- method_visibility: source_node.method_visibility,
76
- instance_method: true)
68
+ method_policy =
69
+ Contrast::Agent::Patching::Policy::MethodPolicy.new(source_node: source_node,
70
+ method_name: source_node.method_name,
71
+ method_visibility: source_node.method_visibility,
72
+ instance_method: true)
77
73
  patcher.patch_method(mod, method_array, method_policy)
78
74
  end
79
75
  rescue StandardError => e
80
- logger.warn(
81
- 'Unable to patch assess during define_method_attribute',
82
- e,
83
- module: mod.cs__name)
76
+ logger.warn('Unable to patch assess during define_method_attribute', e, module: mod.cs__name)
84
77
  end
85
78
  end
86
79
  end
@@ -35,16 +35,6 @@ module Contrast
35
35
  :TYPE_METHOD
36
36
  end
37
37
 
38
- def target
39
- @_target ||= begin
40
- if targets&.any?
41
- targets[0]
42
- elsif sources&.any?
43
- sources[0]
44
- end
45
- end
46
- end
47
-
48
38
  def target_string= value
49
39
  @target_string = value
50
40
  @targets = convert_policy_markers(value)
@@ -85,8 +75,7 @@ module Contrast
85
75
  next if Contrast::Api::Decorators::TraceTaintRangeTags::VALID_TAGS.include?(tag) ||
86
76
  Contrast::Api::Decorators::TraceTaintRangeTags::VALID_SOURCE_TAGS.include?(tag)
87
77
 
88
- raise(ArgumentError,
89
- "#{ node_class } #{ id } had an invalid tag. #{ tag } is not a known value.")
78
+ raise(ArgumentError, "#{ node_class } #{ id } had an invalid tag. #{ tag } is not a known value.")
90
79
  end
91
80
  end
92
81
 
@@ -100,27 +89,26 @@ module Contrast
100
89
  # Trigger (trigger nodes) don't have targets (they are the target)
101
90
  # Everything else (propagation nodes) are Source2Target
102
91
  def build_action
103
- @event_action ||= begin
104
- case node_class
105
- when Contrast::Agent::Assess::Policy::SourceNode::SOURCE
106
- :CREATION
107
- when Contrast::Agent::Assess::Policy::TriggerNode::TRIGGER
108
- :TRIGGER
109
- else
110
- if source_string.nil?
111
- :CREATION
112
- elsif target_string.nil?
113
- :TRIGGER
114
- else
115
- # TeamServer can't handle the multi-source or multi-target
116
- # values. Give it some help by changing them to 'A'
117
- source = source_string.include?(Contrast::Utils::ObjectShare::COMMA) ? ALL_TYPE : source_string
118
- target = target_string.include?(Contrast::Utils::ObjectShare::COMMA) ? ALL_TYPE : target_string
119
- str = source[0] + TO_MARKER + target[0]
120
- str.to_sym
121
- end
122
- end
123
- end
92
+ @event_action ||= case node_class
93
+ when Contrast::Agent::Assess::Policy::SourceNode::SOURCE
94
+ :CREATION
95
+ when Contrast::Agent::Assess::Policy::TriggerNode::TRIGGER
96
+ :TRIGGER
97
+ else
98
+ if source_string.nil?
99
+ :CREATION
100
+ elsif target_string.nil?
101
+ :TRIGGER
102
+ else
103
+ # TeamServer can't handle the multi-source or multi-target values. Give it some help
104
+ # by changing them to 'A'
105
+ source = all_type?(source_string) ? ALL_TYPE : source_string
106
+ target = all_type?(target_string) ? ALL_TYPE : target_string
107
+ str = source[0] + TO_MARKER + target[0]
108
+ str.to_sym
109
+ end
110
+ end
111
+
124
112
  @event_action
125
113
  end
126
114
 
@@ -158,6 +146,10 @@ module Contrast
158
146
  end
159
147
  converted
160
148
  end
149
+
150
+ def all_type? marker
151
+ marker.include?(Contrast::Utils::ObjectShare::COMMA)
152
+ end
161
153
  end
162
154
  end
163
155
  end
@@ -91,7 +91,9 @@ module Contrast
91
91
 
92
92
  Contrast::Agent::Assess::Tracker.copy(original_arg, preshift_arg)
93
93
  end
94
- preshift.arg_lengths = preshift.args.map { |preshift_arg| Contrast::Utils::DuckUtils.quacks_to?(preshift_arg, :length) ? preshift_arg.length : 0 }
94
+ preshift.arg_lengths = preshift.args.map do |preshift_arg|
95
+ Contrast::Utils::DuckUtils.quacks_to?(preshift_arg, :length) ? preshift_arg.length : 0
96
+ end
95
97
  end
96
98
  end
97
99
  end
@@ -140,13 +140,7 @@ module Contrast
140
140
  !!target
141
141
  end
142
142
 
143
- ZERO_LENGTH_ACTIONS = [
144
- DB_WRITE_ACTION,
145
- CUSTOM_ACTION,
146
- KEEP_ACTION,
147
- REPLACE_ACTION,
148
- SPLAT_ACTION
149
- ].cs__freeze
143
+ ZERO_LENGTH_ACTIONS = [DB_WRITE_ACTION, CUSTOM_ACTION, KEEP_ACTION, REPLACE_ACTION, SPLAT_ACTION].cs__freeze
150
144
  # If the action required needs a length and the target does not have
151
145
  # one, the length is not valid
152
146
  def valid_length? target, action
@@ -245,7 +239,7 @@ module Contrast
245
239
 
246
240
  def handle_enumerable_propagation propagation_node, preshift, target, object, ret, args, block
247
241
  target.each do |value|
248
- next if target == value # Some Enumerable#each are overridden to return self the first time which leads to infinite propagation
242
+ next if target == value
249
243
 
250
244
  apply_propagator(propagation_node, preshift, value, object, ret, args, block)
251
245
  end
@@ -283,9 +277,7 @@ module Contrast
283
277
 
284
278
  properties.add_properties(propagation_node.properties)
285
279
  properties.build_event(propagation_node, target, object, ret, args)
286
- logger.trace('Propagation detected',
287
- node_id: propagation_node.id,
288
- target_id: target.__id__)
280
+ logger.trace('Propagation detected', node_id: propagation_node.id, target_id: target.__id__)
289
281
  restore_frozen_state ? ret : nil
290
282
  end
291
283
 
@@ -296,10 +288,9 @@ module Contrast
296
288
  # @return [Contrast::Agent::Assess::Policy::Propagator, nil]
297
289
  def find_propagation_class propagation_node
298
290
  unless (propagation_class = PROPAGATION_ACTIONS.fetch(propagation_node.action, nil))
299
- logger.warn(
300
- 'Unknown propagation action received. Unable to propagate.',
301
- node_id: propagation_node.id,
302
- action: propagation_node.action)
291
+ logger.warn('Unknown propagation action received. Unable to propagate.',
292
+ node_id: propagation_node.id,
293
+ action: propagation_node.action)
303
294
  end
304
295
  propagation_class
305
296
  end
@@ -62,11 +62,19 @@ module Contrast
62
62
  raise(ArgumentError, "Propagator #{ id } did not have a proper action. Unable to create.") unless action
63
63
 
64
64
  if @action == 'CUSTOM'
65
- raise(ArgumentError, "Propagator #{ id } did not have a proper patch_class. Unable to create.") unless patch_class
66
- raise(ArgumentError, "Propagator #{ id } did not have a proper patch_method. Unable to create.") unless patch_method.is_a?(Symbol)
65
+ unless patch_class
66
+ raise(ArgumentError, "Propagator #{ id } did not have a proper patch_class. Unable to create.")
67
+ end
68
+ unless patch_method.is_a?(Symbol)
69
+ raise(ArgumentError, "Propagator #{ id } did not have a proper patch_method. Unable to create.")
70
+ end
67
71
  else
68
- raise(ArgumentError, "Propagator #{ id } did not have a proper target. Unable to create.") unless targets&.any?
69
- raise(ArgumentError, "Propagator #{ id } did not have a proper source. Unable to create.") unless sources&.any?
72
+ unless targets&.any?
73
+ raise(ArgumentError, "Propagator #{ id } did not have a proper target. Unable to create.")
74
+ end
75
+ unless sources&.any?
76
+ raise(ArgumentError, "Propagator #{ id } did not have a proper source. Unable to create.")
77
+ end
70
78
  end
71
79
  validate_untags
72
80
  end
@@ -76,9 +84,12 @@ module Contrast
76
84
 
77
85
  untags.each do |tag|
78
86
  unless Contrast::Api::Decorators::TraceTaintRangeTags::VALID_TAGS.include?(tag)
79
- raise(ArgumentError, "#{ node_type } #{ id } did not have a valid untag. #{ tag } is not a known value.")
87
+ raise(ArgumentError,
88
+ "#{ node_type } #{ id } did not have a valid untag. #{ tag } is not a known value.")
89
+ end
90
+ if tags&.include?(tag)
91
+ raise(ArgumentError, "#{ node_type } #{ id } had the same tag and untag, #{ tag }.")
80
92
  end
81
- raise(ArgumentError, "#{ node_type } #{ id } had the same tag and untag, #{ tag }.") if tags&.include?(tag)
82
93
  end
83
94
  end
84
95
 
@@ -86,8 +97,8 @@ module Contrast
86
97
  if @_needs_object.nil?
87
98
  @_needs_object = action == Contrast::Agent::Assess::Policy::PropagationMethod::CUSTOM_ACTION ||
88
99
  action == Contrast::Agent::Assess::Policy::PropagationMethod::DB_WRITE_ACTION ||
89
- sources.any? { |source| source == Contrast::Utils::ObjectShare::OBJECT_KEY } ||
90
- targets.any? { |target| target == Contrast::Utils::ObjectShare::OBJECT_KEY }
100
+ sources.any?(Contrast::Utils::ObjectShare::OBJECT_KEY) ||
101
+ targets.any?(Contrast::Utils::ObjectShare::OBJECT_KEY)
91
102
  end
92
103
  @_needs_object
93
104
  end
@@ -31,7 +31,8 @@ module Contrast
31
31
  return unless sources[1]
32
32
 
33
33
  original_end_index = original_start_index + source1.length - 1
34
- handle_incoming_tags(target, propagation_node, sources[1], preshift, original_start_index, original_end_index)
34
+ handle_incoming_tags(target, propagation_node, sources[1], preshift, original_start_index,
35
+ original_end_index)
35
36
  end
36
37
 
37
38
  private
@@ -33,7 +33,9 @@ module Contrast
33
33
  # point on which all tags need to be adjusted
34
34
  # If the insertion point is the end of the string, preshift length is returned
35
35
  # https://stackoverflow.com/questions/31714522/find-the-first-differing-character-between-two-strings-in-ruby
36
- insert_point = (0...preshift_target.length).find { |i| preshift_target[i] != target[i] } || preshift_target.length
36
+ insert_point = (0...preshift_target.length).find do |i|
37
+ preshift_target[i] != target[i]
38
+ end || preshift_target.length
37
39
  # Depending what's inserted, we might be wrong. For instance, inserting 'foo'
38
40
  # into 'asdfasdf' could result in 'asdfoofasdf'. we'd be off by one b/c of the 'f'
39
41
  insert_point = target.rindex(source, insert_point)
@@ -76,7 +76,8 @@ module Contrast
76
76
  applicable_tags.each do |tag_name, tag_ranges|
77
77
  return_properties.set_tags(tag_name, tag_ranges)
78
78
  end
79
- return_properties.build_event(propagation_node, return_value, preshift.object, return_value, preshift.args)
79
+ return_properties.build_event(propagation_node, return_value, preshift.object, return_value,
80
+ preshift.args)
80
81
  end
81
82
  end
82
83
  end
@@ -21,22 +21,12 @@ module Contrast
21
21
  # Additionally, an empty string is returned when the starting index for
22
22
  # a character range is at the end of the string. Let's just skip that
23
23
  # and only track a string that has length
24
- unless ret &&
25
- !ret.empty? &&
26
- Contrast::Agent::Assess::Tracker.tracked?(source)
27
-
28
- return
29
- end
24
+ return unless ret && !ret.empty? && Contrast::Agent::Assess::Tracker.tracked?(source)
30
25
 
31
26
  return unless (source_properties = Contrast::Agent::Assess::Tracker.properties(source))
32
27
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(ret))
33
28
 
34
- properties.build_event(
35
- patcher,
36
- ret,
37
- source,
38
- ret,
39
- args)
29
+ properties.build_event(patcher, ret, source, ret, args)
40
30
 
41
31
  range = determine_select_range(source, args)
42
32
  return unless range
@@ -31,9 +31,7 @@ module Contrast
31
31
  # @return [nil] so as not to risk changing the result of the propagation.
32
32
 
33
33
  def propagate propagation_node, preshift, target
34
- logger.trace('Propagation detected',
35
- node_id: propagation_node.id,
36
- target_id: target.__id__)
34
+ logger.trace('Propagation detected', node_id: propagation_node.id, target_id: target.__id__)
37
35
 
38
36
  source = find_source(propagation_node.sources[0], preshift)
39
37
  return unless (source_properties = Contrast::Agent::Assess::Tracker.properties(source))
@@ -162,10 +160,8 @@ module Contrast
162
160
  #
163
161
  # @return [Contrast::Agent::Assess::Policy::PropagationNode] String#split node
164
162
  def split_node
165
- @_split_node ||= begin
166
- Contrast::Agent::Assess::Policy::Policy.instance.propagators.find do |node|
167
- node.class_name == 'String' && node.method_name == :split && node.instance_method?
168
- end
163
+ @_split_node ||= Contrast::Agent::Assess::Policy::Policy.instance.propagators.find do |node|
164
+ node.class_name == 'String' && node.method_name == :split && node.instance_method?
169
165
  end
170
166
  end
171
167
  end