contrast-agent 3.12.2 → 3.13.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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +0 -1
  3. data/.gitignore +1 -1
  4. data/.simplecov +1 -1
  5. data/Rakefile +31 -0
  6. data/ext/build_funchook.rb +0 -2
  7. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +2 -8
  8. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +0 -1
  9. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +1 -6
  10. data/ext/cs__assess_yield_track/cs__assess_yield_track.c +1 -5
  11. data/ext/cs__assess_yield_track/cs__assess_yield_track.h +0 -1
  12. data/ext/cs__common/cs__common.c +24 -0
  13. data/ext/cs__common/cs__common.h +3 -0
  14. data/ext/cs__common/extconf.rb +0 -14
  15. data/ext/extconf_common.rb +0 -28
  16. data/lib/contrast.rb +3 -1
  17. data/lib/contrast/agent.rb +14 -2
  18. data/lib/contrast/agent/assess/contrast_event.rb +28 -167
  19. data/lib/contrast/agent/assess/events/source_event.rb +3 -7
  20. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +1 -1
  21. data/lib/contrast/agent/assess/policy/policy_node.rb +4 -98
  22. data/lib/contrast/agent/assess/policy/propagation_method.rb +1 -2
  23. data/lib/contrast/agent/assess/policy/propagation_node.rb +5 -1
  24. data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
  25. data/lib/contrast/agent/assess/policy/propagator/insert.rb +1 -4
  26. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +9 -1
  27. data/lib/contrast/agent/assess/policy/propagator/remove.rb +6 -11
  28. data/lib/contrast/agent/assess/policy/propagator/select.rb +4 -4
  29. data/lib/contrast/agent/assess/policy/propagator/split.rb +2 -2
  30. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +4 -4
  31. data/lib/contrast/agent/assess/policy/propagator/trim.rb +6 -10
  32. data/lib/contrast/agent/assess/policy/source_method.rb +1 -2
  33. data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -9
  34. data/lib/contrast/agent/assess/policy/trigger_node.rb +16 -4
  35. data/lib/contrast/agent/assess/properties.rb +4 -382
  36. data/lib/contrast/agent/assess/property/evented.rb +78 -0
  37. data/lib/contrast/agent/assess/property/tagged.rb +339 -0
  38. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +2 -20
  39. data/lib/contrast/agent/assess/tag.rb +27 -12
  40. data/lib/contrast/agent/at_exit_hook.rb +3 -1
  41. data/lib/contrast/agent/exclusion_matcher.rb +2 -2
  42. data/lib/contrast/agent/inventory/policy/datastores.rb +0 -1
  43. data/lib/contrast/agent/middleware.rb +2 -14
  44. data/lib/contrast/agent/patching/policy/patch.rb +1 -1
  45. data/lib/contrast/agent/patching/policy/policy.rb +3 -3
  46. data/lib/contrast/agent/patching/policy/policy_node.rb +2 -2
  47. data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
  48. data/lib/contrast/agent/protect/rule/base.rb +19 -31
  49. data/lib/contrast/agent/protect/rule/base_service.rb +1 -1
  50. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +2 -7
  51. data/lib/contrast/agent/protect/rule/xxe.rb +1 -0
  52. data/lib/contrast/agent/reaction_processor.rb +3 -3
  53. data/lib/contrast/agent/request.rb +92 -331
  54. data/lib/contrast/agent/request_context.rb +15 -15
  55. data/lib/contrast/agent/request_handler.rb +1 -1
  56. data/lib/contrast/agent/response.rb +2 -14
  57. data/lib/contrast/agent/scope.rb +1 -1
  58. data/lib/contrast/agent/service_heartbeat.rb +7 -9
  59. data/lib/contrast/agent/static_analysis.rb +1 -1
  60. data/lib/contrast/agent/thread_watcher.rb +49 -0
  61. data/lib/contrast/agent/version.rb +1 -1
  62. data/lib/contrast/agent/worker_thread.rb +24 -0
  63. data/lib/contrast/api.rb +3 -5
  64. data/lib/contrast/api/communication.rb +20 -0
  65. data/lib/contrast/api/communication/connection_status.rb +41 -0
  66. data/lib/contrast/api/communication/messaging_queue.rb +79 -0
  67. data/lib/contrast/{utils/service_response_util.rb → api/communication/response_processor.rb} +9 -18
  68. data/lib/contrast/api/communication/service_lifecycle.rb +61 -0
  69. data/lib/contrast/api/communication/socket.rb +45 -0
  70. data/lib/contrast/api/communication/socket_client.rb +76 -0
  71. data/lib/contrast/api/communication/speedracer.rb +111 -0
  72. data/lib/contrast/api/communication/tcp_socket.rb +31 -0
  73. data/lib/contrast/api/communication/unix_socket.rb +27 -0
  74. data/lib/contrast/api/decorators.rb +10 -0
  75. data/lib/contrast/api/decorators/address.rb +60 -0
  76. data/lib/contrast/api/decorators/application_settings.rb +7 -3
  77. data/lib/contrast/api/decorators/application_update.rb +0 -9
  78. data/lib/contrast/api/decorators/http_request.rb +139 -0
  79. data/lib/contrast/api/decorators/message.rb +75 -0
  80. data/lib/contrast/api/decorators/rasp_rule_sample.rb +28 -0
  81. data/lib/contrast/api/decorators/route_coverage.rb +57 -0
  82. data/lib/contrast/api/decorators/trace_event.rb +99 -0
  83. data/lib/contrast/api/decorators/trace_event_object.rb +57 -0
  84. data/lib/contrast/api/decorators/trace_event_signature.rb +46 -0
  85. data/lib/contrast/api/decorators/trace_taint_range.rb +51 -0
  86. data/lib/contrast/api/decorators/trace_taint_range_tags.rb +109 -0
  87. data/lib/contrast/api/decorators/user_input.rb +40 -0
  88. data/lib/contrast/components/app_context.rb +0 -7
  89. data/lib/contrast/components/config.rb +4 -9
  90. data/lib/contrast/components/interface.rb +1 -1
  91. data/lib/contrast/components/settings.rb +0 -6
  92. data/lib/contrast/extension/assess.rb +0 -1
  93. data/lib/contrast/extension/assess/assess_extension.rb +1 -2
  94. data/lib/contrast/extension/assess/fiber.rb +1 -1
  95. data/lib/contrast/extension/assess/string.rb +1 -1
  96. data/lib/contrast/extension/inventory.rb +0 -1
  97. data/lib/contrast/framework/base_support.rb +0 -23
  98. data/lib/contrast/framework/manager.rb +0 -9
  99. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -3
  100. data/lib/contrast/framework/rails/patch/assess_configuration.rb +3 -4
  101. data/lib/contrast/framework/rails/support.rb +3 -32
  102. data/lib/contrast/framework/sinatra/patch/base.rb +1 -1
  103. data/lib/contrast/framework/sinatra/support.rb +11 -22
  104. data/lib/contrast/funchook/funchook.rb +45 -0
  105. data/lib/contrast/logger/application.rb +1 -1
  106. data/lib/contrast/logger/format.rb +51 -0
  107. data/lib/contrast/logger/log.rb +8 -2
  108. data/lib/contrast/utils/assess/tracking_util.rb +45 -20
  109. data/lib/contrast/utils/hash_digest.rb +11 -2
  110. data/lib/contrast/utils/invalid_configuration_util.rb +1 -17
  111. data/lib/contrast/utils/inventory_util.rb +2 -7
  112. data/lib/contrast/utils/object_share.rb +0 -1
  113. data/lib/contrast/utils/os.rb +16 -4
  114. data/lib/contrast/utils/stack_trace_utils.rb +0 -1
  115. data/lib/contrast/utils/tag_util.rb +1 -1
  116. data/lib/contrast/utils/thread_tracker.rb +1 -14
  117. data/lib/contrast/utils/timer.rb +1 -17
  118. data/ruby-agent.gemspec +4 -4
  119. metadata +48 -72
  120. data/funchook/Makefile +0 -29
  121. data/funchook/autom4te.cache/output.0 +0 -4964
  122. data/funchook/autom4te.cache/requests +0 -77
  123. data/funchook/autom4te.cache/traces.0 +0 -361
  124. data/funchook/config.log +0 -651
  125. data/funchook/config.status +0 -1015
  126. data/funchook/configure +0 -4964
  127. data/funchook/src/Makefile +0 -70
  128. data/funchook/src/config.h +0 -101
  129. data/funchook/src/config.h.in +0 -100
  130. data/funchook/src/decoder.o +0 -0
  131. data/funchook/src/distorm.o +0 -0
  132. data/funchook/src/funchook.o +0 -0
  133. data/funchook/src/funchook_io.o +0 -0
  134. data/funchook/src/funchook_syscall.o +0 -0
  135. data/funchook/src/funchook_unix.o +0 -0
  136. data/funchook/src/funchook_x86.o +0 -0
  137. data/funchook/src/instructions.o +0 -0
  138. data/funchook/src/insts.o +0 -0
  139. data/funchook/src/libfunchook.dylib +0 -0
  140. data/funchook/src/mnemonics.o +0 -0
  141. data/funchook/src/operands.o +0 -0
  142. data/funchook/src/os_func.o +0 -0
  143. data/funchook/src/os_func_unix.o +0 -0
  144. data/funchook/src/prefix.o +0 -0
  145. data/funchook/src/printf_base.o +0 -0
  146. data/funchook/src/textdefs.o +0 -0
  147. data/funchook/src/wstring.o +0 -0
  148. data/funchook/test/Makefile +0 -43
  149. data/funchook/test/funchook_test +0 -0
  150. data/funchook/test/libfunchook_test.so +0 -0
  151. data/funchook/test/libfunchook_test.so.dSYM/Contents/Info.plist +0 -20
  152. data/funchook/test/libfunchook_test.so.dSYM/Contents/Resources/DWARF/libfunchook_test.so +0 -0
  153. data/funchook/test/test_main.o +0 -0
  154. data/funchook/test/x86_64_test.o +0 -0
  155. data/lib/contrast/agent/assess/adjusted_span.rb +0 -27
  156. data/lib/contrast/agent/socket_client.rb +0 -134
  157. data/lib/contrast/api/connection_status.rb +0 -49
  158. data/lib/contrast/api/socket.rb +0 -43
  159. data/lib/contrast/api/speedracer.rb +0 -188
  160. data/lib/contrast/api/tcp_socket.rb +0 -29
  161. data/lib/contrast/api/unix_socket.rb +0 -25
  162. data/lib/contrast/framework/sinatra/application_helper.rb +0 -51
  163. data/lib/contrast/framework/view_technologies_descriptor.rb +0 -21
  164. data/lib/contrast/internal_exception.rb +0 -8
  165. data/lib/contrast/utils/cache.rb +0 -58
  166. data/lib/contrast/utils/service_sender_util.rb +0 -167
  167. data/lib/contrast/utils/sinatra_helper.rb +0 -49
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c4c1231012886dbd14e4cd13bef64286f18d970be8c3b5c7daa7e585ae500aa
4
- data.tar.gz: 23a64e21d451cea85ce8b2e4c19ac98c5d7e14c294abac30e3a4310c8809a7ea
3
+ metadata.gz: 64a4e6fe5f8f75e8ab4bb911e696330a10e1a3edb95c027a03dd0b8704e23f3e
4
+ data.tar.gz: f031d456741cb0d955030805efd73f8cb2495ca7c927a15121c5ef88a6d86ec7
5
5
  SHA512:
6
- metadata.gz: 49c90e08126185be367fef4c5494fc074faf0af77e1d376966a976e8f4c839d94ba292a24fa0826e332c9adf1ae42fa281ab0ab44dfc0040128856b332f28e82
7
- data.tar.gz: 58f501e22a5c0654b8fbe64f7f1668de9308a63e61749d3ebc8b0c033cf6e41cc4928d890db8de6943ec38a53d90d5affc812c258382137249bde0d3471a18e8
6
+ metadata.gz: e2fac539c17b2cb20ab407f6ded931316f97529073907a3f03ee7ef8774a2e18a597d5c47406e44cb86111338e7d31170399543a1778bb7154eaf618b4e03635
7
+ data.tar.gz: 44e2552f7ee995f73514c62b10002096fcf8f462bdbc573cceb623f9a42786c2421d16490962a9575d777a792fd9ea459d41630e2de9cf60e55c61ecc0fb8403
@@ -4,7 +4,6 @@ docker/
4
4
  code-deploy/
5
5
 
6
6
  Jenkinsfile
7
- bitbucket-pipelines.yml
8
7
  docker-compose.yml
9
8
  .rubocop.yml
10
9
  .travis.yml
data/.gitignore CHANGED
@@ -52,7 +52,7 @@ contrast-agent-*.gem
52
52
  service_executables/*-*
53
53
 
54
54
  # Generated Protobuf files
55
- /lib/contrast/api/*_pb.rb
55
+ /lib/contrast/api/*.pb.rb
56
56
 
57
57
  # IDE stuff
58
58
  tags
data/.simplecov CHANGED
@@ -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
- SimpleCov.minimum_coverage line: 92.30
4
+ SimpleCov.minimum_coverage line: 94.75
5
5
  SimpleCov.start do
6
6
  add_filter '/spec/'
7
7
  end
data/Rakefile CHANGED
@@ -1,9 +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
+ $stdout.sync = true
5
+
4
6
  require 'bundler/gem_tasks'
5
7
  require 'rspec/core/rake_task'
6
8
  require 'rake/extensiontask'
9
+ load 'protobuf/tasks/compile.rake'
10
+ require 'fileutils'
7
11
 
8
12
  CLOBBER << 'shared_libraries/*'
9
13
 
@@ -13,3 +17,30 @@ Dir['ext/cs__*'].each do |extension|
13
17
  ext.lib_dir = "lib/#{ name }"
14
18
  end
15
19
  end
20
+
21
+ task :contrast_pb_compile do
22
+ # do some stuff before compile
23
+
24
+ # Invoke the protobuf compile task with your sensible defaults
25
+ ::Rake::Task['protobuf:compile'].invoke('lib',
26
+ './agent-service-api/protobuf ./agent-service-api/protobuf/dtm.proto',
27
+ 'lib/contrast/api',
28
+ nil)
29
+
30
+ ::Rake::Task['protobuf:compile'].reenable
31
+
32
+ ::Rake::Task['protobuf:compile'].invoke('lib',
33
+ './agent-service-api/protobuf ./agent-service-api/protobuf/settings.proto',
34
+ 'lib/contrast/api',
35
+ nil)
36
+
37
+ ['dtm.pb.rb', 'settings.pb.rb'].each do |target_file|
38
+ target_path = File.absolute_path(File.join(__dir__, "./lib/contrast/api/#{ target_file }"))
39
+ unless File.exist?(target_path)
40
+ puts "File not found #{ target_path }"
41
+ exit 1
42
+ end
43
+ end
44
+
45
+ puts 'Protobuf copied successfully'
46
+ end
@@ -62,5 +62,3 @@ unless find_header('funchook.h', ext_path)
62
62
  end
63
63
  end
64
64
  end
65
-
66
- have_header('funchook.h', ext_path)
@@ -3,7 +3,6 @@
3
3
 
4
4
  #include "cs__assess_fiber_track.h"
5
5
  #include "../cs__common/cs__common.h"
6
- #include <funchook.h>
7
6
  #include <ruby.h>
8
7
 
9
8
  VALUE rb_fiber_new_hook(VALUE (*func)(ANYARGS), VALUE obj) {
@@ -64,17 +63,12 @@ VALUE rb_fiber_yield_hook(int argc, const VALUE *argv) {
64
63
  }
65
64
 
66
65
  int install_fiber_hooks() {
67
- funchook_t *funchook = funchook_create();
68
-
69
66
  rb_fiber_new_original = rb_fiber_new;
70
- funchook_prepare(funchook, (void **)&rb_fiber_new_original,
71
- rb_fiber_new_hook);
67
+ patch_via_funchook(&rb_fiber_new_original, &rb_fiber_new_hook);
72
68
 
73
69
  rb_fiber_yield_original = rb_fiber_yield;
74
- funchook_prepare(funchook, (void **)&rb_fiber_yield_original,
75
- rb_fiber_yield_hook);
70
+ patch_via_funchook(&rb_fiber_yield_original, &rb_fiber_yield_hook);
76
71
 
77
- funchook_install(funchook, 0);
78
72
  return 0;
79
73
  }
80
74
 
@@ -1,4 +1,3 @@
1
- #include <funchook.h>
2
1
  #include <ruby.h>
3
2
 
4
3
  static VALUE rb_sym_next;
@@ -3,7 +3,6 @@
3
3
 
4
4
  #include "cs__assess_string_interpolation26.h"
5
5
  #include "../cs__common/cs__common.h"
6
- #include <funchook.h>
7
6
  #include <ruby.h>
8
7
 
9
8
  static VALUE rb_str_concat_literals_hook(size_t num, VALUE *strary) {
@@ -14,13 +13,9 @@ static VALUE rb_str_concat_literals_hook(size_t num, VALUE *strary) {
14
13
  }
15
14
 
16
15
  static int install_hooks() {
17
- funchook_t *funchook = funchook_create();
18
-
19
16
  rb_str_concat_literals_original = rb_str_concat_literals;
20
- funchook_prepare(funchook, (void **)&rb_str_concat_literals_original,
21
- rb_str_concat_literals_hook);
17
+ patch_via_funchook(&rb_str_concat_literals_original, &rb_str_concat_literals_hook);
22
18
 
23
- funchook_install(funchook, 0);
24
19
  return 0;
25
20
  }
26
21
 
@@ -3,7 +3,6 @@
3
3
 
4
4
  #include "cs__assess_yield_track.h"
5
5
  #include "../cs__common/cs__common.h"
6
- #include <funchook.h>
7
6
  #include <ruby.h>
8
7
 
9
8
  static VALUE rb_yield_hook(VALUE val, const VALUE self) {
@@ -17,11 +16,8 @@ static VALUE rb_yield_hook(VALUE val, const VALUE self) {
17
16
  }
18
17
 
19
18
  static int install_yield_hooks() {
20
- funchook_t *funchook = funchook_create();
21
19
  rb_yield_original = rb_yield;
22
- funchook_prepare(funchook, (void **)&rb_yield_original,
23
- rb_yield_hook);
24
- funchook_install(funchook, 0);
20
+ patch_via_funchook(&rb_yield_original, &rb_yield_hook);
25
21
  return 0;
26
22
  }
27
23
 
@@ -1,4 +1,3 @@
1
- #include <funchook.h>
2
1
  #include <ruby.h>
3
2
 
4
3
  static VALUE split_class;
@@ -3,12 +3,14 @@
3
3
 
4
4
  #include "cs__common.h"
5
5
  #include <ruby.h>
6
+ #include <dlfcn.h>
6
7
 
7
8
  /* Globals */
8
9
  /* These are defined w/ `extern` in the header */
9
10
  VALUE contrast, agent, patching, policy, assess;
10
11
  VALUE core_extensions, core_assess;
11
12
  VALUE assess_policy, assess_propagator;
13
+ VALUE funchook_path;
12
14
 
13
15
  VALUE rb_sym_enter_scope;
14
16
  VALUE rb_sym_exit_scope;
@@ -19,6 +21,28 @@ VALUE rb_sym_method;
19
21
  VALUE rb_sym_cs_tracked;
20
22
  /* end globals */
21
23
 
24
+ void patch_via_funchook(void *original_function, void *hook_function) {
25
+ VALUE funchook_module_wrapper = rb_define_module("Funchook");
26
+ funchook_path = rb_iv_get(funchook_module_wrapper, "@path");
27
+
28
+ void *funchook_lib_handle;
29
+ void *funchook_reference, *(*funchook_create)(void);
30
+ int prepareResult, (*funchook_prepare)(void*, void**, void*);
31
+ int installResult, (*funchook_install)(void*, int);
32
+
33
+ funchook_lib_handle = dlopen(StringValueCStr(funchook_path), RTLD_NOW | RTLD_GLOBAL);
34
+
35
+ /* Load the funchook methods we need */
36
+ funchook_create = (void* (*)(void))dlsym(funchook_lib_handle, "funchook_create");
37
+ funchook_prepare = (int (*)(void*, void**, void*))dlsym(funchook_lib_handle, "funchook_prepare");
38
+ funchook_install = (int (*)(void*, int))dlsym(funchook_lib_handle, "funchook_install");
39
+
40
+ funchook_reference = (void*)(*funchook_create)();
41
+
42
+ prepareResult = (*funchook_prepare)(funchook_reference, (void**)original_function, hook_function);
43
+ installResult = (*funchook_install)(funchook_reference, 0);
44
+ }
45
+
22
46
  void contrast_alias_method(const VALUE target, const char *to,
23
47
  const char *from) {
24
48
  rb_funcall(target, cs__send_method, 3, cs__alias_method_sym,
@@ -16,6 +16,7 @@ static VALUE cs__alias_method_sym;
16
16
  extern VALUE contrast, agent, patching, policy, assess;
17
17
  extern VALUE core_extensions, core_assess;
18
18
  extern VALUE assess_policy, assess_propagator;
19
+ extern VALUE funchook_path;
19
20
 
20
21
  extern VALUE rb_sym_enter_scope;
21
22
  extern VALUE rb_sym_exit_scope;
@@ -32,6 +33,8 @@ static VALUE rb_sym_alias_instance;
32
33
  static VALUE rb_sym_alias_singleton;
33
34
  static VALUE rb_sym_prepend;
34
35
 
36
+ void patch_via_funchook(void *original_function, void *hook_function);
37
+
35
38
  void contrast_alias_method(const VALUE target, const char *to,
36
39
  const char *from);
37
40
 
@@ -4,18 +4,4 @@
4
4
  require 'mkmf'
5
5
  require_relative '../../lib/contrast/agent/version'
6
6
 
7
- installed_path = __dir__
8
-
9
- origin = if !(/darwin/ =~ RUBY_PLATFORM).nil?
10
- '@loader_path'
11
- else
12
- '\$${ORIGIN}'
13
- end
14
-
15
- options = " -Wl,-rpath,#{ origin }/../../shared_libraries"
16
-
17
- $LDFLAGS << options if try_link('int main() {return 0;}', options)
18
-
19
- $LIBPATH << installed_path
20
-
21
7
  create_makefile 'cs__common/cs__common'
@@ -18,34 +18,6 @@ def ext_path
18
18
  __dir__
19
19
  end
20
20
 
21
- def rpath_root
22
- if (/darwin/ =~ RUBY_PLATFORM).nil?
23
- '\$${ORIGIN}'
24
- else
25
- '@loader_path'
26
- end
27
- end
28
-
29
- def funchook_rpath!
30
- options = " -Wl,-rpath,#{ rpath_root }/../../shared_libraries"
31
- raise unless try_link('int main() {return 0;}', options)
32
-
33
- $LDFLAGS << options
34
- $LDFLAGS << " -L#{ __dir__ }/../shared_libraries"
35
-
36
- find_header('funchook.h', ext_path)
37
- have_header('funchook.h')
38
-
39
- find_library('funchook', 'funchook_create', '../shared_libraries')
40
- find_library('funchook', 'funchook_install')
41
- find_library('funchook', 'funchook_prepare')
42
- have_library('funchook', 'funchook_create')
43
- have_library('funchook', 'funchook_install')
44
- have_library('funchook', 'funchook_prepare')
45
- end
46
-
47
21
  require_relative './build_funchook'
48
22
 
49
- # default make pathway, here for convenience
50
- funchook_rpath!
51
23
  make!
@@ -39,6 +39,9 @@ end
39
39
  # config gets built as a consequence of this require
40
40
  cs__scoped_require 'contrast/components/interface'
41
41
 
42
+ # This needs to be required very early, after component interfaces, and before instrumentation attempts
43
+ cs__scoped_require 'contrast/funchook/funchook'
44
+
42
45
  # shared configuration support
43
46
  cs__scoped_require 'contrast/config'
44
47
  cs__scoped_require 'contrast/configuration'
@@ -47,7 +50,6 @@ cs__scoped_require 'contrast/agent/version'
47
50
 
48
51
  # errors and exceptions
49
52
  cs__scoped_require 'contrast/security_exception'
50
- cs__scoped_require 'contrast/internal_exception'
51
53
 
52
54
  # shared utils
53
55
  cs__scoped_require 'contrast/utils/timer'
@@ -41,6 +41,11 @@ cs__scoped_require 'contrast/utils/thread_tracker'
41
41
  # Framework support
42
42
  cs__scoped_require 'contrast/framework/manager'
43
43
 
44
+ # Communication to SR
45
+ cs__scoped_require 'contrast/api/communication'
46
+
47
+ cs__scoped_require 'contrast/agent/thread_watcher'
48
+
44
49
  module Contrast
45
50
  # Top namespace of the Agent section. Holds tracking contexts that will be
46
51
  # accessed throughout the Agent.
@@ -51,6 +56,14 @@ module Contrast
51
56
  def self.framework_manager
52
57
  @_framework_manager ||= Contrast::Framework::Manager.new
53
58
  end
59
+
60
+ def self.messaging_queue
61
+ @_messaging_queue ||= Contrast::Api::Communication::MessagingQueue.new
62
+ end
63
+
64
+ def self.thread_watcher
65
+ @_thread_watcher ||= Contrast::Agent::ThreadWatcher.new
66
+ end
54
67
  end
55
68
  end
56
69
 
@@ -63,7 +76,6 @@ cs__scoped_require 'contrast/agent/at_exit_hook'
63
76
 
64
77
  # communication with contrast service
65
78
  cs__scoped_require 'contrast/agent/exclusion_matcher'
66
- cs__scoped_require 'contrast/agent/socket_client'
67
79
 
68
80
  # threads that handle contrast scope
69
81
  cs__scoped_require 'contrast/agent/thread'
@@ -76,7 +88,7 @@ cs__scoped_require 'contrast/agent/assess'
76
88
  # protect rules
77
89
  cs__scoped_require 'contrast/agent/protect/rule'
78
90
 
79
- # application libraries and technologies
91
+ # application libraries
80
92
  cs__scoped_require 'contrast/utils/gemfile_reader'
81
93
 
82
94
  # rack event monitoring
@@ -59,7 +59,7 @@ module Contrast
59
59
  end
60
60
  end
61
61
 
62
- attr_reader :event_id, :parent_ids
62
+ attr_reader :event_id, :parent_ids, :policy_node, :stack_trace, :time, :thread, :object, :ret, :args
63
63
 
64
64
  # We need this to track the parent id's of events to build up a flow
65
65
  # chart of the finding
@@ -78,7 +78,7 @@ module Contrast
78
78
  @policy_node = policy_node
79
79
  # so long as this event is built in a factory, we know Contrast Code
80
80
  # will be the first three events
81
- @caller = caller(3, 20)
81
+ @stack_trace = caller(3, 20)
82
82
  @time = Contrast::Utils::Timer.now_ms
83
83
  @thread = Thread.current.object_id
84
84
 
@@ -157,6 +157,31 @@ module Contrast
157
157
  end
158
158
  end
159
159
 
160
+ # We have to do a little work to figure out what our TS appropriate
161
+ # target is. To break this down, the logic is as follows:
162
+ # 1) If my policy_node has a target, work on targets. Else, work on sources.
163
+ # Per TS law, each policy_node must have at least a source or a target.
164
+ # The only type of policy_node w/o targets is a Trigger, but that may
165
+ # change.
166
+ # 2) If I have a highlight, it means that I have a P target that is
167
+ # not in integer form (it was a named / keyword type for which I had
168
+ # to find the index). I need to address this so that TS can process
169
+ # it.
170
+ # 3) I'll set the event's source and target to TS values.
171
+ # 4) Return the highlight or the first source/target as the taint
172
+ # target.
173
+ def determine_taint_target event_dtm
174
+ if @policy_node&.targets&.any?
175
+ event_dtm.source = @policy_node.source_string if @policy_node.source_string
176
+ event_dtm.target = @highlight ? "P#{ @highlight }" : @policy_node.target_string
177
+ @highlight || @policy_node.targets[0]
178
+ elsif policy_node&.sources&.any?
179
+ event_dtm.source = @highlight ? "P#{ @highlight }" : @policy_node.source_string
180
+ event_dtm.target = @policy_node.target_string if @policy_node.target_string
181
+ @highlight || @policy_node.sources[0]
182
+ end
183
+ end
184
+
160
185
  def value_of_source source, object, ret, args
161
186
  case source
162
187
  when Contrast::Utils::ObjectShare::OBJECT_KEY
@@ -179,171 +204,7 @@ module Contrast
179
204
 
180
205
  # Convert this event into a DTM that TeamServer can consume
181
206
  def to_dtm_event
182
- event = Contrast::Api::Dtm::TraceEvent.new
183
-
184
- # Figure out what the target of this event was. It's a little
185
- # annoying for us since P can be named (thanks, Ruby) where
186
- # as for everyone else it is idx based.
187
- taint_target = determine_taint_target(event)
188
-
189
- event.type = @policy_node.node_type
190
- event.action = @policy_node.build_action
191
- event.timestamp_ms = @time.to_i
192
- event.thread = Contrast::Utils::StringUtils.force_utf8(@thread)
193
- truncate_obj = Contrast::Utils::ObjectShare::OBJECT_KEY != taint_target
194
- event.object = build_event_object(@object, truncate_obj)
195
- truncate_ret = Contrast::Utils::ObjectShare::RETURN_KEY != taint_target
196
- event.ret = build_event_object(@ret, truncate_ret)
197
- built_args = build_event_args(taint_target)
198
- built_args.each do |arg|
199
- event.args << arg
200
- end
201
- taint_ranges = find_taint_ranges(@object, @args, @ret, taint_target)
202
- taint_ranges.each do |range|
203
- event.taint_ranges << range
204
- end
205
-
206
- # We delayed doing this as long as possible b/c it's expensive
207
- stack = Contrast::Utils::StackTraceUtils.build_assess_stack_array(@caller)
208
- event.stack += stack
209
-
210
- event.object_id = event_id.to_i
211
- parent_ids&.each do |id|
212
- parent = Contrast::Api::Dtm::ParentObjectId.new
213
- parent.id = id.to_i
214
- event.parent_object_ids << parent
215
- end
216
-
217
- # not to be confused w/ the partial signature
218
- build_complete_signature(event)
219
-
220
- event
221
- end
222
-
223
- # We're not going to build the signature string here, b/c we have all
224
- # the composite pieces of it. Instead, we're going to let TeamServer
225
- # render this for us.
226
- def build_complete_signature event
227
- signature = Contrast::Api::Dtm::TraceEventSignature.new
228
- event.signature = signature
229
- return_type = @ret ? @ret.cs__class.name : Contrast::Utils::ObjectShare::NIL_STRING
230
- signature.return_type = Contrast::Utils::StringUtils.force_utf8(return_type)
231
- signature.class_name = Contrast::Utils::StringUtils.force_utf8(@policy_node.class_name)
232
- signature.method_name = Contrast::Utils::StringUtils.force_utf8(@policy_node.method_name)
233
- if @args
234
- @args&.each do |arg|
235
- arg_type = arg ? arg.cs__class.name : Contrast::Utils::ObjectShare::NIL_STRING
236
- signature.arg_types << Contrast::Utils::StringUtils.force_utf8(arg_type)
237
- end
238
- end
239
- signature.constructor = @policy_node.method_name == :new
240
- # if there's a ret, then this method isn't nil. not 100% full proof since you can
241
- # return nil, but this is the best we've got currently.
242
- signature.void_method = @ret.nil?
243
- # 8 is STATIC in Java... we have to placate them for now
244
- # it has been requested that flags be removed since it isn't used
245
- signature.flags = 8 unless @policy_node.instance_method?
246
- end
247
-
248
- # Wrapper around build_event_object for the args array. Handles
249
- # tainting the correct argument.
250
- def build_event_args taint_target
251
- event_args = []
252
- @args.each_index do |idx|
253
- truncate_arg = taint_target != idx
254
- event_arg = build_event_object(@args[idx], truncate_arg)
255
- event_args << event_arg
256
- end
257
- event_args
258
- end
259
-
260
- # Build the event object. We were originally going to include taint on
261
- # each one, but TS doesn't accept / use that, so it is a waste of time.
262
- #
263
- # We'll truncate any object that isn't important to the taint ranges of
264
- # this event, so that we don't murder TeamServer by, for instance,
265
- # hypothetically sending the entire rendered HTML page >_> <_< >_>
266
- ELLIPSIS = '...'
267
- UNTRUNCATED_PORTION_LENGTH = 25
268
- TRUNCATION_LENGTH = (UNTRUNCATED_PORTION_LENGTH * 2) + 3 # ELLIPSIS length
269
- def build_event_object object, truncate
270
- event_object = Contrast::Api::Dtm::TraceEventObject.new
271
- obj_string = Contrast::Utils::StringUtils.force_utf8(object)
272
- if truncate && Contrast::Utils::StringUtils.ret_length(obj_string) > TRUNCATION_LENGTH
273
- tmp = []
274
- tmp << obj_string[0, UNTRUNCATED_PORTION_LENGTH]
275
- tmp << ELLIPSIS
276
- tmp << obj_string[
277
- obj_string.length - UNTRUNCATED_PORTION_LENGTH,
278
- UNTRUNCATED_PORTION_LENGTH]
279
- obj_string = tmp.join
280
- end
281
- event_object.value = Base64.encode64(obj_string)
282
- event_object.tracked = Contrast::Utils::Assess::TrackingUtil.tracked?(object)
283
- event_object
284
- end
285
-
286
- # We have to do a little work to figure out what our TS appropriate
287
- # target is. To break this down, the logic is as follows:
288
- # 1) If my policy_node has a target, work on targets. Else, work on sources.
289
- # Per TS law, each policy_node must have at least a source or a target.
290
- # The only type of policy_node w/o targets is a Trigger, but that may
291
- # change.
292
- # 2) If I have a highlight, it means that I have a P target that is
293
- # not in integer form (it was a named / keyword type for which I had
294
- # to find the index). I need to address this so that TS can process
295
- # it.
296
- # 3) I'll set the event's source and target to TS values.
297
- # 4) Return the highlight or the first source/target as the taint
298
- # target.
299
- def determine_taint_target event
300
- if @policy_node&.targets&.any?
301
- event.source = @policy_node.source_string if @policy_node.source_string
302
- event.target = if @highlight
303
- "P#{ @highlight }"
304
- else
305
- @policy_node.target_string
306
- end
307
- @highlight || @policy_node.targets[0]
308
- elsif @policy_node&.sources&.any?
309
- event.source = if @highlight
310
- "P#{ @highlight }"
311
- else
312
- @policy_node.source_string
313
- end
314
- event.target = @policy_node.target_string if @policy_node.target_string
315
- @highlight || @policy_node.sources[0]
316
- end
317
- end
318
-
319
- # TeamServer only supports one object's taint ranges at a time.
320
- # We'll find the taint ranges for the target and return those
321
- def find_taint_ranges object, args, ret, taint_target
322
- # If there's no taint_target, this isn't a dataflow trace, but a
323
- # trigger one
324
- return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless taint_target
325
-
326
- properties = case taint_target
327
- when Contrast::Utils::ObjectShare::OBJECT_KEY
328
- object.cs__properties
329
- when Contrast::Utils::ObjectShare::RETURN_KEY
330
- ret.cs__properties
331
- else
332
- target = args[taint_target]
333
- if target.is_a?(Hash)
334
- if @policy_node&.targets&.any?
335
- target[@policy_node.targets[0]].cs__properties
336
- else
337
- target[@policy_node.sources[0]].cs__properties
338
- end
339
- else
340
- target.cs__properties
341
- end
342
- end
343
-
344
- return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless properties.tracked?
345
-
346
- properties.tags_to_dtm
207
+ Contrast::Api::Dtm::TraceEvent.build(self)
347
208
  end
348
209
  end
349
210
  end