contrast-agent 3.8.5 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
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