contrast-agent 4.1.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +22 -10
  4. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +4 -3
  5. data/lib/contrast/agent.rb +5 -1
  6. data/lib/contrast/agent/assess.rb +0 -9
  7. data/lib/contrast/agent/assess/contrast_event.rb +49 -132
  8. data/lib/contrast/agent/assess/contrast_object.rb +54 -0
  9. data/lib/contrast/agent/assess/events/source_event.rb +4 -9
  10. data/lib/contrast/agent/assess/finalizers/hash.rb +7 -0
  11. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +17 -3
  12. data/lib/contrast/agent/assess/policy/patcher.rb +4 -3
  13. data/lib/contrast/agent/assess/policy/policy_node.rb +31 -59
  14. data/lib/contrast/agent/assess/policy/preshift.rb +3 -3
  15. data/lib/contrast/agent/assess/policy/propagation_method.rb +41 -32
  16. data/lib/contrast/agent/assess/policy/propagation_node.rb +12 -24
  17. data/lib/contrast/agent/assess/policy/propagator/append.rb +29 -15
  18. data/lib/contrast/agent/assess/policy/propagator/center.rb +1 -2
  19. data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
  20. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +21 -18
  21. data/lib/contrast/agent/assess/policy/propagator/insert.rb +1 -2
  22. data/lib/contrast/agent/assess/policy/propagator/keep.rb +1 -2
  23. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +3 -2
  24. data/lib/contrast/agent/assess/policy/propagator/next.rb +1 -2
  25. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +1 -2
  26. data/lib/contrast/agent/assess/policy/propagator/remove.rb +2 -4
  27. data/lib/contrast/agent/assess/policy/propagator/replace.rb +1 -2
  28. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +1 -2
  29. data/lib/contrast/agent/assess/policy/propagator/select.rb +3 -4
  30. data/lib/contrast/agent/assess/policy/propagator/splat.rb +25 -17
  31. data/lib/contrast/agent/assess/policy/propagator/split.rb +83 -120
  32. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +41 -25
  33. data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -7
  34. data/lib/contrast/agent/assess/policy/source_method.rb +2 -14
  35. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +5 -8
  36. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +1 -1
  37. data/lib/contrast/agent/assess/policy/trigger_method.rb +13 -8
  38. data/lib/contrast/agent/assess/policy/trigger_node.rb +28 -7
  39. data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +59 -0
  40. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -3
  41. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +6 -4
  42. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +2 -4
  43. data/lib/contrast/agent/assess/properties.rb +0 -2
  44. data/lib/contrast/agent/assess/property/tagged.rb +56 -32
  45. data/lib/contrast/agent/assess/tracker.rb +16 -18
  46. data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +7 -0
  47. data/lib/contrast/agent/middleware.rb +134 -55
  48. data/lib/contrast/agent/patching/policy/method_policy.rb +1 -1
  49. data/lib/contrast/agent/patching/policy/patch.rb +6 -0
  50. data/lib/contrast/agent/patching/policy/patch_status.rb +1 -1
  51. data/lib/contrast/agent/patching/policy/patcher.rb +51 -44
  52. data/lib/contrast/agent/patching/policy/trigger_node.rb +5 -2
  53. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +47 -1
  54. data/lib/contrast/agent/protect/policy/rule_applicator.rb +53 -0
  55. data/lib/contrast/agent/protect/rule/base.rb +63 -14
  56. data/lib/contrast/agent/protect/rule/cmd_injection.rb +12 -28
  57. data/lib/contrast/agent/protect/rule/default_scanner.rb +1 -4
  58. data/lib/contrast/agent/protect/rule/deserialization.rb +4 -1
  59. data/lib/contrast/agent/protect/rule/no_sqli.rb +3 -3
  60. data/lib/contrast/agent/protect/rule/sqli.rb +20 -14
  61. data/lib/contrast/agent/protect/rule/xxe.rb +32 -11
  62. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +10 -6
  63. data/lib/contrast/agent/reaction_processor.rb +1 -1
  64. data/lib/contrast/agent/request_context.rb +12 -0
  65. data/lib/contrast/agent/response.rb +5 -5
  66. data/lib/contrast/agent/rewriter.rb +3 -3
  67. data/lib/contrast/agent/scope.rb +81 -55
  68. data/lib/contrast/agent/static_analysis.rb +13 -7
  69. data/lib/contrast/agent/thread.rb +1 -1
  70. data/lib/contrast/agent/thread_watcher.rb +20 -5
  71. data/lib/contrast/agent/version.rb +1 -1
  72. data/lib/contrast/api/communication/messaging_queue.rb +18 -21
  73. data/lib/contrast/api/communication/response_processor.rb +8 -1
  74. data/lib/contrast/api/communication/socket_client.rb +22 -14
  75. data/lib/contrast/api/decorators.rb +2 -0
  76. data/lib/contrast/api/decorators/agent_startup.rb +58 -0
  77. data/lib/contrast/api/decorators/application_startup.rb +51 -0
  78. data/lib/contrast/api/decorators/library.rb +1 -0
  79. data/lib/contrast/api/decorators/library_usage_update.rb +1 -0
  80. data/lib/contrast/api/decorators/route_coverage.rb +15 -5
  81. data/lib/contrast/api/decorators/trace_event.rb +58 -42
  82. data/lib/contrast/api/decorators/trace_event_object.rb +11 -3
  83. data/lib/contrast/api/decorators/trace_event_signature.rb +27 -5
  84. data/lib/contrast/api/decorators/user_input.rb +2 -1
  85. data/lib/contrast/common_agent_configuration.rb +2 -1
  86. data/lib/contrast/components/agent.rb +2 -0
  87. data/lib/contrast/components/app_context.rb +4 -22
  88. data/lib/contrast/components/assess.rb +36 -0
  89. data/lib/contrast/components/interface.rb +5 -3
  90. data/lib/contrast/components/sampling.rb +48 -6
  91. data/lib/contrast/components/scope.rb +72 -6
  92. data/lib/contrast/components/settings.rb +11 -7
  93. data/lib/contrast/config/assess_configuration.rb +2 -1
  94. data/lib/contrast/extension/assess/array.rb +2 -3
  95. data/lib/contrast/extension/assess/erb.rb +1 -3
  96. data/lib/contrast/extension/assess/exec_trigger.rb +1 -4
  97. data/lib/contrast/extension/assess/fiber.rb +2 -3
  98. data/lib/contrast/extension/assess/hash.rb +4 -2
  99. data/lib/contrast/extension/assess/kernel.rb +1 -2
  100. data/lib/contrast/extension/assess/marshal.rb +34 -26
  101. data/lib/contrast/extension/assess/regexp.rb +3 -8
  102. data/lib/contrast/extension/assess/string.rb +1 -2
  103. data/lib/contrast/framework/base_support.rb +51 -53
  104. data/lib/contrast/framework/manager.rb +16 -14
  105. data/lib/contrast/framework/rack/patch/session_cookie.rb +1 -1
  106. data/lib/contrast/framework/rack/support.rb +2 -1
  107. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -1
  108. data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +1 -1
  109. data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +1 -1
  110. data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +1 -1
  111. data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +1 -1
  112. data/lib/contrast/framework/rails/support.rb +44 -44
  113. data/lib/contrast/framework/sinatra/support.rb +102 -42
  114. data/lib/contrast/logger/application.rb +0 -3
  115. data/lib/contrast/logger/log.rb +31 -15
  116. data/lib/contrast/utils/class_util.rb +3 -1
  117. data/lib/contrast/utils/duck_utils.rb +1 -1
  118. data/lib/contrast/utils/heap_dump_util.rb +103 -87
  119. data/lib/contrast/utils/invalid_configuration_util.rb +21 -12
  120. data/lib/contrast/utils/object_share.rb +3 -3
  121. data/lib/contrast/utils/preflight_util.rb +1 -1
  122. data/lib/contrast/utils/resource_loader.rb +1 -1
  123. data/lib/contrast/utils/sha256_builder.rb +2 -2
  124. data/lib/contrast/utils/string_utils.rb +1 -1
  125. data/lib/contrast/utils/tag_util.rb +9 -13
  126. data/resources/assess/policy.json +12 -18
  127. data/resources/deadzone/policy.json +156 -0
  128. data/resources/protect/policy.json +12 -0
  129. data/ruby-agent.gemspec +61 -19
  130. data/service_executables/VERSION +1 -1
  131. data/service_executables/linux/contrast-service +0 -0
  132. data/service_executables/mac/contrast-service +0 -0
  133. metadata +126 -113
  134. data/lib/contrast/agent/assess/rule.rb +0 -18
  135. data/lib/contrast/agent/assess/rule/base.rb +0 -52
  136. data/lib/contrast/agent/assess/rule/redos.rb +0 -67
  137. data/lib/contrast/framework/sinatra/patch/base.rb +0 -83
  138. data/lib/contrast/framework/sinatra/patch/support.rb +0 -27
  139. data/lib/contrast/utils/prevent_serialization.rb +0 -52
@@ -52,7 +52,7 @@ module Contrast
52
52
  # Return a String representing the object invoking this method in the
53
53
  # form expected by our dataflow events.
54
54
  #
55
- # @param object [Object] the entity to convert to a String
55
+ # @param object [Object, nil] the entity to convert to a String
56
56
  # @return [String] the human readable form of the String, as defined by
57
57
  # https://bitbucket.org/contrastsecurity/assess-specifications/src/master/vulnerability/capture-snapshot.md
58
58
  def to_contrast_string object
@@ -63,6 +63,8 @@ module Contrast
63
63
  return cached if cached
64
64
 
65
65
  object.dup
66
+ elsif object.nil?
67
+ Contrast::Utils::ObjectShare::NIL_STRING
66
68
  elsif object.cs__is_a?(Symbol)
67
69
  ":#{ object }"
68
70
  elsif object.cs__is_a?(Numeric)
@@ -4,7 +4,7 @@
4
4
  module Contrast
5
5
  module Utils
6
6
  # Utility methods for identifying instances that can be used interchangeably
7
- class DuckUtils
7
+ module DuckUtils
8
8
  class << self
9
9
  # Determine if the given object, or the object to which it delegates,
10
10
  # responds to the given method.
@@ -2,12 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'objspace'
5
+ require 'singleton'
5
6
  require 'contrast/components/interface'
6
7
 
7
8
  module Contrast
8
9
  module Utils
9
10
  # Implementation of a heap dump util to automate generation
10
- class HeapDumpUtil
11
+ class HeapDumpUtil < Contrast::Agent::WorkerThread
11
12
  include Contrast::Components::Interface
12
13
  access_component :heap_dump, :logging
13
14
 
@@ -15,98 +16,113 @@ module Contrast
15
16
  FILE_WRITE_FLAGS = 'w'
16
17
 
17
18
  class << self
18
- def run
19
- return unless heap_dump_enabled?
20
-
21
- log_enabled_warning
22
- dir = heap_dump_control[:path]
23
- Dir.mkdir(dir) unless Dir.exist?(dir)
24
- return unless File.writable?(dir)
25
-
26
- delay = heap_dump_control[:delay]
27
- Contrast::Agent::Thread.new do
28
- logger.info("HEAP DUMP THREAD INITIALIZED. WAITING #{ delay } SECONDS TO BEGIN.")
29
- sleep(delay)
30
- capture_heap_dump
31
- end
32
- rescue StandardError => e
33
- logger.info(LOG_ERROR_DUMPS, e)
34
- nil
19
+ def enabled?
20
+ heap_dump_enabled?
21
+ end
22
+
23
+ def control
24
+ heap_dump_control
35
25
  end
26
+ end
27
+
28
+ def start_thread!
29
+ return unless Contrast::Utils::HeapDumpUtil.enabled?
36
30
 
37
- def log_enabled_warning
38
- dir = heap_dump_control[:path]
39
- window = heap_dump_control[:window]
40
- count = heap_dump_control[:count]
41
- delay = heap_dump_control[:delay]
42
- clean = heap_dump_control[:clean]
43
-
44
- logger.info <<~WARNING
45
- *****************************************************
46
- ******** HEAP DUMP HAS BEEN ENABLED ********
47
- *** APPLICATION PROCESS WILL EXIT UPON COMPLETION ***
48
- *****************************************************
49
-
50
- Heap dump is a debugging tool that snapshots the entire
51
- state of the Ruby VM. It is an exceptionally expensive
52
- process, and should only be used to debug especially
53
- pernicious errors.
54
-
55
- It will write multiple memory snaphots, which are liable
56
- to be multiple gigabytes in size.
57
- They will be named "[unix timestamp]-heap.dump",
58
- e.g.: 1020304050-heap.dump
59
-
60
- It will then call Ruby `exit()`.
61
-
62
- If this is not your specific intent, you can (and should)
63
- disable this option in your Contrast config file.
64
-
65
- HEAP DUMP PARAMETERS:
66
- \t[write files to this directory] dir: #{ dir }
67
- \t[wait this many seconds in between dumps] window: #{ window }
68
- \t[heap dump this many times] count: #{ count }
69
- \t[wait this many seconds into app lifetime] delay: #{ delay }
70
- \t[perform gc pass before dump] clean: #{ clean }
71
-
72
- *****************************************************
73
- ******** YOU HAVE BEEN WARNED ********
74
- *****************************************************
75
- WARNING
31
+ control = Contrast::Utils::HeapDumpUtil.control
32
+ log_enabled_warning
33
+ dir = control[:path]
34
+ Dir.mkdir(dir) unless Dir.exist?(dir)
35
+ return unless File.writable?(dir)
36
+
37
+ delay = control[:delay]
38
+ @_thread = Contrast::Agent::Thread.new do
39
+ logger.info("HEAP DUMP THREAD INITIALIZED. WAITING #{ delay } SECONDS TO BEGIN.")
40
+ sleep(delay)
41
+ capture_heap_dump
76
42
  end
43
+ rescue StandardError => e
44
+ logger.info(LOG_ERROR_DUMPS, e)
45
+ nil
46
+ end
47
+
48
+ def log_enabled_warning
49
+ control = Contrast::Utils::HeapDumpUtil.control
50
+ dir = control[:path]
51
+ window = control[:window]
52
+ count = control[:count]
53
+ delay = control[:delay]
54
+ clean = control[:clean]
55
+
56
+ logger.info <<~WARNING
57
+ *****************************************************
58
+ ******** HEAP DUMP HAS BEEN ENABLED ********
59
+ *** APPLICATION PROCESS WILL EXIT UPON COMPLETION ***
60
+ *****************************************************
61
+
62
+ Heap dump is a debugging tool that snapshots the entire
63
+ state of the Ruby VM. It is an exceptionally expensive
64
+ process, and should only be used to debug especially
65
+ pernicious errors.
66
+
67
+ It will write multiple memory snaphots, which are liable
68
+ to be multiple gigabytes in size.
69
+ They will be named "[unix timestamp]-heap.dump",
70
+ e.g.: 1020304050-heap.dump
71
+
72
+ It will then call Ruby `exit()`.
73
+
74
+ If this is not your specific intent, you can (and should)
75
+ disable this option in your Contrast config file.
76
+
77
+ HEAP DUMP PARAMETERS:
78
+ \t[write files to this directory] dir: #{ dir }
79
+ \t[wait this many seconds in between dumps] window: #{ window }
80
+ \t[heap dump this many times] count: #{ count }
81
+ \t[wait this many seconds into app lifetime] delay: #{ delay }
82
+ \t[perform gc pass before dump] clean: #{ clean }
83
+
84
+ *****************************************************
85
+ ******** YOU HAVE BEEN WARNED ********
86
+ *****************************************************
87
+ WARNING
88
+ end
89
+
90
+ def capture_heap_dump
91
+ control = Contrast::Utils::HeapDumpUtil.control
92
+ dir = control[:path]
93
+ window = control[:window]
94
+ count = control[:count]
95
+ clean = control[:clean]
96
+ logger.info('HEAP DUMP MAIN LOOP')
97
+ ObjectSpace.trace_object_allocations_start
98
+ count.times do |i|
99
+ logger.info('STARTING HEAP DUMP PASS', current_pass: i, max: count)
100
+ snapshot_heap(dir, clean)
101
+ logger.info('FINISHING HEAP DUMP PASS', current_pass: i, max: count)
102
+ sleep(window)
103
+ end
104
+ ensure
105
+ ObjectSpace.trace_object_allocations_stop
106
+ logger.info('*****************************************************')
107
+ logger.info('******** HEAP DUMP HAS CONCLUDED ********')
108
+ logger.info('*** APPLICATION PROCESS WILL EXIT SHORTLY ***')
109
+ logger.info('*****************************************************')
110
+ exit # rubocop:disable Rails/Exit We weren't kidding!
111
+ end
77
112
 
78
- def capture_heap_dump
79
- dir = heap_dump_control[:path]
80
- window = heap_dump_control[:window]
81
- count = heap_dump_control[:count]
82
- clean = heap_dump_control[:clean]
83
- logger.info('HEAP DUMP MAIN LOOP')
84
- ObjectSpace.trace_object_allocations_start
85
- count.times do |i|
86
- logger.info('STARTING HEAP DUMP PASS', current_pass: i + 1, max: count)
87
- output = "#{ Time.now.to_f }-heap.dump"
88
- output = File.join(dir, output)
89
- begin
90
- logger.info('OPENING HEADUMP FILE', dir: dir, file: output)
91
- file = File.new(output, FILE_WRITE_FLAGS)
92
- if clean
93
- logger.info('PERFORMING GARBAGE COLLECTION BEFORE HEAP DUMP')
94
- GC.start
95
- end
96
- ObjectSpace.dump_all(output: file)
97
- logger.info('FINISHING HEAP DUMP PASS', current_pass: i + 1, max: count)
98
- ensure
99
- file.close
100
- end
101
- sleep(window)
113
+ def snapshot_heap dir, clean
114
+ output = "#{ Time.now.to_f }-heap.dump"
115
+ output = File.join(dir, output)
116
+ begin
117
+ logger.info('OPENING HEADUMP FILE', dir: dir, file: output)
118
+ file = File.new(output, FILE_WRITE_FLAGS)
119
+ if clean
120
+ logger.info('PERFORMING GARBAGE COLLECTION BEFORE HEAP DUMP')
121
+ GC.start
102
122
  end
123
+ ObjectSpace.dump_all(output: file)
103
124
  ensure
104
- ObjectSpace.trace_object_allocations_stop
105
- logger.info('*****************************************************')
106
- logger.info('******** HEAP DUMP HAS CONCLUDED ********')
107
- logger.info('*** APPLICATION PROCESS WILL EXIT SHORTLY ***')
108
- logger.info('*****************************************************')
109
- exit # We weren't kidding!
125
+ file.close
110
126
  end
111
127
  end
112
128
  end
@@ -26,19 +26,9 @@ module Contrast
26
26
  def cs__report_finding rule_id, user_provided_options, call_location
27
27
  with_contrast_scope do
28
28
  finding = Contrast::Api::Dtm::Finding.new
29
- finding.rule_id = rule_id
30
- path = call_location.path
31
- # just get the file name, not the full path
32
- path = path.split(Contrast::Utils::ObjectShare::SLASH).last
33
- session_id = user_provided_options[:key].to_s if user_provided_options
34
-
35
29
  finding.version = Contrast::Agent::Assess::Policy::TriggerMethod::CURRENT_FINDING_VERSION
36
- finding.properties[CS__SESSION_ID] = Contrast::Utils::StringUtils.force_utf8(session_id)
37
- finding.properties[CS__PATH] = Contrast::Utils::StringUtils.force_utf8(path)
38
- file_path = call_location.absolute_path
39
- snippet = file_snippet(file_path, call_location)
40
- finding.properties[CS__SNIPPET] = Contrast::Utils::StringUtils.force_utf8(snippet)
41
-
30
+ finding.rule_id = rule_id
31
+ set_properties(finding, user_provided_options, call_location)
42
32
  hash = Contrast::Utils::HashDigest.generate_config_hash(finding)
43
33
  finding.hash_code = Contrast::Utils::StringUtils.force_utf8(hash)
44
34
  finding.preflight = Contrast::Utils::PreflightUtil.create_preflight(finding)
@@ -50,6 +40,25 @@ module Contrast
50
40
 
51
41
  private
52
42
 
43
+ # Set the properties needed to report and subsequently render this finding on the finding given.
44
+ #
45
+ # @param finding [Contrast::Api::Dtm::Finding] the configuration finding to populate
46
+ # @param user_provided_options [Hash] the configuration value(s) which
47
+ # violated the rule
48
+ # @param call_location [Thread::Backtrace::Location] the location where
49
+ # the bad configuration was set
50
+ def set_properties finding, user_provided_options, call_location
51
+ path = call_location.path
52
+ # just get the file name, not the full path
53
+ path = path.split(Contrast::Utils::ObjectShare::SLASH).last
54
+ session_id = user_provided_options[:key].to_s if user_provided_options
55
+ finding.properties[CS__SESSION_ID] = Contrast::Utils::StringUtils.force_utf8(session_id)
56
+ finding.properties[CS__PATH] = Contrast::Utils::StringUtils.force_utf8(path)
57
+ file_path = call_location.absolute_path
58
+ snippet = file_snippet(file_path, call_location)
59
+ finding.properties[CS__SNIPPET] = Contrast::Utils::StringUtils.force_utf8(snippet)
60
+ end
61
+
53
62
  def file_snippet file_path, call_location
54
63
  idx = call_location&.lineno
55
64
  if file_path && idx && File.exist?(file_path)
@@ -1,13 +1,13 @@
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
- # rubocop:disable Object/Freeze
4
+ # rubocop:disable Security/Object/Freeze
5
5
  module Contrast
6
6
  module Utils
7
7
  # A utility class where a series of commonly used Strings and other
8
8
  # commonly used objects can be store and frozen to prevent unnecessary
9
9
  # duplication.
10
- class ObjectShare
10
+ module ObjectShare
11
11
  # Strings
12
12
  ASTERISK = '*'
13
13
  BACK_SLASH = '\\'
@@ -76,4 +76,4 @@ module Contrast
76
76
  end
77
77
  end
78
78
  end
79
- # rubocop:enable Object/Freeze
79
+ # rubocop:enable Security/Object/Freeze
@@ -4,7 +4,7 @@
4
4
  module Contrast
5
5
  module Utils
6
6
  # Utility for generating preflight message token
7
- class PreflightUtil
7
+ module PreflightUtil
8
8
  def self.create_preflight finding
9
9
  "#{ finding.rule_id },#{ finding.hash_code }"
10
10
  end
@@ -4,7 +4,7 @@
4
4
  module Contrast
5
5
  module Utils
6
6
  # ResourceLoader can attempt to read a file from a predefined resource directory
7
- class ResourceLoader
7
+ module ResourceLoader
8
8
  RESOURCES = 'resources'
9
9
 
10
10
  # __FILE__/../../../resources
@@ -29,8 +29,8 @@ module Contrast
29
29
 
30
30
  # Generate a SHA256 hash of the combined source code of this Gem
31
31
  def sha256 path
32
- return nil unless path
33
- return nil unless File.exist?(path) && !File.directory?(path)
32
+ return unless path
33
+ return unless File.exist?(path) && !File.directory?(path)
34
34
 
35
35
  @sha256_cache[path] ||= Digest::SHA256.file(path).to_s
36
36
  end
@@ -74,7 +74,7 @@ module Contrast
74
74
  # @return [String] a copy of the given String, upper cased, trimmed,
75
75
  # dashes replaced with underscore, and HTTP trimmed
76
76
  def self.normalized_key str
77
- return nil unless str
77
+ return unless str
78
78
 
79
79
  str = str.to_s
80
80
  @_normalized_keys ||= {}
@@ -19,16 +19,15 @@ module Contrast
19
19
 
20
20
  relationship = tag.compare_range(range.start_idx, range.end_idx)
21
21
  case relationship
22
- when Contrast::Agent::Assess::Tag::BELOW
23
22
  # since the tags are ordered, if we're below, nope out
24
- return false
25
- when Contrast::Agent::Assess::Tag::LOW_SPAN
26
- # if we ever get a low span, that means a low part
27
- # won't be covered. there's no need to continue
28
- return false
29
- when Contrast::Agent::Assess::Tag::WITHOUT
30
- # if we ever get a without, that means a low part won't
31
- # be covered. there's no need to continue
23
+ when Contrast::Agent::Assess::Tag::BELOW,
24
+ # if we ever get a low span, that means a low part
25
+ # won't be covered. there's no need to continue
26
+ Contrast::Agent::Assess::Tag::LOW_SPAN,
27
+ # if we ever get a without, that means a low part won't
28
+ # be covered. there's no need to continue
29
+ Contrast::Agent::Assess::Tag::WITHOUT
30
+
32
31
  return false
33
32
  when Contrast::Agent::Assess::Tag::WITHIN
34
33
  # if we're within, then 0 out this tag since it is
@@ -131,10 +130,7 @@ module Contrast
131
130
  smallered = []
132
131
  curr = nil
133
132
  tags.each do |tag|
134
- if curr.nil?
135
- curr = tag
136
- smallered << curr
137
- elsif tag.start_idx <= curr.end_idx
133
+ if curr && tag.start_idx <= curr.end_idx
138
134
  curr.update_end(tag.end_idx) if tag.end_idx > curr.end_idx
139
135
  else
140
136
  curr = tag
@@ -640,7 +640,7 @@
640
640
  "action": "CUSTOM",
641
641
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Substitution",
642
642
  "patch_method": "gsub_tagger",
643
- "source": "O,P",
643
+ "source": "O,P1",
644
644
  "target": "R"
645
645
  }, {
646
646
  "class_name": "String",
@@ -650,7 +650,7 @@
650
650
  "action": "CUSTOM",
651
651
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Substitution",
652
652
  "patch_method": "gsub_tagger",
653
- "source": "O,P",
653
+ "source": "O,P1",
654
654
  "target": "O"
655
655
  }, {
656
656
  "class_name": "String",
@@ -660,7 +660,7 @@
660
660
  "action": "CUSTOM",
661
661
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Substitution",
662
662
  "patch_method": "sub_tagger",
663
- "source": "O,P",
663
+ "source": "O,P1",
664
664
  "target": "R"
665
665
  }, {
666
666
  "class_name": "String",
@@ -670,7 +670,7 @@
670
670
  "action": "CUSTOM",
671
671
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Substitution",
672
672
  "patch_method": "sub_tagger",
673
- "source": "O,P",
673
+ "source": "O,P1",
674
674
  "target": "O"
675
675
  }, {
676
676
  "class_name": "String",
@@ -680,7 +680,7 @@
680
680
  "action": "CUSTOM",
681
681
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Trim",
682
682
  "patch_method": "tr_tagger",
683
- "source": "O,P",
683
+ "source": "O,P1",
684
684
  "target": "R"
685
685
  }, {
686
686
  "class_name": "String",
@@ -690,7 +690,7 @@
690
690
  "action": "CUSTOM",
691
691
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Trim",
692
692
  "patch_method": "tr_tagger",
693
- "source": "O,P",
693
+ "source": "O,P1",
694
694
  "target": "O"
695
695
  }, {
696
696
  "class_name": "String",
@@ -700,7 +700,7 @@
700
700
  "action": "CUSTOM",
701
701
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Trim",
702
702
  "patch_method": "tr_s_tagger",
703
- "source": "O,P",
703
+ "source": "O,P1",
704
704
  "target": "R"
705
705
  }, {
706
706
  "class_name": "String",
@@ -710,7 +710,7 @@
710
710
  "action": "CUSTOM",
711
711
  "patch_class": "Contrast::Agent::Assess::Policy::Propagator::Trim",
712
712
  "patch_method": "tr_s_tagger",
713
- "source": "O,P",
713
+ "source": "O,P1",
714
714
  "target": "O"
715
715
  }, {
716
716
  "class_name": "String",
@@ -984,7 +984,7 @@
984
984
  "action": "CUSTOM",
985
985
  "patch_class": "Contrast::Extension::Assess::KernelPropagator",
986
986
  "patch_method": "sprintf_tagger",
987
- "source": "O,P",
987
+ "source": "O,P1",
988
988
  "target": "R"
989
989
  }, {
990
990
  "class_name":"ActiveRecord::ConnectionAdapters::Quoting",
@@ -1173,26 +1173,20 @@
1173
1173
  "instance_method": true,
1174
1174
  "method_visibility": "public",
1175
1175
  "method_name":"match",
1176
- "source":"P0",
1177
- "trigger_class": "Contrast::Agent::Assess::Rule::Redos",
1178
- "trigger_method": "regexp_complexity_check"
1176
+ "source":"P0"
1179
1177
 
1180
1178
  }, {
1181
1179
  "class_name":"String",
1182
1180
  "instance_method": true,
1183
1181
  "method_visibility": "public",
1184
1182
  "method_name":"=~",
1185
- "source":"O",
1186
- "trigger_class": "Contrast::Agent::Assess::Rule::Redos",
1187
- "trigger_method": "regexp_complexity_check"
1183
+ "source":"O"
1188
1184
  }, {
1189
1185
  "class_name":"Regexp",
1190
1186
  "instance_method": true,
1191
1187
  "method_visibility": "public",
1192
1188
  "method_name":"=~",
1193
- "source":"P0",
1194
- "trigger_class": "Contrast::Agent::Assess::Rule::Redos",
1195
- "trigger_method": "regexp_complexity_check"
1189
+ "source":"P0"
1196
1190
 
1197
1191
  }
1198
1192
  ]