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.
- checksums.yaml +4 -4
- data/ext/cs__assess_array/cs__assess_array.c +1 -1
- data/ext/cs__assess_module/cs__assess_module.c +0 -1
- data/ext/cs__assess_yield_track/cs__assess_yield_track.c +34 -0
- data/ext/cs__assess_yield_track/cs__assess_yield_track.h +12 -0
- data/ext/{cs__scope → cs__assess_yield_track}/extconf.rb +0 -0
- data/ext/cs__common/cs__common.c +6 -6
- data/ext/cs__common/cs__common.h +3 -1
- data/ext/cs__contrast_patch/cs__contrast_patch.c +142 -119
- data/ext/cs__contrast_patch/cs__contrast_patch.h +3 -0
- data/funchook/autom4te.cache/requests +48 -48
- data/funchook/config.log +2 -2
- data/lib/contrast/agent.rb +15 -5
- data/lib/contrast/agent/assess.rb +0 -1
- data/lib/contrast/agent/assess/contrast_event.rb +9 -8
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +68 -18
- data/lib/contrast/agent/assess/policy/policy.rb +0 -14
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
- data/lib/contrast/agent/assess/policy/preshift.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagation_method.rb +4 -2
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator/split.rb +166 -1
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +1 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +199 -140
- data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +30 -0
- data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +36 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +238 -153
- data/lib/contrast/agent/assess/policy/trigger_node.rb +54 -9
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +13 -0
- data/lib/contrast/agent/assess/properties.rb +29 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +35 -31
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +1 -1
- data/lib/contrast/agent/class_reopener.rb +98 -55
- data/lib/contrast/agent/feature_state.rb +1 -1
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/logger_manager.rb +2 -2
- data/lib/contrast/agent/middleware.rb +1 -3
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +40 -4
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +33 -8
- data/lib/contrast/agent/patching/policy/method_policy.rb +20 -7
- data/lib/contrast/agent/patching/policy/patch.rb +54 -23
- data/lib/contrast/agent/patching/policy/patch_status.rb +0 -2
- data/lib/contrast/agent/patching/policy/patcher.rb +10 -11
- data/lib/contrast/agent/patching/policy/policy.rb +4 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +14 -1
- data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -1
- data/lib/contrast/agent/protect/policy/policy.rb +6 -6
- data/lib/contrast/agent/protect/rule/base.rb +1 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +3 -25
- data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
- data/lib/contrast/agent/railtie.rb +11 -5
- data/lib/contrast/agent/request.rb +1 -19
- data/lib/contrast/agent/request_context.rb +1 -1
- data/lib/contrast/agent/rewriter.rb +4 -3
- data/lib/contrast/agent/scope.rb +116 -19
- data/lib/contrast/agent/service_heartbeat.rb +5 -2
- data/lib/contrast/agent/settings_state.rb +12 -8
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api.rb +1 -0
- data/lib/contrast/api/speedracer.rb +2 -2
- data/lib/contrast/components/agent.rb +26 -7
- data/lib/contrast/components/app_context.rb +8 -45
- data/lib/contrast/components/contrast_service.rb +3 -4
- data/lib/contrast/components/interface.rb +1 -1
- data/lib/contrast/components/scope.rb +56 -26
- data/lib/contrast/config/ruby_configuration.rb +8 -3
- data/lib/contrast/delegators.rb +9 -0
- data/lib/contrast/delegators/application_update.rb +32 -0
- data/lib/contrast/extensions/framework/rack/cookie.rb +24 -0
- data/lib/contrast/extensions/framework/rack/request.rb +24 -0
- data/lib/contrast/extensions/framework/rack/response.rb +23 -0
- data/lib/contrast/extensions/framework/rails/action_controller_railties_helper_inherited.rb +20 -0
- data/lib/contrast/extensions/framework/rails/active_record.rb +26 -0
- data/lib/contrast/extensions/framework/rails/active_record_named.rb +53 -0
- data/lib/contrast/extensions/framework/rails/active_record_time_zone_inherited.rb +21 -0
- data/lib/contrast/extensions/framework/rails/buffer.rb +28 -0
- data/lib/contrast/extensions/framework/rails/configuration.rb +27 -0
- data/lib/contrast/extensions/framework/sinatra/base.rb +59 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess.rb +12 -11
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/array.rb +4 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/assess_extension.rb +0 -2
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/basic_object.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/erb.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/exec_trigger.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/fiber.rb +3 -4
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/hash.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/kernel.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/module.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/regexp.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/string.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/tilt_template_trigger.rb +0 -0
- data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +40 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/delegator.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/eval_trigger.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory/datastores.rb +1 -1
- data/lib/contrast/extensions/ruby_core/module.rb +17 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_command_injection_rule.rb +8 -6
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_deserialization_rule.rb +7 -5
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_no_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_path_traversal_rule.rb +31 -27
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_sqli_rule.rb +5 -3
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_xxe_rule.rb +9 -7
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/kernel.rb +0 -0
- data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/psych.rb +1 -1
- data/lib/contrast/{core_extensions → extensions/ruby_core}/thread.rb +0 -0
- data/lib/contrast/framework/base_support.rb +63 -0
- data/lib/contrast/framework/manager.rb +109 -0
- data/lib/contrast/framework/platform_version.rb +21 -0
- data/lib/contrast/framework/rails_support.rb +88 -0
- data/lib/contrast/framework/sinatra_application_helper.rb +49 -0
- data/lib/contrast/framework/sinatra_support.rb +94 -0
- data/lib/contrast/framework/view_technologies_descriptor.rb +20 -0
- data/lib/contrast/utils/assess/tracking_util.rb +2 -4
- data/lib/contrast/utils/class_util.rb +92 -37
- data/lib/contrast/utils/duck_utils.rb +59 -39
- data/lib/contrast/utils/environment_util.rb +5 -75
- data/lib/contrast/utils/freeze_util.rb +3 -7
- data/lib/contrast/utils/invalid_configuration_util.rb +5 -5
- data/lib/contrast/utils/job_servers_running.rb +39 -0
- data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -2
- data/lib/contrast/utils/service_response_util.rb +0 -6
- data/lib/contrast/utils/sinatra_helper.rb +6 -0
- data/lib/contrast/utils/stack_trace_utils.rb +1 -1
- data/resources/assess/policy.json +74 -23
- data/resources/inventory/policy.json +1 -1
- data/resources/protect/policy.json +11 -9
- data/resources/rubocops/object/frozen_cop.rb +1 -1
- data/ruby-agent.gemspec +2 -0
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +94 -57
- data/ext/cs__scope/cs__scope.c +0 -96
- data/ext/cs__scope/cs__scope.h +0 -33
- data/lib/contrast/agent/assess/class_reverter.rb +0 -82
- data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +0 -28
- data/lib/contrast/core_extensions/module.rb +0 -42
- data/lib/contrast/core_extensions/object.rb +0 -27
- data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +0 -48
- data/lib/contrast/rails_extensions/assess/active_record.rb +0 -32
- data/lib/contrast/rails_extensions/assess/active_record_named.rb +0 -61
- data/lib/contrast/rails_extensions/assess/configuration.rb +0 -26
- data/lib/contrast/rails_extensions/buffer.rb +0 -30
- data/lib/contrast/rails_extensions/rack.rb +0 -45
- data/lib/contrast/sinatra_extensions/assess/cookie.rb +0 -26
- data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +0 -59
- data/lib/contrast/utils/operating_environment.rb +0 -38
- data/lib/contrast/utils/path_util.rb +0 -151
- data/lib/contrast/utils/scope_util.rb +0 -99
data/ext/cs__scope/cs__scope.h
DELETED
@@ -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
|