tcell_agent 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +4 -0
  3. data/README.md +43 -0
  4. data/Rakefile +7 -0
  5. data/bin/tcell_agent +171 -0
  6. data/config/initializers/authlogic_auth.rb +51 -0
  7. data/config/initializers/devise_auth.rb +167 -0
  8. data/config/initializers/init.rb +8 -0
  9. data/lib/tcell_agent.rb +33 -0
  10. data/lib/tcell_agent/agent.rb +79 -0
  11. data/lib/tcell_agent/agent/event_processor.rb +133 -0
  12. data/lib/tcell_agent/agent/policy_manager.rb +138 -0
  13. data/lib/tcell_agent/agent/policy_types.rb +42 -0
  14. data/lib/tcell_agent/agent/static_agent.rb +22 -0
  15. data/lib/tcell_agent/api.rb +101 -0
  16. data/lib/tcell_agent/appsensor.rb +42 -0
  17. data/lib/tcell_agent/appsensor/cmdi.rb +32 -0
  18. data/lib/tcell_agent/appsensor/path_traversal.rb +33 -0
  19. data/lib/tcell_agent/appsensor/sqli.rb +55 -0
  20. data/lib/tcell_agent/appsensor/xss.rb +40 -0
  21. data/lib/tcell_agent/authlogic.rb +26 -0
  22. data/lib/tcell_agent/configuration.rb +148 -0
  23. data/lib/tcell_agent/dataloss.rb +0 -0
  24. data/lib/tcell_agent/devise.rb +83 -0
  25. data/lib/tcell_agent/instrumentation.rb +44 -0
  26. data/lib/tcell_agent/logger.rb +46 -0
  27. data/lib/tcell_agent/policies/add_script_tag_policy.rb +47 -0
  28. data/lib/tcell_agent/policies/appsensor_policy.rb +76 -0
  29. data/lib/tcell_agent/policies/clickjacking_policy.rb +113 -0
  30. data/lib/tcell_agent/policies/content_security_policy.rb +119 -0
  31. data/lib/tcell_agent/policies/dataloss_policy.rb +175 -0
  32. data/lib/tcell_agent/policies/honeytokens_policy.rb +67 -0
  33. data/lib/tcell_agent/policies/http_redirect_policy.rb +84 -0
  34. data/lib/tcell_agent/policies/http_tx_policy.rb +60 -0
  35. data/lib/tcell_agent/policies/login_fraud_policy.rb +42 -0
  36. data/lib/tcell_agent/policies/secure_headers_policy.rb +64 -0
  37. data/lib/tcell_agent/rails.rb +146 -0
  38. data/lib/tcell_agent/rails/devise.rb +0 -0
  39. data/lib/tcell_agent/rails/dlp.rb +204 -0
  40. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +69 -0
  41. data/lib/tcell_agent/rails/middleware/context_middleware.rb +50 -0
  42. data/lib/tcell_agent/rails/middleware/global_middleware.rb +53 -0
  43. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +176 -0
  44. data/lib/tcell_agent/rails/routes.rb +130 -0
  45. data/lib/tcell_agent/rails/settings_reporter.rb +40 -0
  46. data/lib/tcell_agent/sensor_events/app_config.rb +16 -0
  47. data/lib/tcell_agent/sensor_events/app_sensor.rb +240 -0
  48. data/lib/tcell_agent/sensor_events/dlp.rb +58 -0
  49. data/lib/tcell_agent/sensor_events/honeytokens.rb +16 -0
  50. data/lib/tcell_agent/sensor_events/login_fraud.rb +43 -0
  51. data/lib/tcell_agent/sensor_events/metrics.rb +24 -0
  52. data/lib/tcell_agent/sensor_events/sensor.rb +85 -0
  53. data/lib/tcell_agent/sensor_events/server_agent.rb +101 -0
  54. data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +22 -0
  55. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +153 -0
  56. data/lib/tcell_agent/sensor_events/util/utils.rb +21 -0
  57. data/lib/tcell_agent/sinatra.rb +41 -0
  58. data/lib/tcell_agent/start_background_thread.rb +63 -0
  59. data/lib/tcell_agent/userinfo.rb +8 -0
  60. data/lib/tcell_agent/utils/queue_with_timeout.rb +60 -0
  61. data/lib/tcell_agent/version.rb +5 -0
  62. data/spec/controllers/application_controller.rb +12 -0
  63. data/spec/lib/tcell_agent/api/api_spec.rb +36 -0
  64. data/spec/lib/tcell_agent/appsensor_spec.rb +66 -0
  65. data/spec/lib/tcell_agent/policies/add_script_tag_policy_spec.rb +37 -0
  66. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +40 -0
  67. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +71 -0
  68. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +71 -0
  69. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +88 -0
  70. data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +22 -0
  71. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +62 -0
  72. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +22 -0
  73. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +42 -0
  74. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +67 -0
  75. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +187 -0
  76. data/spec/lib/tcell_agent/rails_spec.rb +57 -0
  77. data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +14 -0
  78. data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +25 -0
  79. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +57 -0
  80. data/spec/lib/tcell_agent_spec.rb +22 -0
  81. data/spec/resources/normal_config.json +13 -0
  82. data/spec/spec_helper.rb +4 -0
  83. data/tcell_agent.gemspec +29 -0
  84. metadata +249 -0
@@ -0,0 +1,53 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require 'rails'
4
+ require 'uri'
5
+ require 'tcell_agent/logger'
6
+ require 'tcell_agent/agent'
7
+ require 'tcell_agent/sensor_events/sensor'
8
+ require 'tcell_agent/sensor_events/app_sensor'
9
+ require 'tcell_agent/sensor_events/server_agent'
10
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
11
+ require 'tcell_agent/sensor_events/util/redirect_utils'
12
+
13
+ require 'tcell_agent/rails/routes'
14
+
15
+ require 'tcell_agent/userinfo'
16
+ require 'cgi'
17
+
18
+ require 'tcell_agent/instrumentation'
19
+
20
+ module TCellAgent
21
+ module Instrumentation
22
+ module Rails
23
+ module Middleware
24
+
25
+ class GlobalMiddleware
26
+
27
+ def initialize(app)
28
+ @app = app
29
+ end
30
+
31
+ def call(env)
32
+ request = Rack::Request.new(env)
33
+ TCellAgent::Instrumentation.safe_block("Setting session_id & user_id") {
34
+ if request.session
35
+ env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID].session_id = request.session["session_id"]
36
+ env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID].user_id = TCellAgent::UserInformation.getUserFromRequest(request)
37
+ end
38
+ }
39
+ TCellAgent::Instrumentation.safe_block("Setting hmac_session_id") {
40
+ hmac_key = TCellAgent::SensorEvents::Util.getHmacKey()
41
+ if request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID].session_id
42
+ env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID].hmac_session_id = TCellAgent::SensorEvents::Util.hmac(request.env["tcell.request_data"].session_id, hmac_key)
43
+ end
44
+ }
45
+ response = @app.call(env)
46
+ response
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,176 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require 'rails'
4
+ require 'uri'
5
+ require 'tcell_agent/logger'
6
+ require 'tcell_agent/agent'
7
+ require 'tcell_agent/sensor_events/sensor'
8
+ require 'tcell_agent/sensor_events/app_sensor'
9
+ require 'tcell_agent/sensor_events/server_agent'
10
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
11
+ require 'tcell_agent/sensor_events/util/redirect_utils'
12
+
13
+ require 'tcell_agent/rails/routes'
14
+
15
+ require 'tcell_agent/userinfo'
16
+ require 'cgi'
17
+
18
+ require 'tcell_agent/instrumentation'
19
+
20
+ module TCellAgent
21
+ module Instrumentation
22
+ module Rails
23
+ module Middleware
24
+
25
+ class HeadersMiddleware
26
+
27
+ def initialize(app)
28
+ @app = app
29
+ end
30
+
31
+ def call(env)
32
+
33
+ request = Rack::Request.new(env)
34
+ response = @app.call(env)
35
+ status, headers, active_response = response
36
+ TCellAgent::Instrumentation.safe_block("Handling Request") {
37
+ tcell_response = response
38
+ tcell_response = self._handle_appsensor(request, tcell_response)
39
+ tcell_response = self._handle_redirect(request, tcell_response)
40
+ tcell_response = self._set_csp_header(request, tcell_response)
41
+ tcell_response = self._set_clickjacking_header(request, tcell_response)
42
+ tcell_response = self._set_secure_headers(request, tcell_response)
43
+ response = tcell_response
44
+ }
45
+ response
46
+ end
47
+
48
+ def _set_csp_header(request, response)
49
+ TCellAgent::Instrumentation.safe_block("Setting CSP Headers") {
50
+ status, headers, active_response = response
51
+
52
+ content_security_policy = TCellAgent.policy(TCellAgent::PolicyTypes::CSP)
53
+
54
+ if content_security_policy
55
+ content_security_policy.each(
56
+ request.env["tcell.request_data"].transaction_id,
57
+ request.env["tcell.request_data"].hmac_session_id,
58
+ request.env["tcell.request_data"].user_id) do | header_pair |
59
+ headers[header_pair["name"]] = header_pair["value"]
60
+ end
61
+ end
62
+ response = [status, headers, active_response]
63
+ }
64
+ response
65
+ end
66
+
67
+ def _set_clickjacking_header(request, response)
68
+ TCellAgent::Instrumentation.safe_block("Setting Clickjacking Headers") {
69
+ status, headers, active_response = response
70
+ clickjacking_policy = TCellAgent.policy(TCellAgent::PolicyTypes::Clickjacking)
71
+
72
+ if clickjacking_policy
73
+ clickjacking_policy.each(
74
+ request.env["tcell.request_data"].transaction_id,
75
+ request.env["tcell.request_data"].hmac_session_id,
76
+ request.env["tcell.request_data"].user_id) do | header_pair |
77
+ header_name = header_pair["name"]
78
+ header_value = header_pair["value"]
79
+ if (headers.has_key?header_name)
80
+ headers[header_name] = headers[header_name] + "," + header_value
81
+ else
82
+ headers[header_name] = header_value
83
+ end
84
+ end
85
+ end #if
86
+
87
+ response = [status, headers, active_response]
88
+ }
89
+ response
90
+ end
91
+
92
+ def _set_secure_headers(request, response)
93
+ TCellAgent::Instrumentation.safe_block("Setting Secure Headers") {
94
+ status, headers, active_response = response
95
+
96
+ secure_headers_policy = TCellAgent.policy(TCellAgent::PolicyTypes::SecureHeaders)
97
+ if secure_headers_policy
98
+ secure_headers_policy.headers.each do | secure_header |
99
+ headers[secure_header.name] = secure_header.value
100
+ end
101
+ end
102
+ response = [status, headers, active_response]
103
+ }
104
+ response
105
+ end
106
+
107
+ def _handle_redirect(request, response)
108
+ TCellAgent::Instrumentation.safe_block("Handling Redirect Headers") {
109
+ status, headers, active_response = response
110
+
111
+ http_redirect_policy = TCellAgent.policy(TCellAgent::PolicyTypes::HttpRedirect)
112
+ if http_redirect_policy && headers.has_key?("Location")
113
+ local_uri = URI.parse(request.url)
114
+ new_location = http_redirect_policy.enforce(
115
+ headers["Location"],
116
+ local_uri.host,
117
+ request.fullpath,
118
+ request.request_method,
119
+ status,
120
+ request.ip)
121
+ # Enforcement
122
+ if (new_location)
123
+ headers["Location"] = new_location
124
+ end
125
+ end
126
+ response = [status, headers, active_response]
127
+ }
128
+ response
129
+ end
130
+
131
+ def _handle_appsensor(request, response)
132
+ TCellAgent::Instrumentation.safe_block("Handling AppSensor") {
133
+ status_code, response_headers, response_body = response
134
+ appsensor_policy = TCellAgent.policy(TCellAgent::PolicyTypes::AppSensor)
135
+
136
+ if (!(response_body.is_a?(Array)) && !(response_body.is_a?(Rack::BodyProxy)))
137
+ return response
138
+ end
139
+ rack_response = Rack::Response.new(response)
140
+ if appsensor_policy && appsensor_policy.enabled
141
+ event = TCellAgent::SensorEvents::TCellAppSensorEventProcessor.new
142
+ event.request_headers = request.env
143
+ event.request_content_length = (request.content_length || "0").to_i
144
+ event.request_body = request.body
145
+ event.response_content_length = (rack_response.length || "0").to_i
146
+ event.remote_addr = request.ip
147
+ event.uri = request.fullpath
148
+ event.get_params = request.GET
149
+ event.post_params = request.POST
150
+ event.cookies = request.cookies
151
+
152
+ #status, headers, active_response = response
153
+ #if active_response.class != ActionDispatch::Response
154
+ # return response
155
+ #end
156
+
157
+ event.status_code = status_code
158
+ event.response_headers = response_headers
159
+ event.response_body = response_body
160
+
161
+ event.route_id = request.env["tcell.request_data"].route_id
162
+ event.transaction_id = request.env["tcell.request_data"].transaction_id
163
+ event.session_id = request.env["tcell.request_data"].hmac_session_id
164
+ event.user_id = request.env["tcell.request_data"].user_id
165
+
166
+ TCellAgent.send_event(event)
167
+ end
168
+ }
169
+ response
170
+ end
171
+
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,130 @@
1
+
2
+ module TCellAgent
3
+ class Engine < Rails::Engine
4
+ ActiveSupport.on_load(:action_controller) do
5
+ ActionController::Base.class_eval do
6
+ around_filter :tell_around_filter_routes
7
+ def tell_around_filter_routes
8
+ begin
9
+ TCellAgent::Instrumentation.safe_block("Determining Rails Route ID") {
10
+ route = Rails.application.routes.router.recognize(request) { |route, _| route }.first
11
+ if route
12
+ route_path = route[2].path.spec
13
+ tcell_context = request.env[TCellAgent::Instrumentation::Rails::Middleware::TCELL_ID]
14
+ tcell_context.route_id = TCellAgent::SensorEvents::Util.calculateRouteId(request.method.downcase, route_path)
15
+ end
16
+ }
17
+ yield
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+
27
+ module TCellAgent
28
+ module Instrumentation
29
+ module Rails
30
+ def self.route_path_from_route(route)
31
+ if (::Rails::VERSION::MAJOR == 4)
32
+ begin
33
+ route_path = "#{route[2].path.spec}"
34
+ if (route_path.end_with?("(.:format)"))
35
+ route_path = route_path.chomp("(.:format)")
36
+ end
37
+ return route_path
38
+ rescue Exception => inner_excetion
39
+ TCellAgent.logger.debug("Could not figure out path #{inner_excetion.message}")
40
+ end
41
+ end
42
+ nil
43
+ end
44
+ def self.route_from_request(rails_request)
45
+ if (rails_request.env["action_dispatch.request_id"] == nil)
46
+ return nil
47
+ end
48
+ if (::Rails::VERSION::MAJOR == 4)
49
+ begin
50
+ recognized = ::Rails.application.routes.router.recognize(rails_request) { |route, _| route }
51
+ if recognized
52
+ return recognized.first
53
+ end
54
+ rescue Exception => inner_excetion
55
+ TCellAgent.logger.debug("Could not figure out path #{inner_excetion.message}")
56
+ end
57
+ end
58
+ nil
59
+ end
60
+ def self.route_id_from_request(active_request)
61
+ route = route_from_request(active_request)
62
+ if route != nil
63
+ route_path = route_path_from_route(route)
64
+ if route_path != nil
65
+ return TCellAgent::SensorEvents::Util.calculateRouteId(active_request.request_method.downcase, route_path)
66
+ end
67
+ end
68
+ nil
69
+ end
70
+ def self.get_routes
71
+ end
72
+ if (::Rails::VERSION::MAJOR == 3)
73
+ ActionDispatch::Routing::RouteSet.class_eval do
74
+ alias_method :original_add_route, :add_route
75
+ def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
76
+ methods = ['GET','POST','PUT','DELETE','HEAD',
77
+ 'PATCH','TRACE','CONNECT','OPTIONS']
78
+ route = original_add_route(app, conditions, requirements, defaults, name, anchor)
79
+ if (route.constraints.has_key? :request_method)
80
+ route_path = "#{route.path.spec}"
81
+ if (route_path.end_with?("(.:format)"))
82
+ route_path = route_path.chomp("(.:format)")
83
+ end
84
+ route_destination = route.defaults.to_json.to_s
85
+ route_params = route.path.required_names
86
+ route_methods = methods.select {|x| route.verb.match(x) }
87
+ route_methods.each { |route_method|
88
+ route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
89
+ TCellAgent.send_event(
90
+ TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
91
+ route_path, route_method, route_id, nil, route_destination
92
+ )
93
+ )
94
+ }
95
+ end
96
+ route
97
+ end
98
+ end
99
+ end
100
+ if (::Rails::VERSION::MAJOR == 4)
101
+ ActionDispatch::Journey::Routes.class_eval do
102
+ alias_method :original_add_route, :add_route
103
+ def add_route(app, path, conditions, defaults, name = nil)
104
+ methods = ['GET','POST','PUT','DELETE','HEAD',
105
+ 'PATCH','TRACE','CONNECT','OPTIONS']
106
+ route = original_add_route(app, path, conditions, defaults, name)
107
+ if (route.constraints.has_key? :request_method)
108
+ route_path = "#{route.path.spec}"
109
+ if (route_path.end_with?("(.:format)"))
110
+ route_path = route_path.chomp("(.:format)")
111
+ end
112
+ route_destination = route.defaults.to_json.to_s
113
+ route_params = route.path.required_names
114
+ route_methods = methods.select {|x| route.verb.match(x) }
115
+ route_methods.each { |route_method|
116
+ route_id = TCellAgent::SensorEvents::Util.calculateRouteId(route_method.downcase, route.path.spec)
117
+ TCellAgent.send_event(
118
+ TCellAgent::SensorEvents::AppRoutesSensorEvent.new(
119
+ route_path, route_method, route_id, nil, route_destination
120
+ )
121
+ )
122
+ }
123
+ end
124
+ route
125
+ end
126
+ end
127
+ end #endif rails version = 4
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,40 @@
1
+ require 'rails'
2
+ require 'tcell_agent'
3
+ require 'tcell_agent/sensor_events/app_config'
4
+ require 'tcell_agent/sensor_events/server_agent'
5
+
6
+ module TCellAgent
7
+ module Instrumentation
8
+ module Rails
9
+ def self.send_framework_info
10
+ if (TCellAgent.configuration.exp_config_settings)
11
+ version = ::Rails.version
12
+ TCellAgent.send_event(TCellAgent::SensorEvents::ServerAgentAppFrameworkEvent.new(
13
+ "Rails", version
14
+ ))
15
+ end
16
+ end
17
+ def self.send_settings(application)
18
+ if (TCellAgent.configuration.exp_config_settings)
19
+ # Defaults to true
20
+ csrf_protection = application.config.action_controller.allow_forgery_protection || true
21
+ TCellAgent.send_event(TCellAgent::SensorEvents::AppConfigSettingEvent.new(
22
+ "Rails", "core", "", "csrf_protection", csrf_protection
23
+ ))
24
+
25
+ # Defaults to false if nil
26
+ mass_assignment_allowed = application.config.action_controller.permit_all_parameters || false
27
+ TCellAgent.send_event(TCellAgent::SensorEvents::AppConfigSettingEvent.new(
28
+ "Rails", "core", "", "mass_assignment_allowed", mass_assignment_allowed
29
+ ))
30
+
31
+ # Defaults to never
32
+ session_expire = application.config.session_options[:expire_after] || -1
33
+ TCellAgent.send_event(TCellAgent::SensorEvents::AppConfigSettingEvent.new(
34
+ "Rails", "session", "", "timeout", session_expire
35
+ ))
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ require 'tcell_agent/sensor_events/sensor'
2
+
3
+ module TCellAgent
4
+ module SensorEvents
5
+ class AppConfigSettingEvent < TCellSensorEvent
6
+ def initialize(package, section, prefix, name, value)
7
+ super("app_config_setting")
8
+ self["package"] = package
9
+ self["section"] = section
10
+ self["prefix"] = prefix
11
+ self["name"] = name
12
+ self["value"] = value.to_s
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,240 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
5
+ require 'tcell_agent/sensor_events/sensor'
6
+
7
+ require 'tcell_agent/agent'
8
+ require 'tcell_agent/agent/policy_types'
9
+
10
+ require 'tcell_agent/policies/appsensor_policy'
11
+ require 'tcell_agent/appsensor'
12
+
13
+ require 'tcell_agent/instrumentation'
14
+
15
+ # Some Rules Originate from ModSecurity
16
+ # ModSecurity for Apache 2.x, http://www.modsecurity.org/
17
+ # Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
18
+
19
+ module TCellAgent
20
+ module SensorEvents
21
+ 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
+ super("as")
24
+ self["dp"] = detection_point
25
+ self["param"] = param
26
+ self["remote_addr"] = remote_addr
27
+ if (route_id)
28
+ self["rou"] = route_id
29
+ end
30
+ @raw_location = location
31
+ @user_id = user_id
32
+ @transaction_id = transaction_id
33
+ @raw_session_id = session_id
34
+ end
35
+ def post_process
36
+ self["loc"] = Util.strip_uri_values(@raw_location)
37
+ if @user_id
38
+ self["uid"] = @user_id.to_s
39
+ end
40
+ if @transaction_id
41
+ self["tid"] = @transaction_id
42
+ end
43
+ if @raw_session_id
44
+ hmac_key = Util.getHmacKey()
45
+ self["sid"] = Util.hmac(@raw_session_id, hmac_key)
46
+ end
47
+ end
48
+ end
49
+ class TCellAppSensorEventProcessor < TCellSensorEvent
50
+ attr_accessor :request_headers, :request_body, :remote_addr,
51
+ :uri, :get_params, :post_params, :cookies,
52
+ :request_content_length, :request_content_type
53
+ attr_accessor :status_code, :response_headers, :response_body,
54
+ :response_content_length,
55
+ :route_id, :transaction_id, :session_id, :user_id
56
+ def initialize
57
+ @request_content_length=0
58
+ @response_content_length = 0
59
+ @send = false
60
+ end
61
+ def appsensor_event(dp, param, data)
62
+ TCellAgent::Instrumentation.safe_block("AppSensor Sending Event") {
63
+ event = TCellAgent::SensorEvents::TCellAppSensorEvent.new(
64
+ @uri,
65
+ dp,
66
+ @remote_addr,
67
+ param,
68
+ @route_id,
69
+ data=nil,
70
+ transaction_id=@transaction_id,
71
+ session_id=@session_id,
72
+ user_id=@user_id)
73
+ @sensor_triggered = true
74
+ TCellAgent.send_event(event)
75
+ }
76
+ end
77
+ def for_params
78
+ if @get_params
79
+ @get_params.each do |param_name, param_value|
80
+ if !param_value || !param_value.instance_of?(String) || param_value == ""
81
+ next
82
+ end
83
+ yield('get', param_name, param_value)
84
+ end
85
+ end
86
+ if @post_params
87
+ @post_params.each do |param_name, param_value|
88
+ if !param_value || !param_value.instance_of?(String) || param_value == ""
89
+ next
90
+ end
91
+ yield('post', param_name, param_value)
92
+ end
93
+ end
94
+ end
95
+
96
+ def for_get_params
97
+ if @get_params
98
+ @get_params.each do |param_name, param_value|
99
+ if !param_value || !param_value.instance_of?(String) || param_value == ""
100
+ next
101
+ end
102
+ yield('get', param_name, param_value)
103
+ end
104
+ end
105
+ end
106
+
107
+ def test_response_size
108
+ if (@response_content_length && @response_content_length > TCellAgent::Policies::AppSensorPolicy::MAX_NORMAL_RESPONSE_BYTES)
109
+ appsensor_event(TCellAgent::Policies::AppSensorPolicy::DP_UNUSUAL_RESPONSE_SIZE, response_content_length.to_s, nil)
110
+ end
111
+ request_size = 0
112
+ if @request_body
113
+ if @request_body.kind_of?(StringIO)
114
+ request_size = @request_body.size
115
+ else
116
+ request_size = @request_content_length
117
+ end
118
+ end
119
+ if (request_size > TCellAgent::Policies::AppSensorPolicy::MAX_NORMAL_REQUEST_BYTES)
120
+ appsensor_event(TCellAgent::Policies::AppSensorPolicy::DP_UNUSUAL_REQUEST_SIZE,request_size.to_s, nil)
121
+ end
122
+ end
123
+
124
+ def test_response_code
125
+ @status_code = @status_code.to_i
126
+ if @status_code == 200
127
+ return
128
+ end
129
+ series = @status_code.to_i / 100
130
+ dp = nil
131
+ if (@status_code == 401)
132
+ dp = "s401"
133
+ elsif (@status_code == 403)
134
+ dp = "s403"
135
+ elsif (@status_code == 404)
136
+ dp = "s404"
137
+ elsif (series == 4)
138
+ dp = "s4xx"
139
+ elsif (@status_code == 500)
140
+ dp = "s500"
141
+ elsif (series == 5)
142
+ dp = "s5xx"
143
+ end
144
+ if (dp)
145
+ appsensor_event(dp, @status_code.to_s, nil)
146
+ end
147
+ end
148
+
149
+ def post_process
150
+ appsensor_policy = TCellAgent.policy(TCellAgent::PolicyTypes::AppSensor)
151
+ if (!appsensor_policy || !appsensor_policy.enabled)
152
+ return
153
+ end
154
+
155
+ @sensor_triggered = false;
156
+
157
+ if (appsensor_policy.option_enabled?("req_res_size"))
158
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing Response Size") {
159
+ test_response_size
160
+ }
161
+ end
162
+
163
+
164
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("resp_codes"))
165
+ TCellAgent::Instrumentation.safe_block("AppSensor Resting Response Code") {
166
+ test_response_code
167
+ }
168
+ end
169
+
170
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("xss"))
171
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for XSS") {
172
+ for_params { | param_type, param_name, param_value |
173
+ if (TCellAgent::AppSensor.isXss(param_value))
174
+ appsensor_event("xss", param_name, nil)
175
+ return
176
+ end
177
+ }
178
+ }
179
+ end
180
+
181
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("cmdi"))
182
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for CMDI") {
183
+ for_params { | param_type, param_name, param_value |
184
+ if (TCellAgent::AppSensor.isCmdi(param_value))
185
+ appsensor_event("cmdi", param_name, nil)
186
+ return
187
+ end
188
+ }
189
+ }
190
+ end
191
+
192
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("sqli"))
193
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for SQLI") {
194
+ for_params { | param_type, param_name, param_value |
195
+ if (TCellAgent::AppSensor.isSqli(param_value))
196
+ appsensor_event("sqli", param_name, nil)
197
+ return
198
+ end
199
+ }
200
+ }
201
+ end
202
+
203
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("retr"))
204
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for Return Chars") {
205
+ for_get_params { | param_type, param_name, param_value |
206
+ if (TCellAgent::AppSensor.containsReturnChars(param_value))
207
+ appsensor_event("retr", param_name, nil)
208
+ return
209
+ end
210
+ }
211
+ }
212
+ end
213
+
214
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("null"))
215
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for Null") {
216
+ for_params { | param_type, param_name, param_value |
217
+ if (TCellAgent::AppSensor.containsNull(param_value))
218
+ appsensor_event("null", param_name, nil)
219
+ return
220
+ end
221
+ }
222
+ }
223
+ end
224
+
225
+ if (!@sensor_triggered && appsensor_policy.option_enabled?("null"))
226
+ TCellAgent::Instrumentation.safe_block("AppSensor Testing for File path traversal") {
227
+ for_params { | param_type, param_name, param_value |
228
+ if (TCellAgent::AppSensor.isPathTraversal(param_value))
229
+ appsensor_event("null", param_name, nil)
230
+ return
231
+ end
232
+ }
233
+ }
234
+ end
235
+
236
+ end
237
+
238
+ end
239
+ end
240
+ end