tcell_agent 2.2.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/bin/tcell_agent +6 -11
- data/lib/tcell_agent/agent.rb +18 -13
- data/lib/tcell_agent/config_initializer.rb +2 -5
- data/lib/tcell_agent/configuration.rb +6 -6
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation/cmdi.rb +32 -0
- data/lib/tcell_agent/instrumentation/lfi.rb +55 -9
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/logger.rb +2 -2
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +1 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp.rb +48 -48
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +1 -5
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/routes/grape.rb +2 -1
- data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -6
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +20 -2
- data/lib/tcell_agent/rust/{libtcellagent-5.0.2.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{tcellagent-5.0.2.dll → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-5.0.2.dylib → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-5.0.2.so → libtcellagent.so} +0 -0
- data/lib/tcell_agent/rust/native_agent.rb +51 -59
- data/lib/tcell_agent/rust/native_library.rb +7 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +25 -8
- data/lib/tcell_agent/servers/rack_puma_handler.rb +13 -3
- data/lib/tcell_agent/servers/webrick.rb +13 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -14
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +15 -6
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +1 -1
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +207 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +89 -70
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +73 -0
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -16
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +3 -1
- data/spec/support/builders.rb +2 -1
- data/spec/support/server_mocks/puma_mock.rb +4 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +23 -19
- data/Rakefile +0 -18
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -131
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -102
|
@@ -6,22 +6,20 @@ module TCellAgent
|
|
|
6
6
|
require 'ffi'
|
|
7
7
|
extend FFI::Library
|
|
8
8
|
|
|
9
|
-
VERSION = '5.0.2'.freeze
|
|
10
|
-
prefix = 'lib'
|
|
11
9
|
extension = '.so'
|
|
12
10
|
variant = ''
|
|
13
11
|
if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
|
12
|
+
variant = '-x64'
|
|
14
13
|
extension = '.dll'
|
|
15
|
-
prefix = ''
|
|
16
14
|
elsif /darwin/ =~ RUBY_PLATFORM
|
|
17
15
|
extension = '.dylib'
|
|
18
16
|
elsif /musl/ =~ RUBY_PLATFORM
|
|
19
|
-
variant = 'alpine
|
|
17
|
+
variant = '-alpine'
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
begin
|
|
23
21
|
ffi_lib File.join(File.dirname(__FILE__),
|
|
24
|
-
"#{
|
|
22
|
+
"libtcellagent#{variant}#{extension}")
|
|
25
23
|
|
|
26
24
|
# All the rust library calls have the following response api:
|
|
27
25
|
#
|
|
@@ -36,6 +34,7 @@ module TCellAgent
|
|
|
36
34
|
attach_function :poll_new_policies, %i[pointer pointer size_t], :int
|
|
37
35
|
attach_function :appfirewall_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
38
36
|
attach_function :patches_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
37
|
+
attach_function :suspicious_quick_check_apply, %i[pointer pointer size_t], :int
|
|
39
38
|
attach_function :cmdi_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
40
39
|
attach_function :get_headers, %i[pointer pointer size_t pointer size_t], :int
|
|
41
40
|
attach_function :get_js_agent_script_tag, %i[pointer pointer size_t pointer size_t], :int
|
|
@@ -48,17 +47,15 @@ module TCellAgent
|
|
|
48
47
|
attach_function :log_message, %i[pointer pointer size_t pointer size_t], :int
|
|
49
48
|
|
|
50
49
|
attach_function :update_policies, %i[pointer pointer size_t pointer size_t], :int
|
|
51
|
-
attach_function :test_event_sender, %i[pointer size_t pointer size_t], :int
|
|
52
|
-
attach_function :test_policies, %i[pointer size_t pointer size_t], :int
|
|
53
50
|
attach_function :test_agent, %i[pointer size_t pointer size_t], :int
|
|
54
51
|
|
|
55
52
|
def self.common_lib_available?
|
|
56
53
|
true
|
|
57
54
|
end
|
|
58
|
-
rescue LoadError =>
|
|
55
|
+
rescue LoadError => e
|
|
59
56
|
logger = TCellAgent::ModuleLogger.new(TCellAgent::RubyLogger.new, name)
|
|
60
|
-
logger.error("Failed loading agent library. #{
|
|
61
|
-
logger.exception(
|
|
57
|
+
logger.error("Failed loading agent library. #{e.message}")
|
|
58
|
+
logger.exception(e)
|
|
62
59
|
|
|
63
60
|
def self.common_lib_available? # rubocop:disable Lint/DuplicateMethods
|
|
64
61
|
false
|
|
@@ -7,59 +7,6 @@ require 'etc'
|
|
|
7
7
|
|
|
8
8
|
module TCellAgent
|
|
9
9
|
module SensorEvents
|
|
10
|
-
class ServerAgentDetailsSensorEvent < TCellSensorEvent
|
|
11
|
-
include TCellAgent::ModuleLoggerAccess
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
super('server_agent_details')
|
|
15
|
-
@flush = true
|
|
16
|
-
@ensure = true
|
|
17
|
-
|
|
18
|
-
self['user'] = 'unknown'
|
|
19
|
-
self['group'] = 'unknown'
|
|
20
|
-
|
|
21
|
-
begin
|
|
22
|
-
login = Etc.getlogin
|
|
23
|
-
if login
|
|
24
|
-
self['user'] = login
|
|
25
|
-
begin
|
|
26
|
-
info = Etc.getpwnam(login)
|
|
27
|
-
self['group'] = info.gid.to_s
|
|
28
|
-
rescue StandardError => te
|
|
29
|
-
module_logger.debug("Could not get group id: #{te.message}")
|
|
30
|
-
module_logger.exception(te)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
rescue StandardError => to
|
|
34
|
-
module_logger.debug("Could not get user & group: #{to.message}")
|
|
35
|
-
module_logger.exception(te)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
module_logger.debug("User #{self['user']}")
|
|
39
|
-
module_logger.debug("Group #{self['group']}")
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
class ServerAgentDetailsLanguageEvent < TCellSensorEvent
|
|
44
|
-
def initialize(language, language_version)
|
|
45
|
-
super('server_agent_details')
|
|
46
|
-
@flush = true
|
|
47
|
-
@ensure = true
|
|
48
|
-
self['language'] = language
|
|
49
|
-
self['language_version'] = language_version
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
class ServerAgentAppFrameworkEvent < TCellSensorEvent
|
|
54
|
-
def initialize(framework_name, framework_version)
|
|
55
|
-
super('server_agent_details')
|
|
56
|
-
@flush = true
|
|
57
|
-
@ensure = true
|
|
58
|
-
self['app_framework'] = framework_name
|
|
59
|
-
self['app_framework_version'] = framework_version
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
10
|
class ServerAgentPackagesSensorEvent < TCellSensorEvent
|
|
64
11
|
include TCellAgent::ModuleLoggerAccess
|
|
65
12
|
|
|
@@ -75,59 +22,15 @@ module TCellAgent
|
|
|
75
22
|
packages.push(package)
|
|
76
23
|
module_logger.debug("Adding packages #{x.name}")
|
|
77
24
|
end
|
|
78
|
-
rescue StandardError =>
|
|
79
|
-
module_logger.error("Exception adding package: #{
|
|
80
|
-
module_logger.exception(
|
|
25
|
+
rescue StandardError => e
|
|
26
|
+
module_logger.error("Exception adding package: #{e.message}")
|
|
27
|
+
module_logger.exception(e)
|
|
81
28
|
end
|
|
82
29
|
end
|
|
83
30
|
self['packages'] = packages
|
|
84
31
|
end
|
|
85
32
|
end
|
|
86
33
|
|
|
87
|
-
class AppFramework < TCellSensorEvent
|
|
88
|
-
def initialize(name, version)
|
|
89
|
-
super('appserver_framework')
|
|
90
|
-
@flush = false
|
|
91
|
-
@ensure = true
|
|
92
|
-
self['n'] = name
|
|
93
|
-
self['v'] = version
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
class AppAuthFramework < TCellSensorEvent
|
|
98
|
-
def initialize(name, version)
|
|
99
|
-
super('appserver_auth_framework')
|
|
100
|
-
@flush = false
|
|
101
|
-
@ensure = true
|
|
102
|
-
self['n'] = name
|
|
103
|
-
self['v'] = version
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
class AppFrameworkSetting < TCellSensorEvent
|
|
108
|
-
def initialize(framework_name, setting, value)
|
|
109
|
-
super('appserver_framework_setting')
|
|
110
|
-
@flush = false
|
|
111
|
-
@ensure = true
|
|
112
|
-
self['framework'] = framework_name
|
|
113
|
-
self['s'] = setting
|
|
114
|
-
self['v'] = value
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
class AppCookie < TCellSensorEvent
|
|
119
|
-
def initialize(name, value, secure, http_only, session)
|
|
120
|
-
super('appserver_framework_setting')
|
|
121
|
-
@flush = false
|
|
122
|
-
@ensure = true
|
|
123
|
-
self['n'] = name
|
|
124
|
-
self['v'] = value
|
|
125
|
-
self['http_only'] = http_only
|
|
126
|
-
self['secure'] = secure
|
|
127
|
-
self['session'] = session
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
34
|
class AppRoutesSensorEvent < TCellSensorEvent
|
|
132
35
|
def initialize(uri, method, route_id, params = nil, destination = nil)
|
|
133
36
|
super('appserver_routes')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
if defined?(Puma.cli_config)
|
|
2
2
|
if Puma.cli_config.options[:preload_app]
|
|
3
|
-
if Puma.cli_config.options[:workers] == 0
|
|
3
|
+
if Puma.cli_config.options[:workers] == 0
|
|
4
4
|
# Puma is running in single mode, so run both the initial instrumentation and
|
|
5
5
|
# start the agent
|
|
6
6
|
Puma::Runner.class_eval do
|
|
@@ -15,24 +15,41 @@ if defined?(Puma.cli_config)
|
|
|
15
15
|
else
|
|
16
16
|
Puma::Server.class_eval do
|
|
17
17
|
alias_method :tcell_original_run, :run
|
|
18
|
-
def run(background = true)
|
|
19
|
-
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
if defined?(Gem::Version) &&
|
|
20
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
21
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) < Gem::Version.new('5.1.0'))
|
|
22
|
+
def run(background = true)
|
|
23
|
+
TCellAgent.thread_agent.start('Puma')
|
|
24
|
+
original_run(background, options)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
def run(background = true, thread_name: 'server')
|
|
28
|
+
TCellAgent.thread_agent.start('Puma')
|
|
29
|
+
original_run(background, :thread_name => thread_name)
|
|
30
|
+
end
|
|
22
31
|
end
|
|
23
32
|
end
|
|
24
33
|
end
|
|
25
|
-
|
|
26
34
|
else
|
|
27
35
|
# this ensures instrumentation runs for preload_app = false.
|
|
28
36
|
# Instrumentation will run for each worker but there's
|
|
29
37
|
# nothing we can do about that (Unicorn's preload_app behaves the same way)
|
|
30
38
|
Puma::Server.class_eval do
|
|
31
39
|
alias_method :tcell_original_run, :run
|
|
32
|
-
def run(background = true)
|
|
33
|
-
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
if defined?(Gem::Version) &&
|
|
42
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
43
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) < Gem::Version.new('5.1.0'))
|
|
44
|
+
def run(background = true)
|
|
45
|
+
TCellAgent.thread_agent.start('Puma')
|
|
46
|
+
tcell_original_run(background)
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
def run(background = true, thread_name: 'server')
|
|
50
|
+
TCellAgent.thread_agent.start('Puma')
|
|
51
|
+
original_run(background, :thread_name => thread_name)
|
|
52
|
+
end
|
|
36
53
|
end
|
|
37
54
|
end
|
|
38
55
|
end
|
|
@@ -9,10 +9,20 @@ Rack::Handler::Puma.class_eval do
|
|
|
9
9
|
if defined?(Puma::Server) && !Puma::Server.instance_methods.include?(:tcell_original_run)
|
|
10
10
|
Puma::Server.class_eval do
|
|
11
11
|
alias_method :tcell_original_run, :run
|
|
12
|
-
def run(background = true)
|
|
13
|
-
TCellAgent.thread_agent.start('Puma')
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
if defined?(Gem::Version) &&
|
|
14
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
15
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) >= Gem::Version.new('5.1.0'))
|
|
16
|
+
def run(background = true, thread_name: 'server')
|
|
17
|
+
TCellAgent.thread_agent.start('Puma')
|
|
18
|
+
original_run(background, :thread_name => thread_name)
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
def run(background = true)
|
|
22
|
+
TCellAgent.thread_agent.start('Puma')
|
|
23
|
+
|
|
24
|
+
tcell_original_run(background)
|
|
25
|
+
end
|
|
16
26
|
end
|
|
17
27
|
end
|
|
18
28
|
end
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
Rack::Handler::WEBrick.class_eval do
|
|
2
2
|
class << self
|
|
3
3
|
alias_method :original_run, :run
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
if defined?(Gem::Version) &&
|
|
6
|
+
defined?(Rack.release) &&
|
|
7
|
+
Gem::Version.new(Rack.release) < Gem::Version.new('2.2.0')
|
|
8
|
+
def run(app, options = {})
|
|
9
|
+
TCellAgent.thread_agent.start('WEBrick')
|
|
10
|
+
original_run(app, options)
|
|
11
|
+
end
|
|
12
|
+
else
|
|
13
|
+
def run(app, **options)
|
|
14
|
+
TCellAgent.thread_agent.start('WEBrick')
|
|
15
|
+
original_run(app, **options)
|
|
16
|
+
end
|
|
7
17
|
end
|
|
8
18
|
end
|
|
9
19
|
end
|
|
@@ -7,25 +7,11 @@ require 'thread'
|
|
|
7
7
|
module TCellAgent
|
|
8
8
|
def self.report_settings
|
|
9
9
|
Thread.new do
|
|
10
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Agent Details') do
|
|
11
|
-
event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
|
|
12
|
-
TCellAgent.send_event(event)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
10
|
TCellAgent::Instrumentation.safe_block('Instrumenting Server Packages') do
|
|
16
11
|
event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
|
|
17
12
|
TCellAgent.send_event(event)
|
|
18
13
|
end
|
|
19
14
|
|
|
20
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Language Info') do
|
|
21
|
-
TCellAgent.send_event(
|
|
22
|
-
TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
|
|
23
|
-
'Ruby',
|
|
24
|
-
RUBY_VERSION
|
|
25
|
-
)
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
15
|
TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
|
|
30
16
|
require 'tcell_agent/rust/native_agent'
|
|
31
17
|
|
data/lib/tcell_agent/sinatra.rb
CHANGED
|
@@ -16,6 +16,7 @@ module TCellAgent
|
|
|
16
16
|
TCellAgent::Instrumentation.safe_block('Setting Headers') do
|
|
17
17
|
headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HEADERS)
|
|
18
18
|
policy_headers = headers_policy.get_headers(
|
|
19
|
+
headers['Content-Type'],
|
|
19
20
|
request.env[TCellAgent::Instrumentation::TCELL_ID]
|
|
20
21
|
)
|
|
21
22
|
policy_headers.each do |header_info|
|
|
@@ -43,7 +43,8 @@ module TCellAgent
|
|
|
43
43
|
tcell_context.session_id,
|
|
44
44
|
tcell_context.user_id,
|
|
45
45
|
tcell_context.transaction_id,
|
|
46
|
-
tcell_context.uri
|
|
46
|
+
tcell_context.uri,
|
|
47
|
+
tcell_context.reverse_proxy_header_value
|
|
47
48
|
)
|
|
48
49
|
meta_data.path = tcell_context.path
|
|
49
50
|
|
|
@@ -70,7 +71,8 @@ module TCellAgent
|
|
|
70
71
|
:response_headers,
|
|
71
72
|
:csrf_exception_name,
|
|
72
73
|
:sql_exceptions,
|
|
73
|
-
:database_result_sizes
|
|
74
|
+
:database_result_sizes,
|
|
75
|
+
:reverse_proxy_header_value
|
|
74
76
|
|
|
75
77
|
attr_reader :flattened_get_dict,
|
|
76
78
|
:flattened_cookie_dict,
|
|
@@ -85,7 +87,8 @@ module TCellAgent
|
|
|
85
87
|
session_id,
|
|
86
88
|
user_id,
|
|
87
89
|
transaction_id,
|
|
88
|
-
location
|
|
90
|
+
location,
|
|
91
|
+
reverse_proxy_header_value)
|
|
89
92
|
@method = method
|
|
90
93
|
@remote_address = remote_address
|
|
91
94
|
@route_id = route_id
|
|
@@ -93,7 +96,7 @@ module TCellAgent
|
|
|
93
96
|
@user_id = user_id
|
|
94
97
|
@transaction_id = transaction_id
|
|
95
98
|
@location = location
|
|
96
|
-
@
|
|
99
|
+
@reverse_proxy_header_value = reverse_proxy_header_value
|
|
97
100
|
|
|
98
101
|
@flattened_get_dict = {}
|
|
99
102
|
@flattened_cookie_dict = {}
|
|
@@ -148,6 +151,7 @@ module TCellAgent
|
|
|
148
151
|
if !content_length.nil? && content_length > TCELL_MAX_BODY_LENGTH || request.content_type.nil?
|
|
149
152
|
return nil
|
|
150
153
|
end
|
|
154
|
+
|
|
151
155
|
raw_post_data = nil
|
|
152
156
|
# Positions strio to the beginning of input, resetting lineno to zero.
|
|
153
157
|
# rails 4.1 seems to read the stringIO directly and so body.gets is empty
|
|
@@ -171,10 +175,15 @@ module TCellAgent
|
|
|
171
175
|
self.get_dict = request.GET
|
|
172
176
|
self.cookie_dict = request.cookies
|
|
173
177
|
|
|
174
|
-
self.post_dict = if @content_type.start_with?('application/json', 'application/xml')
|
|
178
|
+
self.post_dict = if @content_type.start_with?('application/json', 'application/xml') ||
|
|
179
|
+
(@content_type.start_with?('multipart/form-data') && @request_content_bytes_len == 0)
|
|
175
180
|
{}
|
|
176
181
|
else
|
|
177
|
-
|
|
182
|
+
begin
|
|
183
|
+
request.POST
|
|
184
|
+
rescue EOFError
|
|
185
|
+
{}
|
|
186
|
+
end
|
|
178
187
|
end
|
|
179
188
|
|
|
180
189
|
self.headers_dict = request.env
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module TCellAgent
|
|
2
2
|
module Utils
|
|
3
3
|
module Strings
|
|
4
|
-
BLANK_RE = /\A[[:space:]]*\z
|
|
4
|
+
BLANK_RE = /\A[[:space:]]*\z/.freeze
|
|
5
5
|
|
|
6
6
|
def self.blank?(str)
|
|
7
|
-
str.nil? || str.empty? || BLANK_RE === str
|
|
7
|
+
str.nil? || str.empty? || BLANK_RE === str
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def self.present?(str)
|
data/lib/tcell_agent/version.rb
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'tcell_agent'
|
|
2
|
+
|
|
3
|
+
TCellAgent.configuration.enabled = true
|
|
4
|
+
TCellAgent.configuration.instrument = true
|
|
5
|
+
TCellAgent.configuration.enable_intercept_requests = true
|
|
6
|
+
TCellAgent.configuration.disabled_instrumentation = []
|
|
7
|
+
TCellAgent.thread_agent.instrument_built_ins
|
|
8
|
+
|
|
9
|
+
# This monkey patch turns off blocking for LFI/CMDI when run in CRuby specs/
|
|
10
|
+
# test suite. The original method also depends on a Rails installation,
|
|
11
|
+
# which CRuby does not have installed.
|
|
12
|
+
module TCellAgent
|
|
13
|
+
module Instrumentation
|
|
14
|
+
module Lfi
|
|
15
|
+
def self.block_file_access?(_path, _mode)
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module Cmdi
|
|
22
|
+
def self.block_command?(_cmd)
|
|
23
|
+
false
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|