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.
- checksums.yaml +4 -4
- data/.dockerignore +0 -1
- data/.gitignore +1 -1
- data/.simplecov +1 -1
- data/Rakefile +31 -0
- data/ext/build_funchook.rb +0 -2
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +2 -8
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +0 -1
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +1 -6
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +1 -5
- data/ext/cs__assess_yield_track/cs__assess_yield_track.h +0 -1
- data/ext/cs__common/cs__common.c +24 -0
- data/ext/cs__common/cs__common.h +3 -0
- data/ext/cs__common/extconf.rb +0 -14
- data/ext/extconf_common.rb +0 -28
- data/lib/contrast.rb +3 -1
- data/lib/contrast/agent.rb +14 -2
- data/lib/contrast/agent/assess/contrast_event.rb +28 -167
- data/lib/contrast/agent/assess/events/source_event.rb +3 -7
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +1 -1
- data/lib/contrast/agent/assess/policy/policy_node.rb +4 -98
- data/lib/contrast/agent/assess/policy/propagation_method.rb +1 -2
- data/lib/contrast/agent/assess/policy/propagation_node.rb +5 -1
- data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +1 -4
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +9 -1
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +6 -11
- data/lib/contrast/agent/assess/policy/propagator/select.rb +4 -4
- data/lib/contrast/agent/assess/policy/propagator/split.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +4 -4
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +6 -10
- data/lib/contrast/agent/assess/policy/source_method.rb +1 -2
- data/lib/contrast/agent/assess/policy/trigger_method.rb +1 -9
- data/lib/contrast/agent/assess/policy/trigger_node.rb +16 -4
- data/lib/contrast/agent/assess/properties.rb +4 -382
- data/lib/contrast/agent/assess/property/evented.rb +78 -0
- data/lib/contrast/agent/assess/property/tagged.rb +339 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +2 -20
- data/lib/contrast/agent/assess/tag.rb +27 -12
- data/lib/contrast/agent/at_exit_hook.rb +3 -1
- data/lib/contrast/agent/exclusion_matcher.rb +2 -2
- data/lib/contrast/agent/inventory/policy/datastores.rb +0 -1
- data/lib/contrast/agent/middleware.rb +2 -14
- data/lib/contrast/agent/patching/policy/patch.rb +1 -1
- data/lib/contrast/agent/patching/policy/policy.rb +3 -3
- data/lib/contrast/agent/patching/policy/policy_node.rb +2 -2
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
- data/lib/contrast/agent/protect/rule/base.rb +19 -31
- data/lib/contrast/agent/protect/rule/base_service.rb +1 -1
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +2 -7
- data/lib/contrast/agent/protect/rule/xxe.rb +1 -0
- data/lib/contrast/agent/reaction_processor.rb +3 -3
- data/lib/contrast/agent/request.rb +92 -331
- data/lib/contrast/agent/request_context.rb +15 -15
- data/lib/contrast/agent/request_handler.rb +1 -1
- data/lib/contrast/agent/response.rb +2 -14
- data/lib/contrast/agent/scope.rb +1 -1
- data/lib/contrast/agent/service_heartbeat.rb +7 -9
- data/lib/contrast/agent/static_analysis.rb +1 -1
- data/lib/contrast/agent/thread_watcher.rb +49 -0
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent/worker_thread.rb +24 -0
- data/lib/contrast/api.rb +3 -5
- data/lib/contrast/api/communication.rb +20 -0
- data/lib/contrast/api/communication/connection_status.rb +41 -0
- data/lib/contrast/api/communication/messaging_queue.rb +79 -0
- data/lib/contrast/{utils/service_response_util.rb → api/communication/response_processor.rb} +9 -18
- data/lib/contrast/api/communication/service_lifecycle.rb +61 -0
- data/lib/contrast/api/communication/socket.rb +45 -0
- data/lib/contrast/api/communication/socket_client.rb +76 -0
- data/lib/contrast/api/communication/speedracer.rb +111 -0
- data/lib/contrast/api/communication/tcp_socket.rb +31 -0
- data/lib/contrast/api/communication/unix_socket.rb +27 -0
- data/lib/contrast/api/decorators.rb +10 -0
- data/lib/contrast/api/decorators/address.rb +60 -0
- data/lib/contrast/api/decorators/application_settings.rb +7 -3
- data/lib/contrast/api/decorators/application_update.rb +0 -9
- data/lib/contrast/api/decorators/http_request.rb +139 -0
- data/lib/contrast/api/decorators/message.rb +75 -0
- data/lib/contrast/api/decorators/rasp_rule_sample.rb +28 -0
- data/lib/contrast/api/decorators/route_coverage.rb +57 -0
- data/lib/contrast/api/decorators/trace_event.rb +99 -0
- data/lib/contrast/api/decorators/trace_event_object.rb +57 -0
- data/lib/contrast/api/decorators/trace_event_signature.rb +46 -0
- data/lib/contrast/api/decorators/trace_taint_range.rb +51 -0
- data/lib/contrast/api/decorators/trace_taint_range_tags.rb +109 -0
- data/lib/contrast/api/decorators/user_input.rb +40 -0
- data/lib/contrast/components/app_context.rb +0 -7
- data/lib/contrast/components/config.rb +4 -9
- data/lib/contrast/components/interface.rb +1 -1
- data/lib/contrast/components/settings.rb +0 -6
- data/lib/contrast/extension/assess.rb +0 -1
- data/lib/contrast/extension/assess/assess_extension.rb +1 -2
- data/lib/contrast/extension/assess/fiber.rb +1 -1
- data/lib/contrast/extension/assess/string.rb +1 -1
- data/lib/contrast/extension/inventory.rb +0 -1
- data/lib/contrast/framework/base_support.rb +0 -23
- data/lib/contrast/framework/manager.rb +0 -9
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -3
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +3 -4
- data/lib/contrast/framework/rails/support.rb +3 -32
- data/lib/contrast/framework/sinatra/patch/base.rb +1 -1
- data/lib/contrast/framework/sinatra/support.rb +11 -22
- data/lib/contrast/funchook/funchook.rb +45 -0
- data/lib/contrast/logger/application.rb +1 -1
- data/lib/contrast/logger/format.rb +51 -0
- data/lib/contrast/logger/log.rb +8 -2
- data/lib/contrast/utils/assess/tracking_util.rb +45 -20
- data/lib/contrast/utils/hash_digest.rb +11 -2
- data/lib/contrast/utils/invalid_configuration_util.rb +1 -17
- data/lib/contrast/utils/inventory_util.rb +2 -7
- data/lib/contrast/utils/object_share.rb +0 -1
- data/lib/contrast/utils/os.rb +16 -4
- data/lib/contrast/utils/stack_trace_utils.rb +0 -1
- data/lib/contrast/utils/tag_util.rb +1 -1
- data/lib/contrast/utils/thread_tracker.rb +1 -14
- data/lib/contrast/utils/timer.rb +1 -17
- data/ruby-agent.gemspec +4 -4
- metadata +48 -72
- data/funchook/Makefile +0 -29
- data/funchook/autom4te.cache/output.0 +0 -4964
- data/funchook/autom4te.cache/requests +0 -77
- data/funchook/autom4te.cache/traces.0 +0 -361
- data/funchook/config.log +0 -651
- data/funchook/config.status +0 -1015
- data/funchook/configure +0 -4964
- data/funchook/src/Makefile +0 -70
- data/funchook/src/config.h +0 -101
- data/funchook/src/config.h.in +0 -100
- data/funchook/src/decoder.o +0 -0
- data/funchook/src/distorm.o +0 -0
- data/funchook/src/funchook.o +0 -0
- data/funchook/src/funchook_io.o +0 -0
- data/funchook/src/funchook_syscall.o +0 -0
- data/funchook/src/funchook_unix.o +0 -0
- data/funchook/src/funchook_x86.o +0 -0
- data/funchook/src/instructions.o +0 -0
- data/funchook/src/insts.o +0 -0
- data/funchook/src/libfunchook.dylib +0 -0
- data/funchook/src/mnemonics.o +0 -0
- data/funchook/src/operands.o +0 -0
- data/funchook/src/os_func.o +0 -0
- data/funchook/src/os_func_unix.o +0 -0
- data/funchook/src/prefix.o +0 -0
- data/funchook/src/printf_base.o +0 -0
- data/funchook/src/textdefs.o +0 -0
- data/funchook/src/wstring.o +0 -0
- data/funchook/test/Makefile +0 -43
- data/funchook/test/funchook_test +0 -0
- data/funchook/test/libfunchook_test.so +0 -0
- data/funchook/test/libfunchook_test.so.dSYM/Contents/Info.plist +0 -20
- data/funchook/test/libfunchook_test.so.dSYM/Contents/Resources/DWARF/libfunchook_test.so +0 -0
- data/funchook/test/test_main.o +0 -0
- data/funchook/test/x86_64_test.o +0 -0
- data/lib/contrast/agent/assess/adjusted_span.rb +0 -27
- data/lib/contrast/agent/socket_client.rb +0 -134
- data/lib/contrast/api/connection_status.rb +0 -49
- data/lib/contrast/api/socket.rb +0 -43
- data/lib/contrast/api/speedracer.rb +0 -188
- data/lib/contrast/api/tcp_socket.rb +0 -29
- data/lib/contrast/api/unix_socket.rb +0 -25
- data/lib/contrast/framework/sinatra/application_helper.rb +0 -51
- data/lib/contrast/framework/view_technologies_descriptor.rb +0 -21
- data/lib/contrast/internal_exception.rb +0 -8
- data/lib/contrast/utils/cache.rb +0 -58
- data/lib/contrast/utils/service_sender_util.rb +0 -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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64a4e6fe5f8f75e8ab4bb911e696330a10e1a3edb95c027a03dd0b8704e23f3e
|
|
4
|
+
data.tar.gz: f031d456741cb0d955030805efd73f8cb2495ca7c927a15121c5ef88a6d86ec7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2fac539c17b2cb20ab407f6ded931316f97529073907a3f03ee7ef8774a2e18a597d5c47406e44cb86111338e7d31170399543a1778bb7154eaf618b4e03635
|
|
7
|
+
data.tar.gz: 44e2552f7ee995f73514c62b10002096fcf8f462bdbc573cceb623f9a42786c2421d16490962a9575d777a792fd9ea459d41630e2de9cf60e55c61ecc0fb8403
|
data/.dockerignore
CHANGED
data/.gitignore
CHANGED
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:
|
|
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
|
data/ext/build_funchook.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
data/ext/cs__common/cs__common.c
CHANGED
|
@@ -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,
|
data/ext/cs__common/cs__common.h
CHANGED
|
@@ -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
|
|
data/ext/cs__common/extconf.rb
CHANGED
|
@@ -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'
|
data/ext/extconf_common.rb
CHANGED
|
@@ -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!
|
data/lib/contrast.rb
CHANGED
|
@@ -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'
|
data/lib/contrast/agent.rb
CHANGED
|
@@ -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
|
|
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
|
-
@
|
|
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
|
-
|
|
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
|