tcell_agent 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/tcell_agent/agent.rb +2 -1
- data/lib/tcell_agent/agent/event_processor.rb +58 -9
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +18 -15
- data/lib/tcell_agent/agent/static_agent.rb +4 -1
- data/lib/tcell_agent/configuration.rb +6 -4
- data/lib/tcell_agent/devise.rb +40 -40
- data/lib/tcell_agent/instrumentation.rb +125 -59
- data/lib/tcell_agent/policies/dataloss_policy.rb +74 -17
- data/lib/tcell_agent/policies/login_fraud_policy.rb +39 -36
- data/lib/tcell_agent/rails.rb +5 -14
- data/lib/tcell_agent/rails/auth/devise.rb +1 -0
- data/lib/tcell_agent/rails/dlp.rb +1 -1
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +21 -1
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +5 -3
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +16 -7
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +8 -9
- data/lib/tcell_agent/rails/on_start.rb +101 -0
- data/lib/tcell_agent/rails/routes.rb +80 -71
- data/lib/tcell_agent/sensor_events/app_sensor.rb +45 -14
- data/lib/tcell_agent/sensor_events/metrics.rb +119 -17
- data/lib/tcell_agent/sensor_events/server_agent.rb +8 -1
- data/lib/tcell_agent/servers/puma.rb +39 -37
- data/lib/tcell_agent/servers/thin.rb +0 -1
- data/lib/tcell_agent/servers/unicorn.rb +18 -5
- data/lib/tcell_agent/start_background_thread.rb +12 -28
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/apps/rails-3.2/Gemfile +25 -0
- data/spec/apps/rails-3.2/Gemfile.lock +126 -0
- data/spec/apps/rails-3.2/Rakefile +7 -0
- data/spec/apps/rails-3.2/app/assets/images/rails.png +0 -0
- data/spec/apps/rails-3.2/app/assets/javascripts/application.js +15 -0
- data/spec/apps/rails-3.2/app/assets/stylesheets/application.css +13 -0
- data/spec/apps/rails-3.2/app/controllers/application_controller.rb +3 -0
- data/spec/apps/rails-3.2/app/controllers/t_cell_app_controller.rb +5 -0
- data/spec/apps/rails-3.2/app/helpers/application_helper.rb +2 -0
- data/spec/apps/rails-3.2/app/views/layouts/application.html.erb +14 -0
- data/spec/apps/rails-3.2/app/views/t_cell_app/index.html.erb +1 -0
- data/spec/apps/rails-3.2/config.ru +4 -0
- data/spec/apps/rails-3.2/config/application.rb +63 -0
- data/spec/apps/rails-3.2/config/boot.rb +6 -0
- data/spec/apps/rails-3.2/config/environment.rb +5 -0
- data/spec/apps/rails-3.2/config/environments/test.rb +37 -0
- data/spec/apps/rails-3.2/config/routes.rb +11 -0
- data/spec/apps/rails-4.1/Gemfile +7 -0
- data/spec/apps/rails-4.1/Gemfile.lock +114 -0
- data/spec/apps/rails-4.1/Rakefile +6 -0
- data/spec/apps/rails-4.1/app/assets/javascripts/application.js +16 -0
- data/spec/apps/rails-4.1/app/assets/stylesheets/application.css +15 -0
- data/spec/apps/rails-4.1/app/controllers/application_controller.rb +5 -0
- data/spec/apps/rails-4.1/app/controllers/t_cell_app_controller.rb +5 -0
- data/spec/apps/rails-4.1/app/helpers/application_helper.rb +2 -0
- data/spec/apps/rails-4.1/app/views/layouts/application.html.erb +14 -0
- data/spec/apps/rails-4.1/app/views/t_cell_app/index.html.erb +1 -0
- data/spec/apps/rails-4.1/config.ru +4 -0
- data/spec/apps/rails-4.1/config/application.rb +24 -0
- data/spec/apps/rails-4.1/config/boot.rb +4 -0
- data/spec/apps/rails-4.1/config/environment.rb +5 -0
- data/spec/apps/rails-4.1/config/environments/test.rb +41 -0
- data/spec/apps/rails-4.1/config/initializers/assets.rb +8 -0
- data/spec/apps/rails-4.1/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/apps/rails-4.1/config/initializers/cookies_serializer.rb +3 -0
- data/spec/apps/rails-4.1/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/apps/rails-4.1/config/initializers/inflections.rb +16 -0
- data/spec/apps/rails-4.1/config/initializers/mime_types.rb +4 -0
- data/spec/apps/rails-4.1/config/initializers/session_store.rb +3 -0
- data/spec/apps/rails-4.1/config/initializers/wrap_parameters.rb +14 -0
- data/spec/apps/rails-4.1/config/locales/en.yml +23 -0
- data/spec/apps/rails-4.1/config/routes.rb +12 -0
- data/spec/apps/rails-4.1/config/secrets.yml +22 -0
- data/spec/integration/puma.rb +195 -0
- data/spec/lib/tcell_agent/agent/static_agent_spec.rb +136 -0
- data/spec/lib/tcell_agent/appsensor_spec.rb +0 -1
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +0 -1
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +94 -10
- data/spec/lib/tcell_agent/policies/login_policy_spec.rb +39 -34
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +146 -0
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +13 -5
- data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +258 -0
- data/spec/spec_helper.rb +6 -15
- data/spec/support/middleware_helper.rb +17 -0
- data/spec/{resources → support/resources}/normal_config.json +0 -0
- data/spec/support/static_agent_overrides.rb +36 -0
- metadata +103 -4
@@ -0,0 +1,101 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
#require 'tcell_agent/authlogic' if defined?(Authlogic)
|
4
|
+
#require 'tcell_agent/devise' if defined?(Devise)
|
5
|
+
|
6
|
+
require 'rails/all'
|
7
|
+
|
8
|
+
module TCellAgent
|
9
|
+
module Instrumentation
|
10
|
+
module Rails
|
11
|
+
METHODS = ['GET','POST','PUT','DELETE','HEAD',
|
12
|
+
'PATCH','TRACE','CONNECT','OPTIONS']
|
13
|
+
|
14
|
+
def self.instrument_route(route)
|
15
|
+
if (route.constraints.has_key? :request_method)
|
16
|
+
route_path = "#{route.path.spec}"
|
17
|
+
if (route_path.end_with?("(.:format)"))
|
18
|
+
route_path = route_path.chomp("(.:format)")
|
19
|
+
end
|
20
|
+
|
21
|
+
route_destination = route.defaults.to_json.to_s
|
22
|
+
|
23
|
+
route_methods = METHODS.select { |x| route.verb.match(x) }
|
24
|
+
route_methods.each { |route_method|
|
25
|
+
route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
|
26
|
+
TCellAgent.send_event(
|
27
|
+
TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
|
28
|
+
route_path, route_method, route_id, nil, route_destination
|
29
|
+
)
|
30
|
+
)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.instrument_routes
|
36
|
+
if ::Rails.application
|
37
|
+
::Rails.application.routes.routes.each do |route|
|
38
|
+
self.instrument_route(route)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if (::Rails::VERSION::MAJOR == 3)
|
44
|
+
ActionDispatch::Routing::RouteSet.class_eval do
|
45
|
+
alias_method :original_add_route, :add_route
|
46
|
+
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
|
47
|
+
route = original_add_route(app, conditions, requirements, defaults, name, anchor)
|
48
|
+
|
49
|
+
TCellAgent::Instrumentation::Rails.instrument_route(route)
|
50
|
+
|
51
|
+
route
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if (::Rails::VERSION::MAJOR == 4)
|
57
|
+
ActionDispatch::Journey::Routes.class_eval do
|
58
|
+
alias_method :original_add_route, :add_route
|
59
|
+
def add_route(app, path, conditions, defaults, name = nil)
|
60
|
+
route = original_add_route(app, path, conditions, defaults, name)
|
61
|
+
|
62
|
+
TCellAgent::Instrumentation::Rails.instrument_route(route)
|
63
|
+
|
64
|
+
route
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
TCellAgent::Instrumentation::Rails.send_framework_info
|
75
|
+
if (Rails.application)
|
76
|
+
TCellAgent::Instrumentation::Rails.send_settings(Rails.application)
|
77
|
+
require 'tcell_agent/devise' if defined?(Devise)
|
78
|
+
require 'tcell_agent/rails/auth/devise' if defined?(Devise)
|
79
|
+
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
80
|
+
require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
|
81
|
+
|
82
|
+
else
|
83
|
+
module TCellAgent
|
84
|
+
class MyRailtie < Rails::Railtie
|
85
|
+
initializer 'activeservice.autoload', :after => :set_autoload_paths do |app|
|
86
|
+
if (TCellAgent.configuration.enabled)
|
87
|
+
Rails.application.config.to_prepare do
|
88
|
+
require 'tcell_agent/devise' if defined?(Devise)
|
89
|
+
require 'tcell_agent/rails/auth/devise' if defined?(Devise)
|
90
|
+
require 'tcell_agent/authlogic' if defined?(Authlogic)
|
91
|
+
require 'tcell_agent/rails/auth/authlogic' if defined?(Authlogic)
|
92
|
+
end
|
93
|
+
|
94
|
+
Rails.application.config.after_initialize do
|
95
|
+
TCellAgent::Instrumentation::Rails.send_settings(Rails.application)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -1,90 +1,99 @@
|
|
1
|
-
|
2
1
|
module TCellAgent
|
3
2
|
ActiveSupport.on_load(:action_controller) do
|
4
|
-
|
5
3
|
ActionController::Base.class_eval do
|
6
4
|
|
7
|
-
|
5
|
+
prepend_around_filter :tell_around_filter_routes
|
8
6
|
def tell_around_filter_routes
|
9
7
|
begin
|
10
8
|
TCellAgent::Instrumentation.safe_block("Determining Rails Route ID") {
|
11
9
|
route = Rails.application.routes.router.recognize(request) { |r, _| r }.first
|
12
|
-
|
13
10
|
if route
|
14
11
|
route_path = route[2].path.spec
|
15
12
|
tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
16
|
-
tcell_context
|
13
|
+
if tcell_context
|
14
|
+
tcell_context.route_id = TCellAgent::SensorEvents::Util.calculateRouteId(request.method.downcase, route_path)
|
15
|
+
end
|
17
16
|
end
|
18
17
|
}
|
18
|
+
def loop_params_hash(method, param_hash, prefix, &block)
|
19
|
+
param_hash.each do |param_name, param_value|
|
20
|
+
if param_value && param_value.is_a?(Hash)
|
21
|
+
loop_params_hash(method, param_value, 'hash', &block)
|
22
|
+
elsif !param_value || !param_value.instance_of?(String) || param_value == ""
|
23
|
+
next
|
24
|
+
else
|
25
|
+
block.call(method, param_name, param_value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def for_params(request, &block)
|
30
|
+
get_params = request.GET
|
31
|
+
if get_params
|
32
|
+
self.loop_params_hash('get', get_params, nil, &block)
|
33
|
+
end
|
34
|
+
post_params = request.POST
|
35
|
+
if post_params
|
36
|
+
self.loop_params_hash('post', post_params, nil, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def _handle_dataexpsure_forms(request)
|
40
|
+
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
41
|
+
tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
42
|
+
if tcell_context && dataex_policy && dataex_policy.has_actions_for_form_parameter?
|
43
|
+
for_params(request) { |method, param_name, param_value|
|
44
|
+
actions = dataex_policy.get_actions_for_request("form",param_name)
|
45
|
+
if actions
|
46
|
+
actions.each { |action|
|
47
|
+
tcell_context.add_filter_for_request_parameter(param_value, action, param_name)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request forms)") {
|
54
|
+
_handle_dataexpsure_forms(request)
|
55
|
+
}
|
56
|
+
|
57
|
+
def _handle_dataexpsure_headers(request)
|
58
|
+
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
59
|
+
tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
60
|
+
if tcell_context && dataex_policy && dataex_policy.has_actions_for_headers?
|
61
|
+
headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
|
62
|
+
headers.each { |header_name, header_value|
|
63
|
+
header_name = header_name.sub(/^HTTP_/, '').gsub('_','-')
|
64
|
+
actions = dataex_policy.get_actions_for_header(header_name)
|
65
|
+
if actions
|
66
|
+
actions.each { |action|
|
67
|
+
tcell_context.add_filter_for_header_value(header_value, action, header_name)
|
68
|
+
}
|
69
|
+
end
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request headers)") {
|
74
|
+
_handle_dataexpsure_headers(request)
|
75
|
+
}
|
76
|
+
|
77
|
+
def _handler_dataexposure_cookies(request)
|
78
|
+
dataex_policy = TCellAgent.policy(TCellAgent::PolicyTypes::DataLoss)
|
79
|
+
tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
|
80
|
+
if tcell_context && dataex_policy && dataex_policy.has_actions_for_cookie?
|
81
|
+
request.cookies.each { |cookie_name, cookie_value|
|
82
|
+
actions = dataex_policy.get_actions_for_cookie(cookie_name)
|
83
|
+
if actions
|
84
|
+
actions.each { |action|
|
85
|
+
tcell_context.add_filter_for_cookie_value(cookie_value, action, cookie_name)
|
86
|
+
}
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
TCellAgent::Instrumentation.safe_block("Handling Dataexposure (request cookies)") {
|
92
|
+
_handler_dataexposure_cookies(request)
|
93
|
+
}
|
19
94
|
yield
|
20
95
|
end
|
21
96
|
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
module TCellAgent
|
28
|
-
|
29
|
-
module Instrumentation
|
30
|
-
|
31
|
-
module Rails
|
32
|
-
METHODS = ['GET','POST','PUT','DELETE','HEAD',
|
33
|
-
'PATCH','TRACE','CONNECT','OPTIONS']
|
34
|
-
|
35
|
-
def self.instrument_route(route)
|
36
|
-
if (route.constraints.has_key? :request_method)
|
37
|
-
route_path = "#{route.path.spec}"
|
38
|
-
if (route_path.end_with?("(.:format)"))
|
39
|
-
route_path = route_path.chomp("(.:format)")
|
40
|
-
end
|
41
|
-
|
42
|
-
route_destination = route.defaults.to_json.to_s
|
43
|
-
|
44
|
-
route_methods = METHODS.select { |x| route.verb.match(x) }
|
45
|
-
route_methods.each { |route_method|
|
46
|
-
route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
|
47
|
-
TCellAgent.send_event(
|
48
|
-
TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
|
49
|
-
route_path, route_method, route_id, nil, route_destination
|
50
|
-
)
|
51
|
-
)
|
52
|
-
}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.instrument_routes
|
57
|
-
::Rails.application.routes.routes.each do |route|
|
58
|
-
self.instrument_route(route)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
if (::Rails::VERSION::MAJOR == 3)
|
63
|
-
ActionDispatch::Routing::RouteSet.class_eval do
|
64
|
-
alias_method :original_add_route, :add_route
|
65
|
-
def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
|
66
|
-
route = original_add_route(app, conditions, requirements, defaults, name, anchor)
|
67
|
-
|
68
|
-
TCellAgent::Instrumentation::Rails.instrument_route(route)
|
69
|
-
|
70
|
-
route
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
if (::Rails::VERSION::MAJOR == 4)
|
76
|
-
ActionDispatch::Journey::Routes.class_eval do
|
77
|
-
alias_method :original_add_route, :add_route
|
78
|
-
def add_route(app, path, conditions, defaults, name = nil)
|
79
|
-
route = original_add_route(app, path, conditions, defaults, name)
|
80
|
-
|
81
|
-
TCellAgent::Instrumentation::Rails.instrument_route(route)
|
82
|
-
|
83
|
-
route
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
97
|
end
|
89
98
|
end
|
90
99
|
end
|
@@ -11,6 +11,7 @@ require 'tcell_agent/policies/appsensor_policy'
|
|
11
11
|
require 'tcell_agent/appsensor'
|
12
12
|
|
13
13
|
require 'tcell_agent/instrumentation'
|
14
|
+
require 'tcell_agent/configuration'
|
14
15
|
|
15
16
|
# Some Rules Originate from ModSecurity
|
16
17
|
# ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
@@ -19,7 +20,7 @@ require 'tcell_agent/instrumentation'
|
|
19
20
|
module TCellAgent
|
20
21
|
module SensorEvents
|
21
22
|
class TCellAppSensorEvent < TCellSensorEvent
|
22
|
-
def initialize(location, detection_point, remote_addr, param, route_id, data=nil, transaction_id=nil, session_id=nil, user_id=nil)
|
23
|
+
def initialize(location, detection_point, method, remote_addr, param, route_id, data=nil, transaction_id=nil, session_id=nil, user_id=nil, payload=nil)
|
23
24
|
super("as")
|
24
25
|
self["dp"] = detection_point
|
25
26
|
self["param"] = param
|
@@ -27,10 +28,13 @@ module TCellAgent
|
|
27
28
|
if (route_id)
|
28
29
|
self["rou"] = route_id
|
29
30
|
end
|
31
|
+
self["m"] = method
|
30
32
|
@raw_location = location
|
31
33
|
@user_id = user_id
|
32
34
|
@transaction_id = transaction_id
|
33
35
|
@raw_session_id = session_id
|
36
|
+
@payload = payload
|
37
|
+
|
34
38
|
end
|
35
39
|
def post_process
|
36
40
|
self["loc"] = Util.strip_uri_values(@raw_location)
|
@@ -44,12 +48,16 @@ module TCellAgent
|
|
44
48
|
hmac_key = Util.getHmacKey()
|
45
49
|
self["sid"] = Util.hmac(@raw_session_id, hmac_key)
|
46
50
|
end
|
51
|
+
if @payload
|
52
|
+
self["payload"] = @payload[0..150]
|
53
|
+
end
|
47
54
|
end
|
48
55
|
end
|
49
56
|
class TCellAppSensorEventProcessor < TCellSensorEvent
|
50
57
|
attr_accessor :request_headers, :request_size, :remote_addr,
|
51
58
|
:uri, :get_params, :post_params, :cookies,
|
52
|
-
:request_content_length, :request_content_type
|
59
|
+
:request_content_length, :request_content_type,
|
60
|
+
:request_method
|
53
61
|
attr_accessor :status_code, :response_headers,
|
54
62
|
:response_content_length,
|
55
63
|
:route_id, :transaction_id, :session_id, :user_id
|
@@ -58,18 +66,20 @@ module TCellAgent
|
|
58
66
|
@response_content_length = 0
|
59
67
|
@send = false
|
60
68
|
end
|
61
|
-
def appsensor_event(dp, param, data)
|
69
|
+
def appsensor_event(dp, param, data, payload=nil)
|
62
70
|
TCellAgent::Instrumentation.safe_block("AppSensor Sending Event") {
|
63
71
|
event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
|
64
72
|
@uri,
|
65
73
|
dp,
|
74
|
+
@request_method,
|
66
75
|
@remote_addr,
|
67
76
|
param,
|
68
77
|
@route_id,
|
69
78
|
data=nil,
|
70
79
|
transaction_id=@transaction_id,
|
71
80
|
session_id=@session_id,
|
72
|
-
user_id=@user_id
|
81
|
+
user_id=@user_id,
|
82
|
+
payload=payload)
|
73
83
|
@sensor_triggered = true
|
74
84
|
TCellAgent.send_event(event)
|
75
85
|
}
|
@@ -148,20 +158,21 @@ module TCellAgent
|
|
148
158
|
}
|
149
159
|
end
|
150
160
|
|
151
|
-
|
152
161
|
if (!@sensor_triggered && appsensor_policy.option_enabled?("resp_codes"))
|
153
162
|
TCellAgent::Instrumentation.safe_block("AppSensor Resting Response Code") {
|
154
163
|
test_response_code
|
155
164
|
}
|
156
165
|
end
|
157
166
|
|
158
|
-
|
159
|
-
|
160
167
|
if (!@sensor_triggered && appsensor_policy.option_enabled?("xss"))
|
161
168
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for XSS") {
|
162
169
|
for_params { | param_type, param_name, param_value |
|
163
170
|
if (TCellAgent::AppSensor.isXss(param_value))
|
164
|
-
|
171
|
+
send_payload = nil
|
172
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
173
|
+
send_payload = param_value
|
174
|
+
end
|
175
|
+
appsensor_event("xss", param_name, nil, payload=send_payload)
|
165
176
|
return
|
166
177
|
end
|
167
178
|
}
|
@@ -171,7 +182,11 @@ module TCellAgent
|
|
171
182
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for CMDI") {
|
172
183
|
for_params { | param_type, param_name, param_value |
|
173
184
|
if (TCellAgent::AppSensor.isCmdi(param_value))
|
174
|
-
|
185
|
+
send_payload = nil
|
186
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
187
|
+
send_payload = param_value
|
188
|
+
end
|
189
|
+
appsensor_event("cmdi", param_name, nil, payload=send_payload)
|
175
190
|
return
|
176
191
|
end
|
177
192
|
}
|
@@ -182,7 +197,11 @@ module TCellAgent
|
|
182
197
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for SQLI") {
|
183
198
|
for_params { | param_type, param_name, param_value |
|
184
199
|
if (TCellAgent::AppSensor.isSqli(param_value))
|
185
|
-
|
200
|
+
send_payload = nil
|
201
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
202
|
+
send_payload = param_value
|
203
|
+
end
|
204
|
+
appsensor_event("sqli", param_name, nil, payload=send_payload)
|
186
205
|
return
|
187
206
|
end
|
188
207
|
}
|
@@ -193,7 +212,11 @@ module TCellAgent
|
|
193
212
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for Return Chars") {
|
194
213
|
for_get_params { | param_type, param_name, param_value |
|
195
214
|
if (TCellAgent::AppSensor.containsReturnChars(param_value))
|
196
|
-
|
215
|
+
send_payload = nil
|
216
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
217
|
+
send_payload = param_value
|
218
|
+
end
|
219
|
+
appsensor_event("retr", param_name, nil, payload=send_payload)
|
197
220
|
return
|
198
221
|
end
|
199
222
|
}
|
@@ -204,18 +227,26 @@ module TCellAgent
|
|
204
227
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for Null") {
|
205
228
|
for_params { | param_type, param_name, param_value |
|
206
229
|
if (TCellAgent::AppSensor.containsNull(param_value))
|
207
|
-
|
230
|
+
send_payload = nil
|
231
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
232
|
+
send_payload = param_value
|
233
|
+
end
|
234
|
+
appsensor_event("null", param_name, nil, payload=send_payload)
|
208
235
|
return
|
209
236
|
end
|
210
237
|
}
|
211
238
|
}
|
212
239
|
end
|
213
240
|
|
214
|
-
if (!@sensor_triggered && appsensor_policy.option_enabled?("
|
241
|
+
if (!@sensor_triggered && appsensor_policy.option_enabled?("fpt"))
|
215
242
|
TCellAgent::Instrumentation.safe_block("AppSensor Testing for File path traversal") {
|
216
243
|
for_params { | param_type, param_name, param_value |
|
217
244
|
if (TCellAgent::AppSensor.isPathTraversal(param_value))
|
218
|
-
|
245
|
+
send_payload = nil
|
246
|
+
if (TCellAgent.configuration.allow_unencrypted_appsensor_payloads)
|
247
|
+
send_payload = param_value
|
248
|
+
end
|
249
|
+
appsensor_event("fpt", param_name, nil, payload=send_payload)
|
219
250
|
return
|
220
251
|
end
|
221
252
|
}
|
@@ -1,24 +1,126 @@
|
|
1
1
|
# See the file "LICENSE" for the full license governing this code.
|
2
2
|
|
3
3
|
module TCellAgent
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
module SensorEvents
|
5
|
+
class Counter
|
6
|
+
attr_reader :counter
|
7
|
+
def initialize
|
8
|
+
@counter = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_object
|
12
|
+
@counter += 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset
|
16
|
+
@counter = 0
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class RequestRouteTimer < TCellSensorEvent
|
21
|
+
attr_accessor :route_id
|
22
|
+
attr_accessor :response_time
|
23
|
+
def initialize(route_id, response_time)
|
24
|
+
super("RequestRouteTimer")
|
25
|
+
self.route_id = route_id
|
26
|
+
self.response_time = response_time
|
27
|
+
@send = false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MetricsEvent < TCellSensorEvent
|
32
|
+
def initialize()
|
33
|
+
super("metrics")
|
34
|
+
end
|
35
|
+
def set_route_count_table(route_count_table)
|
36
|
+
self["rct"] = route_count_table
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class SessionsMetric < TCellSensorEvent
|
41
|
+
class UserSessionTrackMetric < Hash
|
42
|
+
def initialize(object_counter, user_id)
|
43
|
+
@object_counter = object_counter
|
44
|
+
@user_agents = {}
|
45
|
+
self["uid"] = user_id
|
46
|
+
self["track"] = []
|
14
47
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
48
|
+
|
49
|
+
def add_user_agent_ip(truncated_agent, ip_address)
|
50
|
+
if @user_agents.has_key?(truncated_agent)
|
51
|
+
tracked_agents = @user_agents[truncated_agent]
|
52
|
+
ips = tracked_agents[1]
|
53
|
+
unless ips.include?(ip_address)
|
54
|
+
@object_counter.add_object
|
55
|
+
ips.push(ip_address)
|
21
56
|
end
|
57
|
+
|
58
|
+
else
|
59
|
+
@object_counter.add_object
|
60
|
+
@user_agents[truncated_agent] = [truncated_agent, [ip_address]]
|
61
|
+
self["track"].push(@user_agents[truncated_agent])
|
62
|
+
end
|
22
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class UserSessionMetric < Array
|
67
|
+
def initialize(object_counter)
|
68
|
+
@user_ids = {}
|
69
|
+
@object_counter = object_counter
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_user_id_user_agent_ip(user_id, truncated_agent, ip_address)
|
73
|
+
if @user_ids.has_key?(user_id)
|
74
|
+
user_id_info = @user_ids[user_id]
|
75
|
+
user_id_info.add_user_agent_ip(truncated_agent, ip_address)
|
76
|
+
|
77
|
+
else
|
78
|
+
@object_counter.add_object
|
79
|
+
|
80
|
+
@user_ids[user_id] = user_id_info = UserSessionTrackMetric.new(@object_counter, user_id)
|
81
|
+
user_id_info.add_user_agent_ip(truncated_agent, ip_address)
|
82
|
+
|
83
|
+
self.push(user_id_info)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def initialize()
|
89
|
+
super("metrics")
|
90
|
+
@send = false
|
91
|
+
@flush = false
|
92
|
+
|
93
|
+
self["sessions"] = {}
|
94
|
+
@has_sessions = false
|
95
|
+
@object_counter = Counter.new
|
96
|
+
end
|
97
|
+
|
98
|
+
def has_sessions?
|
99
|
+
@has_sessions
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_session_info(hmac_session_id, user_id, ip_address, user_agent)
|
103
|
+
if @object_counter.counter >= 250
|
104
|
+
TCellAgent.logger.warn("Sessions Metric is full. Information dropped")
|
105
|
+
|
106
|
+
else
|
107
|
+
self["sessions"][hmac_session_id] =
|
108
|
+
self["sessions"].fetch(hmac_session_id, UserSessionMetric.new(@object_counter))
|
109
|
+
|
110
|
+
@has_sessions = true
|
111
|
+
|
112
|
+
truncated_agent = truncated_user_agent(user_agent)
|
113
|
+
self["sessions"][hmac_session_id].add_user_id_user_agent_ip(user_id, truncated_agent, ip_address)
|
114
|
+
|
115
|
+
if @object_counter.counter >= 200
|
116
|
+
@flush = true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def truncated_user_agent(user_agent)
|
122
|
+
user_agent[0...256]
|
123
|
+
end
|
23
124
|
end
|
24
|
-
end
|
125
|
+
end
|
126
|
+
end
|