contrast-agent 4.9.0 → 4.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rspec_parallel +6 -0
  4. data/ext/cs__common/cs__common.c +19 -7
  5. data/ext/cs__common/cs__common.h +4 -2
  6. data/ext/cs__contrast_patch/cs__contrast_patch.c +32 -11
  7. data/ext/cs__contrast_patch/cs__contrast_patch.h +5 -4
  8. data/lib/contrast/agent/assess/contrast_event.rb +1 -2
  9. data/lib/contrast/agent/assess/contrast_object.rb +1 -4
  10. data/lib/contrast/agent/assess/finalizers/hash.rb +0 -1
  11. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +2 -0
  12. data/lib/contrast/agent/assess/policy/patcher.rb +0 -1
  13. data/lib/contrast/agent/assess/policy/policy_scanner.rb +0 -2
  14. data/lib/contrast/agent/assess/policy/preshift.rb +29 -12
  15. data/lib/contrast/agent/assess/policy/propagation_method.rb +100 -57
  16. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +2 -2
  17. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +31 -11
  18. data/lib/contrast/agent/assess/policy/propagator/remove.rb +4 -9
  19. data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -2
  20. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -0
  21. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +0 -1
  22. data/lib/contrast/agent/assess/policy/source_method.rb +13 -17
  23. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +0 -1
  24. data/lib/contrast/agent/assess/policy/trigger_method.rb +60 -85
  25. data/lib/contrast/agent/assess/policy/trigger_node.rb +52 -19
  26. data/lib/contrast/agent/assess/property/evented.rb +2 -1
  27. data/lib/contrast/agent/assess/property/tagged.rb +34 -25
  28. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +0 -1
  29. data/lib/contrast/agent/deadzone/policy/policy.rb +6 -0
  30. data/lib/contrast/agent/disable_reaction.rb +1 -1
  31. data/lib/contrast/agent/exclusion_matcher.rb +0 -4
  32. data/lib/contrast/agent/inventory/database_config.rb +117 -0
  33. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +6 -5
  34. data/lib/contrast/agent/inventory/policy/datastores.rb +2 -2
  35. data/lib/contrast/agent/middleware.rb +1 -0
  36. data/lib/contrast/agent/patching/policy/after_load_patch.rb +3 -0
  37. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +17 -12
  38. data/lib/contrast/agent/patching/policy/method_policy.rb +54 -9
  39. data/lib/contrast/agent/patching/policy/module_policy.rb +2 -4
  40. data/lib/contrast/agent/patching/policy/patch.rb +17 -6
  41. data/lib/contrast/agent/patching/policy/patch_status.rb +3 -7
  42. data/lib/contrast/agent/patching/policy/patcher.rb +9 -9
  43. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
  44. data/lib/contrast/agent/protect/rule/no_sqli.rb +7 -53
  45. data/lib/contrast/agent/protect/rule/sql_sample_builder.rb +137 -0
  46. data/lib/contrast/agent/protect/rule/sqli.rb +7 -70
  47. data/lib/contrast/agent/reaction_processor.rb +1 -1
  48. data/lib/contrast/agent/request.rb +9 -4
  49. data/lib/contrast/agent/request_context.rb +51 -33
  50. data/lib/contrast/agent/rule_set.rb +2 -4
  51. data/lib/contrast/agent/scope.rb +32 -20
  52. data/lib/contrast/agent/static_analysis.rb +1 -1
  53. data/lib/contrast/agent/tracepoint_hook.rb +16 -3
  54. data/lib/contrast/agent/version.rb +1 -1
  55. data/lib/contrast/agent.rb +0 -1
  56. data/lib/contrast/api/communication/messaging_queue.rb +12 -6
  57. data/lib/contrast/api/communication/service_lifecycle.rb +4 -1
  58. data/lib/contrast/api/communication/socket_client.rb +4 -4
  59. data/lib/contrast/api/decorators/agent_startup.rb +4 -4
  60. data/lib/contrast/api/decorators/application_startup.rb +6 -5
  61. data/lib/contrast/api/decorators/route_coverage.rb +24 -1
  62. data/lib/contrast/components/agent.rb +5 -2
  63. data/lib/contrast/components/assess.rb +13 -3
  64. data/lib/contrast/components/base.rb +2 -2
  65. data/lib/contrast/components/config.rb +1 -0
  66. data/lib/contrast/components/contrast_service.rb +4 -2
  67. data/lib/contrast/components/logger.rb +13 -8
  68. data/lib/contrast/components/scope.rb +9 -28
  69. data/lib/contrast/config/assess_configuration.rb +1 -0
  70. data/lib/contrast/config/base_configuration.rb +14 -6
  71. data/lib/contrast/configuration.rb +19 -15
  72. data/lib/contrast/extension/assess/array.rb +1 -11
  73. data/lib/contrast/extension/assess/eval_trigger.rb +0 -20
  74. data/lib/contrast/extension/assess/fiber.rb +0 -11
  75. data/lib/contrast/extension/assess/hash.rb +0 -10
  76. data/lib/contrast/extension/assess/kernel.rb +1 -10
  77. data/lib/contrast/extension/assess/marshal.rb +3 -11
  78. data/lib/contrast/extension/assess/regexp.rb +0 -11
  79. data/lib/contrast/extension/assess/string.rb +1 -26
  80. data/lib/contrast/extension/extension.rb +61 -0
  81. data/lib/contrast/framework/grape/support.rb +174 -0
  82. data/lib/contrast/framework/manager.rb +42 -6
  83. data/lib/contrast/framework/rack/support.rb +1 -1
  84. data/lib/contrast/framework/rails/patch/assess_configuration.rb +0 -1
  85. data/lib/contrast/framework/rails/patch/support.rb +6 -3
  86. data/lib/contrast/framework/rails/railtie.rb +1 -1
  87. data/lib/contrast/framework/rails/rewrite/active_record_named.rb +1 -0
  88. data/lib/contrast/framework/rails/support.rb +60 -13
  89. data/lib/contrast/framework/sinatra/support.rb +1 -1
  90. data/lib/contrast/logger/log.rb +89 -15
  91. data/lib/contrast/tasks/config.rb +0 -1
  92. data/lib/contrast/utils/class_util.rb +58 -44
  93. data/lib/contrast/utils/io_util.rb +43 -35
  94. data/lib/contrast/utils/lru_cache.rb +45 -0
  95. data/lib/contrast/utils/ruby_ast_rewriter.rb +16 -13
  96. data/lib/contrast/utils/tag_util.rb +2 -1
  97. data/lib/contrast.rb +1 -1
  98. data/resources/assess/policy.json +208 -7
  99. data/resources/deadzone/policy.json +91 -0
  100. data/ruby-agent.gemspec +10 -2
  101. data/service_executables/VERSION +1 -1
  102. data/service_executables/linux/contrast-service +0 -0
  103. data/service_executables/mac/contrast-service +0 -0
  104. metadata +74 -26
  105. data/ext/cs__protect_kernel/cs__protect_kernel.c +0 -47
  106. data/ext/cs__protect_kernel/cs__protect_kernel.h +0 -12
  107. data/ext/cs__protect_kernel/extconf.rb +0 -5
  108. data/lib/contrast/extension/protect/kernel.rb +0 -39
  109. data/lib/contrast/utils/inventory_util.rb +0 -113
@@ -1,47 +0,0 @@
1
- /* Copyright (c) 2021 Contrast Security, Inc. See
2
- * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */
3
-
4
- #include "cs__protect_kernel.h"
5
- #include "../cs__common/cs__common.h"
6
- #include <ruby.h>
7
-
8
- static VALUE contrast_protect_fork(const int argc, const VALUE *argv,
9
- const VALUE self) {
10
- VALUE ret;
11
- if (rb_block_given_p()) {
12
- /* We call our hook, but it's a little complicated.
13
- * We wrap the fork block with our own lambda in
14
- * order to instrument it. There are no public
15
- * methods in the Ruby C API to set the prevailing
16
- * block, so we have to use rb_funcall_with_block.
17
- * Also, rb_funcall_with_block does a public call,
18
- * and our method is private.
19
- * So we (as a hack) temporarily set it to public.
20
- */
21
- VALUE wrapper;
22
- wrapper =
23
- rb_funcall_with_block(kernel_protect, rb_sym_protect_kernel_wrapper,
24
- 0, NULL, rb_block_proc());
25
- rb_funcall(rb_mKernel, rb_intern("public"), 1,
26
- ID2SYM(rb_sym_protect_kernel_fork));
27
- ret = rb_funcall_with_block(self, rb_sym_protect_kernel_fork, argc,
28
- argv, wrapper);
29
- rb_funcall(rb_mKernel, rb_intern("private"), 1,
30
- ID2SYM(rb_sym_protect_kernel_fork));
31
- } else {
32
- ret = rb_funcall2(self, rb_sym_protect_kernel_fork, argc, argv);
33
- }
34
- return ret;
35
- }
36
-
37
- void Init_cs__protect_kernel(void) {
38
- VALUE core_protect = rb_define_module_under(core_extensions, "Protect");
39
- kernel_protect = rb_define_module_under(core_protect, "Kernel");
40
- rb_sym_protect_kernel_wrapper = rb_intern("build_wrapper");
41
-
42
- rb_sym_protect_kernel_fork =
43
- contrast_register_patch("Kernel", "fork", &contrast_protect_fork);
44
-
45
- rb_sym_protect_kernel_fork = contrast_register_singleton_patch(
46
- "Kernel", "fork", &contrast_protect_fork);
47
- }
@@ -1,12 +0,0 @@
1
- #include <ruby.h>
2
-
3
- extern VALUE rb_vm_top_self(void);
4
-
5
- static VALUE kernel_protect;
6
- static VALUE rb_sym_protect_kernel_fork;
7
- static VALUE rb_sym_protect_kernel_wrapper;
8
-
9
- static VALUE contrast_protect_fork(const int argc, const VALUE *argv,
10
- const VALUE self);
11
-
12
- void Init_cs__protect_kernel(void);
@@ -1,5 +0,0 @@
1
- # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- $TO_MAKE = File.basename(__dir__)
5
- require_relative '../extconf_common'
@@ -1,39 +0,0 @@
1
- # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- module Contrast
5
- module Extension
6
- module Protect
7
- # This Module functions as our patch into the Kernel class for Protect,
8
- # allowing us to track activity as it crosses spawned processes.
9
- module Kernel
10
- class << self
11
- def build_wrapper
12
- lambda {
13
- proc_start
14
- yield
15
- # AtExitHook handles sending any messages generated in the new forked process
16
- }
17
- end
18
-
19
- def proc_start
20
- context = Contrast::Agent::REQUEST_TRACKER.current
21
- return unless context
22
-
23
- context.reset_activity
24
- end
25
-
26
- def instrument
27
- @_instrument ||= begin
28
- require 'cs__protect_kernel/cs__protect_kernel'
29
- true
30
- end
31
- rescue StandardError, LoadError => e
32
- logger.error('Error loading kernel protect patch', e)
33
- false
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,113 +0,0 @@
1
- # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- require 'contrast/utils/timer'
5
- require 'contrast/utils/object_share'
6
- require 'contrast/components/logger'
7
-
8
- module Contrast
9
- module Utils
10
- # Utilities for getting inventory information from the application
11
- class InventoryUtil
12
- extend Contrast::Components::Logger::InstanceMethods
13
-
14
- # TeamServer only accepts certain values for ArchitectureComponents.
15
- # DO NOT CHANGE THIS!
16
- AC_TYPE_DB = 'db'
17
- # TeamServer only accepts certain values for FlowMap Services.
18
- # DO NOT CHANGE THIS
19
- ADAPTER = 'adapter'
20
- HOST = 'host'
21
- PORT = 'port'
22
- DATABASE = 'database'
23
- DEFAULT = 'default'
24
- LOCALHOST = 'localhost'
25
-
26
- def self.active_record_config
27
- return @_active_record_config if instance_variable_defined?(:@_active_record_config)
28
-
29
- @_active_record_config = ActiveRecord::Base.connection_config rescue nil # rubocop:disable Style/RescueModifier
30
- end
31
-
32
- def self.append_db_config activity_or_update, hash_or_str = Contrast::Utils::InventoryUtil.active_record_config
33
- arr = build_from_db_config(hash_or_str)
34
- return unless arr&.any?
35
-
36
- arr.each do |a|
37
- next unless a
38
-
39
- if activity_or_update.is_a?(Contrast::Api::Dtm::Activity)
40
- activity_or_update.architectures << a
41
- else
42
- activity_or_update.components << a
43
- end
44
- end
45
- rescue StandardError => e
46
- logger.error('Unable to append db config', e)
47
- nil
48
- end
49
-
50
- def self.build_from_db_config hash_or_str
51
- return unless hash_or_str
52
-
53
- if hash_or_str.is_a?(Hash)
54
- build_from_db_hash(hash_or_str)
55
- else
56
- build_from_db_string(hash_or_str.to_s)
57
- end
58
- end
59
-
60
- def self.build_from_db_hash hash
61
- ac = Contrast::Api::Dtm::ArchitectureComponent.new
62
- ac.vendor = hash[:adapter] || hash[ADAPTER] || Contrast::Utils::ObjectShare::EMPTY_STRING
63
- ac.remote_host = host_from_hash(hash)
64
- ac.remote_port = port_from_hash(hash)
65
- ac.type = AC_TYPE_DB
66
- ac.url = hash[:database] || hash[DATABASE] || DEFAULT
67
- [ac]
68
- end
69
-
70
- def self.host_from_hash hash
71
- hash[:host] || hash[HOST] || Contrast::Utils::ObjectShare::EMPTY_STRING
72
- end
73
-
74
- def self.port_from_hash hash
75
- p = hash[:port] || hash[PORT] || Contrast::Utils::ObjectShare::EMPTY_STRING
76
- p.to_i
77
- end
78
-
79
- # Examples:
80
- # mongodb://[user:pass@]host1[:port1][,host2[:port2],[,hostN[:portN]]][/[database][?options]]
81
- # postgresql://scott:tiger@localhost/mydatabase
82
- # mysql+mysqlconnector://scott:tiger@localhost/foo
83
- def self.build_from_db_string str
84
- adapter, hosts, database = split_connection_str(str)
85
- acs = []
86
- hosts.split(Contrast::Utils::ObjectShare::COMMA).map do |s|
87
- host, port = s.split(Contrast::Utils::ObjectShare::COLON)
88
-
89
- ac = Contrast::Api::Dtm::ArchitectureComponent.new
90
- ac.vendor = Contrast::Utils::StringUtils.force_utf8(adapter)
91
- ac.remote_host = Contrast::Utils::StringUtils.force_utf8(host)
92
- ac.remote_port = port.to_i
93
- ac.type = AC_TYPE_DB
94
- ac.url = Contrast::Utils::StringUtils.force_utf8(database)
95
- acs << ac
96
- end
97
- acs
98
- end
99
-
100
- def self.split_connection_str str
101
- adapter, str = str.split(Contrast::Utils::ObjectShare::COLON_SLASH_SLASH)
102
- _auth, str = str.split(Contrast::Utils::ObjectShare::AT)
103
- # Not currently used
104
- # user, pass = auth.split(Contrast::Utils::ObjectShare::COLON)
105
- hosts, db_and_options = str.split(Contrast::Utils::ObjectShare::SLASH)
106
- hosts << LOCALHOST if hosts.empty?
107
- database, _options = db_and_options.split(Contrast::Utils::ObjectShare::QUESTION_MARK)
108
-
109
- [adapter, hosts, database]
110
- end
111
- end
112
- end
113
- end