contrast-agent 3.13.0 → 3.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/exe/contrast_service +1 -7
  3. data/ext/cs__assess_active_record_named/cs__active_record_named.c +8 -7
  4. data/ext/cs__assess_array/cs__assess_array.c +6 -5
  5. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +5 -5
  6. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +2 -1
  7. data/ext/cs__assess_hash/cs__assess_hash.c +18 -17
  8. data/ext/cs__assess_hash/cs__assess_hash.h +2 -1
  9. data/ext/cs__assess_kernel/cs__assess_kernel.c +7 -8
  10. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +18 -16
  11. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +1 -0
  12. data/ext/cs__assess_module/cs__assess_module.c +6 -6
  13. data/ext/cs__assess_regexp/cs__assess_regexp.c +4 -4
  14. data/ext/cs__assess_string/cs__assess_string.c +31 -16
  15. data/ext/cs__assess_string/cs__assess_string.h +6 -1
  16. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +4 -2
  17. data/ext/cs__assess_yield_track/cs__assess_yield_track.c +2 -2
  18. data/ext/cs__common/cs__common.c +48 -39
  19. data/ext/cs__common/cs__common.h +16 -21
  20. data/ext/cs__contrast_patch/cs__contrast_patch.c +27 -25
  21. data/ext/cs__contrast_patch/cs__contrast_patch.h +5 -7
  22. data/ext/cs__protect_kernel/cs__protect_kernel.c +11 -12
  23. data/ext/cs__protect_kernel/cs__protect_kernel.h +2 -2
  24. data/lib/contrast-agent.rb +1 -1
  25. data/lib/contrast.rb +13 -23
  26. data/lib/contrast/agent.rb +39 -46
  27. data/lib/contrast/agent/assess.rb +12 -12
  28. data/lib/contrast/agent/assess/contrast_event.rb +151 -85
  29. data/lib/contrast/agent/assess/events/event_factory.rb +2 -2
  30. data/lib/contrast/agent/assess/events/source_event.rb +3 -3
  31. data/lib/contrast/agent/assess/finalizers/freeze.rb +15 -0
  32. data/lib/contrast/agent/assess/finalizers/hash.rb +97 -0
  33. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +11 -4
  34. data/lib/contrast/agent/assess/policy/patcher.rb +6 -6
  35. data/lib/contrast/agent/assess/policy/policy.rb +9 -11
  36. data/lib/contrast/agent/assess/policy/policy_node.rb +17 -12
  37. data/lib/contrast/agent/assess/policy/policy_scanner.rb +9 -4
  38. data/lib/contrast/agent/assess/policy/preshift.rb +13 -7
  39. data/lib/contrast/agent/assess/policy/propagation_method.rb +64 -44
  40. data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -2
  41. data/lib/contrast/agent/assess/policy/propagator.rb +18 -18
  42. data/lib/contrast/agent/assess/policy/propagator/append.rb +8 -5
  43. data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
  44. data/lib/contrast/agent/assess/policy/propagator/center.rb +9 -5
  45. data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
  46. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +6 -4
  47. data/lib/contrast/agent/assess/policy/propagator/insert.rb +7 -4
  48. data/lib/contrast/agent/assess/policy/propagator/keep.rb +4 -1
  49. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +7 -9
  50. data/lib/contrast/agent/assess/policy/propagator/next.rb +7 -5
  51. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +13 -5
  52. data/lib/contrast/agent/assess/policy/propagator/remove.rb +8 -4
  53. data/lib/contrast/agent/assess/policy/propagator/replace.rb +5 -2
  54. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +7 -5
  55. data/lib/contrast/agent/assess/policy/propagator/select.rb +13 -7
  56. data/lib/contrast/agent/assess/policy/propagator/splat.rb +10 -9
  57. data/lib/contrast/agent/assess/policy/propagator/split.rb +27 -22
  58. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +52 -35
  59. data/lib/contrast/agent/assess/policy/propagator/trim.rb +11 -5
  60. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +5 -5
  61. data/lib/contrast/agent/assess/policy/source_method.rb +90 -72
  62. data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +1 -1
  63. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -1
  64. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +16 -12
  65. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +2 -2
  66. data/lib/contrast/agent/assess/policy/trigger_method.rb +81 -33
  67. data/lib/contrast/agent/assess/policy/trigger_node.rb +41 -46
  68. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -1
  69. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +2 -2
  70. data/lib/contrast/agent/assess/properties.rb +15 -5
  71. data/lib/contrast/agent/assess/property/evented.rb +7 -20
  72. data/lib/contrast/agent/assess/property/tagged.rb +13 -7
  73. data/lib/contrast/agent/assess/property/updated.rb +131 -0
  74. data/lib/contrast/agent/assess/rule.rb +2 -2
  75. data/lib/contrast/agent/assess/rule/base.rb +3 -4
  76. data/lib/contrast/agent/assess/rule/provider.rb +3 -3
  77. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +58 -5
  78. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +24 -9
  79. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +84 -16
  80. data/lib/contrast/agent/assess/tag.rb +1 -1
  81. data/lib/contrast/agent/assess/tracker.rb +66 -0
  82. data/lib/contrast/agent/at_exit_hook.rb +6 -6
  83. data/lib/contrast/agent/class_reopener.rb +14 -11
  84. data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +1 -1
  85. data/lib/contrast/agent/deadzone/policy/policy.rb +2 -2
  86. data/lib/contrast/agent/disable_reaction.rb +1 -1
  87. data/lib/contrast/agent/exclusion_matcher.rb +1 -1
  88. data/lib/contrast/agent/inventory/policy/datastores.rb +2 -2
  89. data/lib/contrast/agent/inventory/policy/policy.rb +3 -3
  90. data/lib/contrast/agent/inventory/policy/trigger_node.rb +1 -1
  91. data/lib/contrast/agent/middleware.rb +32 -32
  92. data/lib/contrast/agent/patching/policy/after_load_patch.rb +9 -9
  93. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +23 -22
  94. data/lib/contrast/agent/patching/policy/module_policy.rb +11 -11
  95. data/lib/contrast/agent/patching/policy/patch.rb +15 -15
  96. data/lib/contrast/agent/patching/policy/patcher.rb +43 -44
  97. data/lib/contrast/agent/patching/policy/policy.rb +23 -12
  98. data/lib/contrast/agent/patching/policy/policy_node.rb +1 -1
  99. data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -2
  100. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +6 -8
  101. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +2 -2
  102. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +2 -2
  103. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +3 -3
  104. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +2 -2
  105. data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +4 -4
  106. data/lib/contrast/agent/protect/policy/policy.rb +8 -8
  107. data/lib/contrast/agent/protect/policy/rule_applicator.rb +1 -1
  108. data/lib/contrast/agent/protect/policy/trigger_node.rb +1 -1
  109. data/lib/contrast/agent/protect/rule.rb +18 -18
  110. data/lib/contrast/agent/protect/rule/base.rb +4 -3
  111. data/lib/contrast/agent/protect/rule/base_service.rb +1 -1
  112. data/lib/contrast/agent/protect/rule/cmd_injection.rb +5 -5
  113. data/lib/contrast/agent/protect/rule/deserialization.rb +1 -1
  114. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +1 -1
  115. data/lib/contrast/agent/protect/rule/no_sqli.rb +1 -1
  116. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -0
  117. data/lib/contrast/agent/protect/rule/path_traversal.rb +4 -5
  118. data/lib/contrast/agent/protect/rule/sqli.rb +2 -2
  119. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
  120. data/lib/contrast/agent/protect/rule/xss.rb +1 -1
  121. data/lib/contrast/agent/protect/rule/xxe.rb +3 -5
  122. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +2 -2
  123. data/lib/contrast/agent/railtie.rb +1 -1
  124. data/lib/contrast/agent/reaction_processor.rb +2 -2
  125. data/lib/contrast/agent/request.rb +45 -43
  126. data/lib/contrast/agent/request_context.rb +10 -6
  127. data/lib/contrast/agent/response.rb +23 -12
  128. data/lib/contrast/agent/rewriter.rb +6 -9
  129. data/lib/contrast/agent/service_heartbeat.rb +2 -2
  130. data/lib/contrast/agent/static_analysis.rb +9 -9
  131. data/lib/contrast/agent/thread.rb +1 -1
  132. data/lib/contrast/agent/thread_watcher.rb +2 -2
  133. data/lib/contrast/agent/tracepoint_hook.rb +1 -1
  134. data/lib/contrast/agent/version.rb +1 -1
  135. data/lib/contrast/api.rb +4 -4
  136. data/lib/contrast/api/communication.rb +9 -9
  137. data/lib/contrast/api/communication/messaging_queue.rb +3 -6
  138. data/lib/contrast/api/communication/response_processor.rb +1 -1
  139. data/lib/contrast/api/communication/socket_client.rb +41 -6
  140. data/lib/contrast/api/communication/speedracer.rb +1 -1
  141. data/lib/contrast/api/communication/tcp_socket.rb +1 -1
  142. data/lib/contrast/api/communication/unix_socket.rb +1 -1
  143. data/lib/contrast/api/decorators.rb +14 -14
  144. data/lib/contrast/api/decorators/address.rb +20 -19
  145. data/lib/contrast/api/decorators/application_settings.rb +3 -2
  146. data/lib/contrast/api/decorators/application_update.rb +7 -8
  147. data/lib/contrast/api/decorators/http_request.rb +13 -12
  148. data/lib/contrast/api/decorators/input_analysis.rb +3 -2
  149. data/lib/contrast/api/decorators/message.rb +4 -2
  150. data/lib/contrast/api/decorators/rasp_rule_sample.rb +2 -1
  151. data/lib/contrast/api/decorators/route_coverage.rb +3 -2
  152. data/lib/contrast/api/decorators/server_features.rb +3 -2
  153. data/lib/contrast/api/decorators/trace_event.rb +28 -25
  154. data/lib/contrast/api/decorators/trace_event_object.rb +6 -5
  155. data/lib/contrast/api/decorators/trace_event_signature.rb +5 -4
  156. data/lib/contrast/api/decorators/trace_taint_range.rb +4 -3
  157. data/lib/contrast/api/decorators/user_input.rb +4 -4
  158. data/lib/contrast/common_agent_configuration.rb +2 -2
  159. data/lib/contrast/components/agent.rb +2 -2
  160. data/lib/contrast/components/app_context.rb +50 -39
  161. data/lib/contrast/components/config.rb +7 -17
  162. data/lib/contrast/components/contrast_service.rb +10 -10
  163. data/lib/contrast/components/interface.rb +15 -15
  164. data/lib/contrast/components/logger.rb +1 -1
  165. data/lib/contrast/components/scope.rb +3 -3
  166. data/lib/contrast/components/settings.rb +20 -23
  167. data/lib/contrast/config.rb +18 -18
  168. data/lib/contrast/config/application_configuration.rb +5 -2
  169. data/lib/contrast/config/base_configuration.rb +2 -2
  170. data/lib/contrast/config/protect_rule_configuration.rb +1 -1
  171. data/lib/contrast/config/service_configuration.rb +8 -0
  172. data/lib/contrast/configuration.rb +93 -52
  173. data/lib/contrast/extension/assess.rb +21 -22
  174. data/lib/contrast/extension/assess/array.rb +18 -11
  175. data/lib/contrast/extension/assess/erb.rb +11 -3
  176. data/lib/contrast/extension/assess/eval_trigger.rb +7 -7
  177. data/lib/contrast/extension/assess/exec_trigger.rb +2 -2
  178. data/lib/contrast/extension/assess/fiber.rb +14 -14
  179. data/lib/contrast/extension/assess/hash.rb +7 -6
  180. data/lib/contrast/extension/assess/kernel.rb +34 -28
  181. data/lib/contrast/extension/assess/marshal.rb +67 -0
  182. data/lib/contrast/extension/assess/regexp.rb +10 -9
  183. data/lib/contrast/extension/assess/string.rb +23 -23
  184. data/lib/contrast/extension/inventory.rb +4 -4
  185. data/lib/contrast/extension/kernel.rb +1 -1
  186. data/lib/contrast/extension/module.rb +1 -1
  187. data/lib/contrast/extension/protect.rb +3 -3
  188. data/lib/contrast/extension/protect/kernel.rb +4 -4
  189. data/lib/contrast/extension/protect/psych.rb +2 -2
  190. data/lib/contrast/framework/base_support.rb +1 -1
  191. data/lib/contrast/framework/manager.rb +10 -11
  192. data/lib/contrast/framework/rack/patch/session_cookie.rb +22 -28
  193. data/lib/contrast/framework/rack/patch/support.rb +1 -1
  194. data/lib/contrast/framework/rack/support.rb +2 -2
  195. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +13 -13
  196. data/lib/contrast/framework/rails/patch/assess_configuration.rb +6 -12
  197. data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +11 -11
  198. data/lib/contrast/framework/rails/patch/support.rb +4 -4
  199. data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +11 -11
  200. data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +12 -12
  201. data/lib/contrast/framework/rails/rewrite/active_record_named.rb +4 -4
  202. data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +12 -12
  203. data/lib/contrast/framework/rails/support.rb +64 -14
  204. data/lib/contrast/framework/sinatra/patch/base.rb +12 -12
  205. data/lib/contrast/framework/sinatra/patch/support.rb +1 -1
  206. data/lib/contrast/framework/sinatra/support.rb +6 -6
  207. data/lib/contrast/funchook/funchook.rb +1 -1
  208. data/lib/contrast/logger/application.rb +13 -5
  209. data/lib/contrast/logger/format.rb +22 -9
  210. data/lib/contrast/logger/log.rb +17 -10
  211. data/lib/contrast/logger/request.rb +30 -0
  212. data/lib/contrast/tasks/config.rb +1 -1
  213. data/lib/contrast/tasks/service.rb +2 -2
  214. data/lib/contrast/utils/assess/sampling_util.rb +2 -2
  215. data/lib/contrast/utils/assess/tracking_util.rb +49 -4
  216. data/lib/contrast/utils/boolean_util.rb +1 -1
  217. data/lib/contrast/utils/class_util.rb +2 -2
  218. data/lib/contrast/utils/duck_utils.rb +0 -10
  219. data/lib/contrast/utils/env_configuration_item.rb +2 -1
  220. data/lib/contrast/utils/gemfile_reader.rb +5 -5
  221. data/lib/contrast/utils/hash_digest.rb +2 -1
  222. data/lib/contrast/utils/heap_dump_util.rb +2 -2
  223. data/lib/contrast/utils/invalid_configuration_util.rb +21 -22
  224. data/lib/contrast/utils/inventory_util.rb +4 -4
  225. data/lib/contrast/utils/io_util.rb +1 -1
  226. data/lib/contrast/utils/os.rb +1 -1
  227. data/lib/contrast/utils/ruby_ast_rewriter.rb +1 -1
  228. data/lib/contrast/utils/sha256_builder.rb +2 -2
  229. data/lib/contrast/utils/stack_trace_utils.rb +2 -2
  230. data/lib/contrast/utils/string_utils.rb +11 -6
  231. data/resources/assess/policy.json +31 -22
  232. data/resources/deadzone/policy.json +5 -0
  233. data/ruby-agent.gemspec +21 -19
  234. data/service_executables/VERSION +1 -1
  235. data/service_executables/linux/contrast-service +0 -0
  236. data/service_executables/mac/contrast-service +0 -0
  237. metadata +67 -29
  238. data/lib/contrast/agent/assess/insulator.rb +0 -49
  239. data/lib/contrast/agent/require_state.rb +0 -61
  240. data/lib/contrast/extension/assess/assess_extension.rb +0 -147
  241. data/lib/contrast/utils/freeze_util.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64a4e6fe5f8f75e8ab4bb911e696330a10e1a3edb95c027a03dd0b8704e23f3e
4
- data.tar.gz: f031d456741cb0d955030805efd73f8cb2495ca7c927a15121c5ef88a6d86ec7
3
+ metadata.gz: c2172066d6736b55c6754bb6913ec9fb9962ac1b818a85b4faa7ef822bb5df97
4
+ data.tar.gz: 209286f4ef6ce8b688e3849a502ece6cfc914f795fae25b5cb417b3fa3998b50
5
5
  SHA512:
6
- metadata.gz: e2fac539c17b2cb20ab407f6ded931316f97529073907a3f03ee7ef8774a2e18a597d5c47406e44cb86111338e7d31170399543a1778bb7154eaf618b4e03635
7
- data.tar.gz: 44e2552f7ee995f73514c62b10002096fcf8f462bdbc573cceb623f9a42786c2421d16490962a9575d777a792fd9ea459d41630e2de9cf60e55c61ecc0fb8403
6
+ metadata.gz: e6c19a309c1d7c7e2600d2f90d5da2664c315550be00475720165dde741d821d3ceb391282831aeb8ddcbe8e86b50b48d741d5c63d85c7a92c38ef0e54b7b0cd
7
+ data.tar.gz: f4c1a92e5272730285b467c63768e31b1d6d7cb4266cbd6133c6de312603fcabc9c3bc814bc7f20d48fa444651fb040713ed1438b70076e9be9be396dab6603b
@@ -3,19 +3,13 @@
3
3
  # frozen_string_literal: true
4
4
 
5
5
  def mac?
6
- RUBY_PLATFORM.match?(/darwin/)
7
- end
8
-
9
- def windows?
10
- RUBY_PLATFORM.match?(/cygwin|mswin|mingw|bccwin|wince|emx/)
6
+ RUBY_PLATFORM.include?('darwin')
11
7
  end
12
8
 
13
9
  def path
14
10
  base_path = "#{ File.dirname(__FILE__) }/.."
15
11
  if mac?
16
12
  "#{ base_path }/service_executables/mac/contrast-service"
17
- elsif windows?
18
- "#{ base_path }/service_executables/windows/contrast-service.exe"
19
13
  else
20
14
  "#{ base_path }/service_executables/linux/contrast-service"
21
15
  end
@@ -2,8 +2,8 @@
2
2
  * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
3
 
4
4
  #include "cs__active_record_named.h"
5
- #include <ruby.h>
6
5
  #include "../cs__common/cs__common.h"
6
+ #include <ruby.h>
7
7
 
8
8
  VALUE contrast_assess_active_record_scope(const int argc, const VALUE *argv,
9
9
  const VALUE self) {
@@ -19,7 +19,8 @@ VALUE contrast_assess_active_record_scope(const int argc, const VALUE *argv,
19
19
  */
20
20
  VALUE new_body, ret;
21
21
  VALUE new_args[3];
22
- new_body = rb_funcall(active_record_named, rb_sym_assess_rewrite, 3, self, argv[0], argv[1]);
22
+ new_body = rb_funcall(active_record_named, rb_sym_assess_rewrite, 3, self,
23
+ argv[0], argv[1]);
23
24
  new_args[0] = argv[0];
24
25
  if (NIL_P(new_body)) {
25
26
  new_args[1] = argv[1];
@@ -36,10 +37,10 @@ void Init_cs__assess_active_record_named(void) {
36
37
  framework = rb_define_module_under(contrast, "Framework");
37
38
  rails = rb_define_module_under(framework, "Rails");
38
39
  rewrite = rb_define_module_under(rails, "Rewrite");
39
- active_record_named = rb_define_class_under(rewrite, "ActiveRecordNamed", rb_cObject);
40
+ active_record_named =
41
+ rb_define_class_under(rewrite, "ActiveRecordNamed", rb_cObject);
40
42
  rb_sym_assess_rewrite = rb_intern("rewrite");
41
- rb_sym_assess_scope = contrast_register_patch("ActiveRecord::Scoping::Named::ClassMethods",
42
- "scope",
43
- contrast_assess_active_record_scope);
43
+ rb_sym_assess_scope =
44
+ contrast_register_patch("ActiveRecord::Scoping::Named::ClassMethods",
45
+ "scope", contrast_assess_active_record_scope);
44
46
  }
45
-
@@ -23,15 +23,16 @@ static VALUE contrast_assess_array_join(const int argc, const VALUE *argv,
23
23
  /* Finally, default to empty String. Implicit since nil.to_s is ''*/
24
24
 
25
25
  result = rb_funcall2(ary, rb_sym_assess_array_join, argc, argv);
26
- result = rb_funcall(array_propagator, rb_sym_assess_track_array_join, 3, ary, sep, result);
26
+ result = rb_funcall(array_propagator, rb_sym_assess_track_array_join, 3,
27
+ ary, sep, result);
27
28
 
28
29
  return result;
29
30
  }
30
31
 
31
32
  void Init_cs__assess_array(void) {
32
- array_propagator = rb_define_class_under(core_assess, "ArrayPropagator", rb_cObject);
33
+ array_propagator =
34
+ rb_define_class_under(core_assess, "ArrayPropagator", rb_cObject);
33
35
  rb_sym_assess_track_array_join = rb_intern("cs__track_join");
34
- rb_sym_assess_array_join = contrast_register_patch("Array",
35
- "join",
36
- contrast_assess_array_join);
36
+ rb_sym_assess_array_join =
37
+ contrast_register_patch("Array", "join", contrast_assess_array_join);
37
38
  }
@@ -7,7 +7,8 @@
7
7
 
8
8
  void contrast_assess_instance_eval_trigger_check(VALUE self, VALUE source,
9
9
  VALUE ret) {
10
- rb_funcall(basic_eval_trigger, instance_trigger_check_method, 3, self, source, ret);
10
+ rb_funcall(basic_eval_trigger, instance_trigger_check_method, 3, self,
11
+ source, ret);
11
12
  }
12
13
 
13
14
  VALUE
@@ -36,7 +37,8 @@ contrast_assess_basic_object_instance_eval(const int argc, const VALUE *argv,
36
37
  }
37
38
 
38
39
  void Init_cs__assess_basic_object(void) {
39
- basic_eval_trigger = rb_define_class_under(core_assess, "EvalTrigger", rb_cObject);
40
+ basic_eval_trigger =
41
+ rb_define_class_under(core_assess, "EvalTrigger", rb_cObject);
40
42
  instance_trigger_check_method = rb_intern("instance_eval_trigger_check");
41
43
 
42
44
  /* We don't keep a reference to the underlying method.
@@ -45,8 +47,6 @@ void Init_cs__assess_basic_object(void) {
45
47
  * but if someone else patched BasicObject#instance_eval,
46
48
  * IDK if this is intentional... noting it. -ajm
47
49
  */
48
- contrast_register_patch("BasicObject",
49
- "instance_eval",
50
+ contrast_register_patch("BasicObject", "instance_eval",
50
51
  contrast_assess_basic_object_instance_eval);
51
-
52
52
  }
@@ -73,7 +73,8 @@ int install_fiber_hooks() {
73
73
  }
74
74
 
75
75
  void Init_cs__assess_fiber_track(void) {
76
- fiber_propagator = rb_define_class_under(core_assess, "FiberPropagator", rb_cObject);
76
+ fiber_propagator =
77
+ rb_define_class_under(core_assess, "FiberPropagator", rb_cObject);
77
78
  track_rb_fiber_new = rb_intern("track_rb_fiber_new");
78
79
  track_rb_fiber_yield = rb_intern("track_rb_fiber_yield");
79
80
  rb_sym_next = rb_intern("next");
@@ -12,23 +12,24 @@
12
12
  * This method instruments that unique bracket-construction style
13
13
  * of initializing a hash.
14
14
  */
15
- static VALUE contrast_assess_hash_bracket_constructor(const int argc, VALUE *argv,
16
- const VALUE hash) {
15
+ static VALUE contrast_assess_hash_bracket_constructor(const int argc,
16
+ VALUE *argv,
17
+ const VALUE hash) {
17
18
  VALUE result;
18
19
 
19
20
  /* Array of Arrays: Hash[ [ [key, value], ... ] ] -> new_hash */
20
21
  if (RB_TYPE_P(argv[0], T_ARRAY)) {
21
22
  int i;
22
23
  for (i = 0; i < argc; i++) {
23
- argv[i] =
24
- rb_funcall(hash_propagator, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
24
+ argv[i] = rb_funcall(hash_propagator,
25
+ rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
25
26
  }
26
27
  /* Hash[ key, value, ... ] -> new_hash */
27
28
  } else if (argc > 1) {
28
29
  int i;
29
30
  for (i = 0; i < argc; i += 2) {
30
- argv[i] =
31
- rb_funcall(hash_propagator, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
31
+ argv[i] = rb_funcall(hash_propagator,
32
+ rb_sym_assess_hash_dup_and_freeze, 1, argv[i]);
32
33
  }
33
34
  }
34
35
 
@@ -36,7 +37,8 @@ static VALUE contrast_assess_hash_bracket_constructor(const int argc, VALUE *arg
36
37
  * String keys
37
38
  * # Hash[ object ] -> new_hash
38
39
  */
39
- result = rb_funcall2(hash, rb_sym_assess_hash_bracket_constructor, argc, argv);
40
+ result =
41
+ rb_funcall2(hash, rb_sym_assess_hash_bracket_constructor, argc, argv);
40
42
 
41
43
  return result;
42
44
  }
@@ -61,8 +63,9 @@ static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv,
61
63
  * We haven't revisited this approach since we started more extensively
62
64
  * hooking public C functions.)
63
65
  */
64
- if(argc > 0) {
65
- argv[0] = rb_funcall(hash_propagator, rb_sym_assess_hash_dup_and_freeze, 1, argv[0]);
66
+ if (argc > 0) {
67
+ argv[0] = rb_funcall(hash_propagator, rb_sym_assess_hash_dup_and_freeze,
68
+ 1, argv[0]);
66
69
  }
67
70
  /* This is the underlying assignment, w/ our instrumented key. */
68
71
  result = rb_funcall2(hash, rb_sym_assess_hash_bracket_equals, argc, argv);
@@ -71,17 +74,15 @@ static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv,
71
74
  }
72
75
 
73
76
  void Init_cs__assess_hash(void) {
74
- hash_propagator = rb_define_class_under(core_assess, "HashPropagator", rb_cObject);
77
+ hash_propagator =
78
+ rb_define_class_under(core_assess, "HashPropagator", rb_cObject);
75
79
  rb_sym_assess_hash_dup_and_freeze = rb_intern("cs__duplicate_and_freeze");
76
80
 
77
81
  VALUE hash_class = rb_define_class("Hash", rb_cObject);
78
82
 
79
- rb_sym_assess_hash_bracket_constructor = contrast_register_singleton_patch("Hash",
80
- "[]",
81
- contrast_assess_hash_bracket_constructor);
82
-
83
- rb_sym_assess_hash_bracket_equals = contrast_register_patch("Hash",
84
- "[]=",
85
- contrast_assess_hash_bracket_set);
83
+ rb_sym_assess_hash_bracket_constructor = contrast_register_singleton_patch(
84
+ "Hash", "[]", contrast_assess_hash_bracket_constructor);
86
85
 
86
+ rb_sym_assess_hash_bracket_equals = contrast_register_patch(
87
+ "Hash", "[]=", contrast_assess_hash_bracket_set);
87
88
  }
@@ -13,7 +13,8 @@ static VALUE hash_propagator;
13
13
  * ahead of time should avoid this, similar to the behavior of the -@ Strings
14
14
  * -HM
15
15
  */
16
- static VALUE contrast_assess_hash_bracket_constructor(const int argc, VALUE *argv,
16
+ static VALUE contrast_assess_hash_bracket_constructor(const int argc,
17
+ VALUE *argv,
17
18
  const VALUE hash);
18
19
 
19
20
  static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv,
@@ -18,8 +18,9 @@ contrast_patched_kernel_exec(const int argc, const VALUE *argv,
18
18
  rb_funcall(contrast_patcher(), rb_sym_exit_scope, 0);
19
19
  }
20
20
 
21
- /* maybe this should be rb_funcall2. this works right now because *argv == argv[0].
22
- * exec shouldn't ever be called with != 1 argc, so not a huge problem */
21
+ /* maybe this should be rb_funcall2. this works right now because *argv ==
22
+ * argv[0]. exec shouldn't ever be called with != 1 argc, so not a huge
23
+ * problem */
23
24
  return rb_funcall(self, rb_sym_assess_kernel_exec, argc, *argv);
24
25
  }
25
26
 
@@ -27,12 +28,10 @@ void Init_cs__assess_kernel(void) {
27
28
  kernel_propagator = rb_define_module_under(core_assess, "KernelPropagator");
28
29
  exec_apply_trigger = rb_intern("apply_trigger");
29
30
 
30
- rb_sym_assess_kernel_exec = contrast_register_patch("Kernel",
31
- "exec",
32
- contrast_patched_kernel_exec);
31
+ rb_sym_assess_kernel_exec =
32
+ contrast_register_patch("Kernel", "exec", contrast_patched_kernel_exec);
33
33
 
34
34
  /* should return the same value as above */
35
- rb_sym_assess_kernel_exec = contrast_register_singleton_patch("Kernel",
36
- "exec",
37
- contrast_patched_kernel_exec);
35
+ rb_sym_assess_kernel_exec = contrast_register_singleton_patch(
36
+ "Kernel", "exec", contrast_patched_kernel_exec);
38
37
  }
@@ -9,26 +9,24 @@ static VALUE contrast_assess_marshal_module_load(const int argc,
9
9
  const VALUE *argv) {
10
10
  VALUE result;
11
11
  VALUE source_string;
12
-
13
12
  result = rb_call_super(argc, argv);
14
13
 
15
14
  if (argc >= 1) {
16
15
  source_string = argv[0];
17
16
 
18
- if (rb_respond_to(source_string, rb_sym_cs_tracked)) {
19
- VALUE tracked = rb_funcall(source_string, rb_sym_cs_tracked, 0);
17
+ VALUE tracked =
18
+ rb_funcall(properties_hash, rb_sym_hash_tracked, 1, source_string);
20
19
 
21
- if (tracked == Qtrue) {
22
- VALUE skip = rb_funcall(contrast_patcher(),
23
- rb_sym_skip_assess_analysis, 0);
20
+ if (tracked == Qtrue) {
21
+ VALUE skip =
22
+ rb_funcall(contrast_patcher(), rb_sym_skip_assess_analysis, 0);
24
23
 
25
- if (skip == Qfalse) {
26
- VALUE scope =
27
- rb_funcall(contrast_patcher(), rb_sym_enter_scope, 0);
28
- rb_funcall(marshal_module, rb_sym_assess_load_trigger_check,
29
- 2, source_string, result);
30
- rb_funcall(contrast_patcher(), rb_sym_exit_scope, 1, scope);
31
- }
24
+ if (skip == Qfalse) {
25
+ VALUE scope =
26
+ rb_funcall(contrast_patcher(), rb_sym_enter_scope, 0);
27
+ rb_funcall(marshal_module, rb_sym_assess_load_trigger_check, 2,
28
+ source_string, result);
29
+ rb_funcall(contrast_patcher(), rb_sym_exit_scope, 0);
32
30
  }
33
31
  }
34
32
  }
@@ -36,9 +34,13 @@ static VALUE contrast_assess_marshal_module_load(const int argc,
36
34
  }
37
35
 
38
36
  void Init_cs__assess_marshal_module(void) {
37
+ // Contrast::Agent::Assess::Tracker::PROPERTIES_HASH
38
+ VALUE tracker = rb_define_class_under(assess, "Tracker", rb_cObject);
39
+ properties_hash = rb_const_get(tracker, rb_intern("PROPERTIES_HASH"));
40
+ marshal_module =
41
+ rb_define_class_under(core_assess, "MarshalPropagator", rb_cObject);
39
42
  rb_sym_assess_load_trigger_check = rb_intern("cs__load_trigger_check");
40
43
 
41
- contrast_register_singleton_prepend_patch("Marshal",
42
- "load",
43
- &contrast_assess_marshal_module_load);
44
+ contrast_register_singleton_prepend_patch(
45
+ "Marshal", "load", &contrast_assess_marshal_module_load);
44
46
  }
@@ -3,6 +3,7 @@
3
3
  static VALUE marshal_module;
4
4
 
5
5
  static VALUE rb_sym_assess_load_trigger_check;
6
+ static VALUE properties_hash;
6
7
 
7
8
  /*
8
9
  * Rails is a jerk. In Rails 5, they decided to do away with the alias chaining
@@ -21,7 +21,8 @@ void contrast_assess_eval_trigger_check(VALUE module, VALUE source, VALUE ret) {
21
21
  /* If this method ever throws an exception, the scope-leave
22
22
  * needs to be moved within a rescue call.
23
23
  */
24
- rb_funcall(module_eval_trigger, trigger_check_method, 4, module, source, ret, method);
24
+ rb_funcall(module_eval_trigger, trigger_check_method, 4, module, source,
25
+ ret, method);
25
26
  }
26
27
 
27
28
  rb_funcall(contrast_patcher(), rb_sym_exit_scope, 0);
@@ -57,7 +58,8 @@ contrast_assess_module_module_eval(const int argc, const VALUE *argv,
57
58
  }
58
59
 
59
60
  void Init_cs__assess_module(void) {
60
- module_eval_trigger = rb_define_class_under(core_assess, "EvalTrigger", rb_cObject);
61
+ module_eval_trigger =
62
+ rb_define_class_under(core_assess, "EvalTrigger", rb_cObject);
61
63
  trigger_check_method = rb_intern("eval_trigger_check");
62
64
 
63
65
  rb_sym_assess_patch_eval = rb_intern("patch_assess_on_eval");
@@ -69,11 +71,9 @@ void Init_cs__assess_module(void) {
69
71
  * See similar comments in basic_object C ext patch.
70
72
  */
71
73
 
72
- contrast_register_patch("Module",
73
- "class_eval",
74
+ contrast_register_patch("Module", "class_eval",
74
75
  contrast_assess_module_class_eval);
75
76
 
76
- contrast_register_patch("Module",
77
- "module_eval",
77
+ contrast_register_patch("Module", "module_eval",
78
78
  contrast_assess_module_module_eval);
79
79
  }
@@ -29,7 +29,8 @@ static VALUE contrast_assess_regexp_equal_squiggle(const int argc,
29
29
  }
30
30
 
31
31
  void Init_cs__assess_regexp(void) {
32
- regexp_propagator = rb_define_class_under(core_assess, "RegexpPropagator", rb_cObject);
32
+ regexp_propagator =
33
+ rb_define_class_under(core_assess, "RegexpPropagator", rb_cObject);
33
34
  rb_sym_assess_track_regexp = rb_intern("track_equal_squiggle");
34
35
 
35
36
  /* These are the keys we use to define our hash of
@@ -46,7 +47,6 @@ void Init_cs__assess_regexp(void) {
46
47
  rb_sym_back_ref = ID2SYM(rb_intern("back_ref"));
47
48
  rb_global_variable(&rb_sym_back_ref);
48
49
 
49
- rb_sym_assess_regexp_equal_squiggle = contrast_register_patch("Regexp",
50
- "=~",
51
- contrast_assess_regexp_equal_squiggle);
50
+ rb_sym_assess_regexp_equal_squiggle = contrast_register_patch(
51
+ "Regexp", "=~", contrast_assess_regexp_equal_squiggle);
52
52
  }
@@ -5,21 +5,31 @@
5
5
  #include "../cs__common/cs__common.h"
6
6
  #include <ruby.h>
7
7
 
8
+ static VALUE contrast_assess_string_freeze(const int argc, VALUE *argv,
9
+ const VALUE obj) {
10
+ if (!OBJ_FROZEN(obj)) {
11
+ rb_funcall(properties_hash, rb_sym_pre_freeze, 1, obj);
12
+ }
13
+ return rb_funcall(obj, rb_sym_assess_string_freeze, 0);
14
+ }
15
+
8
16
  static VALUE contrast_assess_string_uminus(const int argc, VALUE *argv,
9
- const VALUE obj) {
10
- VALUE dup, tracked;
17
+ const VALUE obj) {
11
18
  if (!OBJ_FROZEN(obj)) {
12
- tracked = rb_funcall(obj, rb_sym_cs_tracked, 0);
13
- if (RTEST(tracked)) {
14
- /*
15
- * If the object is not frozen and the object is tracked, we cheat.
16
- * We dup and then freeze to replicate the behavior of str_uminus in
17
- * string.c, but we ignore any other monkey patches on String#-@
18
- */
19
- dup = rb_funcall(obj, rb_sym_dup, 0);
20
- rb_funcall(dup, rb_sym_freeze, 0);
21
- return dup;
22
- }
19
+ /* We're doing something intentionally different here. Ruby, for -@,
20
+ * attempts to de-duplicate the String and use an "interned" copy of
21
+ * the String. We cannot allow that to happen for a couple reasons:
22
+ * - prior to Ruby 2.7, this would cause us to track ALL instances of
23
+ * that interned copy.
24
+ * - 2.7 and later, this action is actually missed because of a change
25
+ * to the str_uminus method in Ruby, which dups the String in a way
26
+ * that we cannot see.
27
+ * B/c we cannot track this in 2.7, rather than having a version check
28
+ * and two approaches, we'll instead directly call the #freeze method,
29
+ * so the end result is that this String itself is frozen and never
30
+ * deduplicated.
31
+ */
32
+ return contrast_assess_string_freeze(argc, argv, obj);
23
33
  }
24
34
  /* in all other cases, preserve monkey patching and c call */
25
35
  return rb_funcall(obj, rb_sym_assess_string_uminus, 0);
@@ -28,8 +38,13 @@ static VALUE contrast_assess_string_uminus(const int argc, VALUE *argv,
28
38
  void Init_cs__assess_string(void) {
29
39
  rb_sym_dup = rb_intern("dup");
30
40
  rb_sym_freeze = rb_intern("freeze");
41
+ rb_sym_pre_freeze = rb_intern("pre_freeze");
42
+ // Contrast::Agent::Assess::Tracker::PROPERTIES_HASH
43
+ VALUE tracker = rb_define_class_under(assess, "Tracker", rb_cObject);
44
+ properties_hash = rb_const_get(tracker, rb_intern("PROPERTIES_HASH"));
31
45
 
32
- rb_sym_assess_string_uminus = contrast_register_patch("String",
33
- "-@",
34
- &contrast_assess_string_uminus);
46
+ rb_sym_assess_string_uminus =
47
+ contrast_register_patch("String", "-@", &contrast_assess_string_uminus);
48
+ rb_sym_assess_string_freeze = contrast_register_patch(
49
+ "String", "freeze", &contrast_assess_string_freeze);
35
50
  }
@@ -1,8 +1,13 @@
1
1
  #include <ruby.h>
2
2
 
3
3
  static VALUE rb_sym_assess_string_uminus;
4
+ static VALUE rb_sym_assess_string_freeze;
5
+ // Contrast::Agent::Assess::Tracker::PROPERTIES_HASH
6
+ static VALUE properties_hash;
4
7
  static VALUE rb_sym_dup;
5
8
  static VALUE rb_sym_freeze;
9
+ static VALUE rb_sym_pre_freeze;
10
+ static VALUE properties_hash;
6
11
 
7
12
  /*
8
13
  * The String#-@ method calls to the str_uminus method in String.C. This method
@@ -15,6 +20,6 @@ static VALUE rb_sym_freeze;
15
20
  * -HM
16
21
  */
17
22
  static VALUE contrast_assess_string_uminus(const int argc, VALUE *argv,
18
- const VALUE obj);
23
+ const VALUE obj);
19
24
 
20
25
  void Init_cs__assess_string(void);