contrast-agent 3.8.5 → 3.9.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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_array/cs__assess_array.c +1 -1
  3. data/ext/cs__assess_module/cs__assess_module.c +0 -1
  4. data/ext/cs__assess_yield_track/cs__assess_yield_track.c +34 -0
  5. data/ext/cs__assess_yield_track/cs__assess_yield_track.h +12 -0
  6. data/ext/{cs__scope → cs__assess_yield_track}/extconf.rb +0 -0
  7. data/ext/cs__common/cs__common.c +6 -6
  8. data/ext/cs__common/cs__common.h +3 -1
  9. data/ext/cs__contrast_patch/cs__contrast_patch.c +142 -119
  10. data/ext/cs__contrast_patch/cs__contrast_patch.h +3 -0
  11. data/funchook/autom4te.cache/requests +48 -48
  12. data/funchook/config.log +2 -2
  13. data/lib/contrast/agent.rb +15 -5
  14. data/lib/contrast/agent/assess.rb +0 -1
  15. data/lib/contrast/agent/assess/contrast_event.rb +9 -8
  16. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +68 -18
  17. data/lib/contrast/agent/assess/policy/policy.rb +0 -14
  18. data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
  19. data/lib/contrast/agent/assess/policy/preshift.rb +1 -1
  20. data/lib/contrast/agent/assess/policy/propagation_method.rb +4 -2
  21. data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
  22. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
  23. data/lib/contrast/agent/assess/policy/propagator/splat.rb +2 -2
  24. data/lib/contrast/agent/assess/policy/propagator/split.rb +166 -1
  25. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +1 -0
  26. data/lib/contrast/agent/assess/policy/source_method.rb +199 -140
  27. data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +30 -0
  28. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +36 -0
  29. data/lib/contrast/agent/assess/policy/trigger_method.rb +238 -153
  30. data/lib/contrast/agent/assess/policy/trigger_node.rb +54 -9
  31. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +13 -0
  32. data/lib/contrast/agent/assess/properties.rb +29 -0
  33. data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +35 -31
  34. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +1 -1
  35. data/lib/contrast/agent/class_reopener.rb +98 -55
  36. data/lib/contrast/agent/feature_state.rb +1 -1
  37. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  38. data/lib/contrast/agent/logger_manager.rb +2 -2
  39. data/lib/contrast/agent/middleware.rb +1 -3
  40. data/lib/contrast/agent/patching/policy/after_load_patch.rb +40 -4
  41. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +33 -8
  42. data/lib/contrast/agent/patching/policy/method_policy.rb +20 -7
  43. data/lib/contrast/agent/patching/policy/patch.rb +54 -23
  44. data/lib/contrast/agent/patching/policy/patch_status.rb +0 -2
  45. data/lib/contrast/agent/patching/policy/patcher.rb +10 -11
  46. data/lib/contrast/agent/patching/policy/policy.rb +4 -0
  47. data/lib/contrast/agent/patching/policy/policy_node.rb +14 -1
  48. data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -1
  49. data/lib/contrast/agent/protect/policy/policy.rb +6 -6
  50. data/lib/contrast/agent/protect/rule/base.rb +1 -1
  51. data/lib/contrast/agent/protect/rule/deserialization.rb +3 -25
  52. data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
  53. data/lib/contrast/agent/railtie.rb +11 -5
  54. data/lib/contrast/agent/request.rb +1 -19
  55. data/lib/contrast/agent/request_context.rb +1 -1
  56. data/lib/contrast/agent/rewriter.rb +4 -3
  57. data/lib/contrast/agent/scope.rb +116 -19
  58. data/lib/contrast/agent/service_heartbeat.rb +5 -2
  59. data/lib/contrast/agent/settings_state.rb +12 -8
  60. data/lib/contrast/agent/version.rb +1 -1
  61. data/lib/contrast/api.rb +1 -0
  62. data/lib/contrast/api/speedracer.rb +2 -2
  63. data/lib/contrast/components/agent.rb +26 -7
  64. data/lib/contrast/components/app_context.rb +8 -45
  65. data/lib/contrast/components/contrast_service.rb +3 -4
  66. data/lib/contrast/components/interface.rb +1 -1
  67. data/lib/contrast/components/scope.rb +56 -26
  68. data/lib/contrast/config/ruby_configuration.rb +8 -3
  69. data/lib/contrast/delegators.rb +9 -0
  70. data/lib/contrast/delegators/application_update.rb +32 -0
  71. data/lib/contrast/extensions/framework/rack/cookie.rb +24 -0
  72. data/lib/contrast/extensions/framework/rack/request.rb +24 -0
  73. data/lib/contrast/extensions/framework/rack/response.rb +23 -0
  74. data/lib/contrast/extensions/framework/rails/action_controller_railties_helper_inherited.rb +20 -0
  75. data/lib/contrast/extensions/framework/rails/active_record.rb +26 -0
  76. data/lib/contrast/extensions/framework/rails/active_record_named.rb +53 -0
  77. data/lib/contrast/extensions/framework/rails/active_record_time_zone_inherited.rb +21 -0
  78. data/lib/contrast/extensions/framework/rails/buffer.rb +28 -0
  79. data/lib/contrast/extensions/framework/rails/configuration.rb +27 -0
  80. data/lib/contrast/extensions/framework/sinatra/base.rb +59 -0
  81. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess.rb +12 -11
  82. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/array.rb +4 -3
  83. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/assess_extension.rb +0 -2
  84. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/basic_object.rb +1 -1
  85. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/erb.rb +0 -0
  86. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/exec_trigger.rb +0 -0
  87. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/fiber.rb +3 -4
  88. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/hash.rb +0 -0
  89. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/kernel.rb +1 -1
  90. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/module.rb +1 -1
  91. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/regexp.rb +0 -0
  92. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/string.rb +0 -0
  93. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/tilt_template_trigger.rb +0 -0
  94. data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +40 -0
  95. data/lib/contrast/{core_extensions → extensions/ruby_core}/delegator.rb +0 -0
  96. data/lib/contrast/{core_extensions → extensions/ruby_core}/eval_trigger.rb +1 -1
  97. data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory.rb +0 -0
  98. data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory/datastores.rb +1 -1
  99. data/lib/contrast/extensions/ruby_core/module.rb +17 -0
  100. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect.rb +0 -0
  101. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_command_injection_rule.rb +8 -6
  102. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_deserialization_rule.rb +7 -5
  103. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_no_sqli_rule.rb +5 -3
  104. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_path_traversal_rule.rb +31 -27
  105. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_sqli_rule.rb +5 -3
  106. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_xxe_rule.rb +9 -7
  107. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/kernel.rb +0 -0
  108. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/psych.rb +1 -1
  109. data/lib/contrast/{core_extensions → extensions/ruby_core}/thread.rb +0 -0
  110. data/lib/contrast/framework/base_support.rb +63 -0
  111. data/lib/contrast/framework/manager.rb +109 -0
  112. data/lib/contrast/framework/platform_version.rb +21 -0
  113. data/lib/contrast/framework/rails_support.rb +88 -0
  114. data/lib/contrast/framework/sinatra_application_helper.rb +49 -0
  115. data/lib/contrast/framework/sinatra_support.rb +94 -0
  116. data/lib/contrast/framework/view_technologies_descriptor.rb +20 -0
  117. data/lib/contrast/utils/assess/tracking_util.rb +2 -4
  118. data/lib/contrast/utils/class_util.rb +92 -37
  119. data/lib/contrast/utils/duck_utils.rb +59 -39
  120. data/lib/contrast/utils/environment_util.rb +5 -75
  121. data/lib/contrast/utils/freeze_util.rb +3 -7
  122. data/lib/contrast/utils/invalid_configuration_util.rb +5 -5
  123. data/lib/contrast/utils/job_servers_running.rb +39 -0
  124. data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -2
  125. data/lib/contrast/utils/service_response_util.rb +0 -6
  126. data/lib/contrast/utils/sinatra_helper.rb +6 -0
  127. data/lib/contrast/utils/stack_trace_utils.rb +1 -1
  128. data/resources/assess/policy.json +74 -23
  129. data/resources/inventory/policy.json +1 -1
  130. data/resources/protect/policy.json +11 -9
  131. data/resources/rubocops/object/frozen_cop.rb +1 -1
  132. data/ruby-agent.gemspec +2 -0
  133. data/service_executables/VERSION +1 -1
  134. data/service_executables/linux/contrast-service +0 -0
  135. data/service_executables/mac/contrast-service +0 -0
  136. metadata +94 -57
  137. data/ext/cs__scope/cs__scope.c +0 -96
  138. data/ext/cs__scope/cs__scope.h +0 -33
  139. data/lib/contrast/agent/assess/class_reverter.rb +0 -82
  140. data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +0 -28
  141. data/lib/contrast/core_extensions/module.rb +0 -42
  142. data/lib/contrast/core_extensions/object.rb +0 -27
  143. data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +0 -48
  144. data/lib/contrast/rails_extensions/assess/active_record.rb +0 -32
  145. data/lib/contrast/rails_extensions/assess/active_record_named.rb +0 -61
  146. data/lib/contrast/rails_extensions/assess/configuration.rb +0 -26
  147. data/lib/contrast/rails_extensions/buffer.rb +0 -30
  148. data/lib/contrast/rails_extensions/rack.rb +0 -45
  149. data/lib/contrast/sinatra_extensions/assess/cookie.rb +0 -26
  150. data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +0 -59
  151. data/lib/contrast/utils/operating_environment.rb +0 -38
  152. data/lib/contrast/utils/path_util.rb +0 -151
  153. data/lib/contrast/utils/scope_util.rb +0 -99
@@ -1,33 +0,0 @@
1
- #include <ruby.h>
2
-
3
- VALUE rbzero = INT2NUM(0);
4
- VALUE scope_class;
5
- VALUE rb_sym_new;
6
-
7
- const char *ivar_contrast_scope;
8
-
9
- VALUE CONTRAST_SCOPE;
10
-
11
- VALUE in_given_scope(const VALUE object, const char *scope);
12
-
13
- void enter_given_scope(const VALUE object, const char *scope);
14
-
15
- void exit_given_scope(const VALUE object, const char *scope);
16
-
17
- VALUE in_contrast_scope(const VALUE self);
18
-
19
- VALUE enter_contrast_scope(const VALUE self);
20
-
21
- VALUE exit_contrast_scope(const VALUE self);
22
-
23
- VALUE run_in_scope(const VALUE self);
24
-
25
- VALUE enter_scope_for(const VALUE self, const VALUE scope_symbol);
26
-
27
- VALUE exit_scope_for(const VALUE self, const VALUE scope_symbol);
28
-
29
- VALUE initialize(const VALUE self);
30
-
31
- VALUE deep_clone(const VALUE self);
32
-
33
- void Init_cs__scope(void);
@@ -1,82 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/components/interface'
5
- cs__scoped_require 'contrast/core_extensions/module'
6
- cs__scoped_require 'contrast/utils/object_share'
7
-
8
- module Contrast
9
- module Agent
10
- module Assess
11
- # This is used to revert, or undo, the patches that we've placed into
12
- # modules. This is necessary for those cases where the original method
13
- # was supposed to be removed, but wasn't b/c we had renamed it -- looking
14
- # at you, FactoryBot
15
- class ClassReverter
16
- include Contrast::Components::Interface
17
- access_component :logging, :scope
18
-
19
- class << self
20
- def unpatch!
21
- Contrast::Agent::FeatureState.instance.uninstrument_namespaces.
22
- each { |mod_sym| revert_module mod_sym }
23
- end
24
-
25
- private
26
-
27
- def revert_module mod
28
- with_contrast_scope do
29
- revert_child_modules(mod, [])
30
- end
31
- rescue StandardError => e
32
- logger.error(e, "Unable to remove patches from the module #{ mod }")
33
- end
34
-
35
- def revert_child_modules mod, reverted_modules, parent_mod = nil
36
- return if parent_mod == mod
37
- return if reverted_modules.include?(mod)
38
-
39
- reverted_modules << mod
40
-
41
- immediate_constants = mod.cs__constants(false).collect! { |k| mod.cs__const_get(k) }
42
- immediate_constants.select! { |k| k.is_a?(Module) }
43
- immediate_constants.flatten!
44
- if immediate_constants.any?
45
- immediate_constants.each do |const|
46
- revert_aliases(const)
47
- revert_child_modules(const, reverted_modules, mod)
48
- end
49
- else
50
- revert_aliases(mod)
51
- end
52
- end
53
-
54
- # in order to fully uninstrument classes we must use true when getting the singleton/instance methods
55
- # that way if a class makes use of instance_eval for instance(defined on Kernel) we are able to revert this
56
- # specific instance of that method to use the default behavior while leaving the remainder of
57
- # objects using the patched behavior
58
- def revert_aliases clazz
59
- marker = Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START
60
- instance_methods = (clazz.instance_methods(true) + clazz.private_instance_methods(true)).select { |method| method.to_s.start_with?(marker) }
61
- singleton_methods = clazz.cs__singleton_class.instance_methods(true).select { |method| method.to_s.start_with?(marker) }
62
- instance_methods.each { |i_method| revert_alias(clazz, i_method, instance_methods) }
63
- singleton_methods.each { |s_method| revert_alias(clazz.cs__singleton_class, s_method, singleton_methods) }
64
- end
65
-
66
- def revert_alias clazz, current_method_name, methods
67
- original_method_name = clazz.instance_method(current_method_name).original_name
68
-
69
- is_private = clazz.private_method_defined?(original_method_name)
70
-
71
- # revert aliasing only for those methods currently defined on the original
72
- if is_private || clazz.method_defined?(original_method_name)
73
- clazz.send(:alias_method, original_method_name, current_method_name)
74
- clazz.send(:private, original_method_name) if is_private
75
- end
76
- clazz.send(:undef_method, current_method_name) if methods.include?(current_method_name)
77
- end
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,28 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/agent/assess/class_reverter'
5
- cs__scoped_require 'contrast/components/interface'
6
-
7
- module Contrast
8
- module Agent
9
- module Patching
10
- module Policy
11
- # This is how we unpatch out of our customer's code. It provides a way
12
- # to remove ourselves from those modules which have since had their
13
- # definition of the patched method revoked, such as when running with
14
- # FactoryBot
15
- module PolicyUnpatcher
16
- include Contrast::Components::Interface
17
- access_component :logging
18
-
19
- def self.revert_conflicting_patches
20
- logger.debug_with_time("\t\tRunning reversions") do
21
- Contrast::Agent::Assess::ClassReverter.unpatch!
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,42 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/utils/object_share'
5
-
6
- # Some developers override various methods on Module, which can often involve
7
- # changing expected method parity/behavior which in turn prevents us from being
8
- # able to reliably use affected methods. Let's alias these method so that we
9
- # always have access to them.
10
- class Module
11
- alias_method :cs__name, :name
12
- alias_method :cs__constants, :constants
13
- alias_method :cs__const_defined?, :const_defined?
14
- alias_method :cs__const_get, :const_get
15
- alias_method :cs__const_set, :const_set
16
- alias_method :cs__autoload?, :autoload?
17
-
18
- # The method const_defined? can cause autoload, which is bad for us. The
19
- # method autoload? doesn't traverse namespaces. This method lets us provide a
20
- # constant, as a String, and parse it to determine if it has been truly
21
- # truly defined, meaning it existed before this method was invoked, not as a
22
- # result of it.
23
- #
24
- # @param name [String] the name of the constant to look up
25
- # @return [Boolean]
26
- def cs__truly_defined? name
27
- return false unless name
28
-
29
- segments = name.split(Contrast::Utils::ObjectShare::DOUBLE_COLON)
30
- previous_module = Module
31
- segments.each do |segment|
32
- return false if previous_module.cs__autoload?(segment)
33
- return false unless previous_module.cs__const_defined?(segment)
34
-
35
- previous_module = previous_module.cs__const_get(segment)
36
- end
37
-
38
- true
39
- rescue NameError # account for nonsense / poorly formatted constants
40
- false
41
- end
42
- end
@@ -1,27 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/utils/object_share'
5
-
6
- # Some aliases within Object have to happen especially early, because they're
7
- # core to class definitions. See lib/contrast.rb.
8
- # ONLY very core aliasing should go there. All the routine extension should
9
- # happen here, where you'd expect it.
10
- class Object
11
- # Return a String representing the self invoking this method.
12
- def cs__inspect
13
- if cs__is_a?(String)
14
- return Contrast::Utils::ObjectShare::EMPTY_STRING if empty?
15
-
16
- dup
17
- elsif cs__is_a?(Symbol)
18
- ":#{ self }"
19
- elsif cs__is_a?(Numeric)
20
- to_s
21
- elsif cs__is_a?(Module)
22
- "#{ cs__name }@#{ __id__ }"
23
- else
24
- "#{ cs__class.cs__name }@#{ __id__ }"
25
- end
26
- end
27
- end
@@ -1,48 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- if defined?(ActionController) &&
5
- defined?(ActionController::Railties) &&
6
- defined?(ActionController::Railties::Helpers)
7
- module ActionController
8
- module Railties
9
- # Used to monkey patch all the inherited calls in action_pack
10
- #
11
- # This is the usual entry point for Rails inheritance work, so it should
12
- # catch most of the calls to inherited.
13
- module Helpers
14
- alias_method :cs__patched_inherited, :inherited
15
- def inherited klass
16
- klass&.instance_variable_set(:@cs__defining_class, true)
17
- cs__patched_inherited(klass)
18
- ensure
19
- klass&.instance_variable_set(:@cs__defining_class, false)
20
- end
21
- end
22
- end
23
- end
24
- end
25
-
26
- if defined?(ActiveRecord) &&
27
- defined?(ActiveRecord::AttributeMethods) &&
28
- defined?(ActiveRecord::AttributeMethods::TimeZoneConversion) &&
29
- defined?(ActiveRecord::AttributeMethods::TimeZoneConversion::ClassMethods)
30
- module ActiveRecord
31
- module AttributeMethods
32
- # Used to monkey patch all the inherited calls in action_pack
33
- module TimeZoneConversion
34
- module ClassMethods #:nodoc:
35
- private
36
-
37
- alias_method :cs__patched_inherited, :inherited
38
- def inherited klass
39
- klass&.instance_variable_set(:@cs__defining_class, true)
40
- cs__patched_inherited(klass)
41
- ensure
42
- klass&.instance_variable_set(:@cs__defining_class, false)
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,32 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- if defined?(ActiveRecord) &&
5
- defined?(ActiveRecord::AttributeMethods) &&
6
- defined?(ActiveRecord::AttributeMethods::Read) &&
7
- defined?(ActiveRecord::AttributeMethods::Read::ClassMethods)
8
-
9
- module ActiveRecord
10
- module AttributeMethods
11
- module Read
12
- # Rails / ActiveRecord are sneaky a.f. They define attributes of a
13
- # class in one method, then monkey patch allocate in another and
14
- # finally invoke module_eval in this method... but of course they use a
15
- # '_tmp_' header for the method name and then alias it in this module
16
- # to name it what we expect
17
- module ClassMethods
18
- alias_method :cs__patched_define_method_attribute, :define_method_attribute
19
-
20
- def define_method_attribute *args, &block
21
- ret = cs__patched_define_method_attribute(*args, &block)
22
- method_name = args[0]
23
- Contrast::Agent::Assess::Policy::Patcher.patch_assess_method(self, method_name)
24
- ret
25
- end
26
-
27
- protected :cs__patched_define_method_attribute, :define_method_attribute
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,61 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/components/interface'
5
-
6
- if defined?(ActiveRecord) &&
7
- defined?(ActiveRecord::Scoping) &&
8
- defined?(ActiveRecord::Scoping::Named) &&
9
- defined?(ActiveRecord::Scoping::Named::ClassMethods) &&
10
- ActiveRecord::Scoping::Named::ClassMethods.
11
- instance_methods(false).
12
- include?(:scope)
13
- module ActiveRecord
14
- module Scoping
15
- module Named
16
- # Our patch into the ActiveRecord::Scoping::Named::ClassMethods Module,
17
- # allowing for the runtime rewrite of interpolation calls defined in
18
- # methods defined dynamically during application execution.
19
- #
20
- # TODO: RUBY-534
21
- module ClassMethods
22
- include Contrast::Components::Interface
23
- access_component :logging, :agent
24
-
25
- def _cs__rewrite method_name, body
26
- return body unless AGENT.rewrite_interpolation?
27
- return body unless body.is_a?(Proc)
28
-
29
- location = body.source_location
30
- return body if location.nil?
31
-
32
- # Good news, once we patch the body once, the source location
33
- # becomes eval. We may need to fix this later though (so it may
34
- # be bad news)
35
- return body if location.empty? || location[0].empty? || location[0].include?('eval')
36
-
37
- opener = Contrast::Agent::ClassReopener.new(Contrast::Agent::ModuleData.new(self))
38
- original_source_code = opener.source_code(location, method_name)
39
- return body unless original_source_code
40
- return body if Contrast::Agent::Rewriter.send(:unrepeatable?, original_source_code)
41
- return body unless Contrast::Agent::Rewriter.send(:interpolations?, original_source_code)
42
-
43
- # the code looks like 'source :some_method_name, ->lambda_literal'
44
- # we just need the lambda
45
- body_start = original_source_code.index(',') + 1
46
- original_source_code = original_source_code[body_start..-1]
47
-
48
- new_method_source = Contrast::Agent::Rewriter.send(:rewrite_method, original_source_code)
49
- return body unless Contrast::Agent::Rewriter.send(:valid_code?, new_method_source)
50
-
51
- unbound_eval(cs__name, new_method_source)
52
- rescue SyntaxError, StandardError => e
53
- logger.debug(e, "Can't parse method source in scoped method #{ method_name }: #{ e.message }")
54
- body
55
- end
56
- end
57
- end
58
- end
59
- end
60
- cs__scoped_require 'cs__assess_active_record_named/cs__assess_active_record_named'
61
- end
@@ -1,26 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: false
3
-
4
- if defined?(Rails) && defined?(Rails::Application) && defined?(Rails::Application::Configuration)
5
- module Rails
6
- class Application
7
- # Our patch into the Rails::Application::Configuration Class, allowing
8
- # for the runtime detection of insecure configurations on individual
9
- # ActionDispatch::Session::AbstractStore instances within the
10
- # application.
11
- class Configuration
12
- include Contrast::Utils::InvalidConfigurationUtil
13
- include Contrast::Components::Interface
14
-
15
- access_component :analysis, :scope
16
-
17
- alias_method :cs__patched_session_store, :session_store
18
- def session_store *args
19
- ret = cs__patched_session_store(*args)
20
- Contrast::Utils::RailsAssessConfiguration.analyze_session_store(*args)
21
- ret
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,30 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- cs__scoped_require 'contrast/components/interface'
5
-
6
- if defined?(ActionController) && defined?(ActionController::Live) && defined?(ActionController::Live::Buffer)
7
- module ActionController
8
- module Live
9
- # This class acts as our patch into the ActionController::Live::Buffer
10
- # class, allowing us to track the close event on streamed responses.
11
- class Buffer
12
- include Contrast::Components::Interface
13
- access_component :contrast_service
14
-
15
- # normally pre->in->post filters are applied however, in a streamed response
16
- # we can run into a case where it's pre -> in -> post -> more infilters
17
- # in order to submit anything found during the infilters after the response has been written we need to explicity send them
18
- alias_method :cs__close, :close
19
- def close
20
- if (context = Contrast::Agent::REQUEST_TRACKER.current)
21
- [context.server_activity, context.activity, context.observed_route].each do |msg|
22
- CONTRAST_SERVICE.send_message msg
23
- end
24
- end
25
- cs__close
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,45 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- if defined?(Rack)
5
- # In earlier versions of rack < 2.0.0 the Rack::Response and Rack::Request do
6
- # not have get_header or set_header methods. This is our way of working
7
- # around that.
8
- module Rack
9
- if defined?(Rack::Request)
10
- # Our patch into the Rack::Request class, allowing us to call set_header
11
- # and get_header in our code without worrying about older versions of
12
- # Rack not implementing these methods.
13
- class Request
14
- unless Rack::Request.instance_methods(true).include?(:set_header)
15
- def set_header name, value
16
- @env[name] = value
17
- end
18
- end
19
- unless Rack::Request.instance_methods(true).include?(:get_header)
20
- def get_header name
21
- @env[name]
22
- end
23
- end
24
- end
25
- end
26
-
27
- if defined?(Rack::Response)
28
- # Our patch into the Rack::Response Class, allowing us to call set_header
29
- # and get_header in our code without worrying about older versions of
30
- # Rack not implementing these methods.
31
- class Response
32
- unless Rack::Response.instance_methods(true).include?(:set_header)
33
- def set_header key, value
34
- headers[key] = value
35
- end
36
- end
37
- unless Rack::Response.instance_methods(true).include?(:get_header)
38
- def get_header key
39
- headers[key]
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end