tcell_agent 0.2.29 → 0.4.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.txt +7 -0
  3. data/bin/tcell_agent +9 -0
  4. data/lib/tcell_agent/agent/policy_manager.rb +3 -0
  5. data/lib/tcell_agent/agent/policy_types.rb +4 -1
  6. data/lib/tcell_agent/appsensor/injections_matcher.rb +20 -0
  7. data/lib/tcell_agent/appsensor/injections_reporter.rb +15 -56
  8. data/lib/tcell_agent/appsensor/meta_data.rb +56 -2
  9. data/lib/tcell_agent/appsensor/rules/baserules.json +371 -138
  10. data/lib/tcell_agent/cmdi.rb +113 -0
  11. data/lib/tcell_agent/config/unknown_options.rb +2 -0
  12. data/lib/tcell_agent/configuration.rb +30 -16
  13. data/lib/tcell_agent/hooks/login_fraud.rb +79 -0
  14. data/lib/tcell_agent/instrumentation.rb +6 -11
  15. data/lib/tcell_agent/patches/meta_data.rb +14 -11
  16. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +5 -9
  17. data/lib/tcell_agent/policies/appsensor_policy.rb +22 -206
  18. data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -2
  19. data/lib/tcell_agent/policies/command_injection_policy.rb +196 -0
  20. data/lib/tcell_agent/policies/content_security_policy.rb +3 -2
  21. data/lib/tcell_agent/policies/dataloss_policy.rb +3 -1
  22. data/lib/tcell_agent/policies/honeytokens_policy.rb +3 -1
  23. data/lib/tcell_agent/policies/http_redirect_policy.rb +51 -37
  24. data/lib/tcell_agent/policies/http_tx_policy.rb +5 -1
  25. data/lib/tcell_agent/policies/login_fraud_policy.rb +6 -1
  26. data/lib/tcell_agent/policies/patches_policy.rb +3 -1
  27. data/lib/tcell_agent/policies/policy.rb +10 -0
  28. data/lib/tcell_agent/policies/secure_headers_policy.rb +5 -2
  29. data/lib/tcell_agent/rails/auth/devise.rb +12 -23
  30. data/lib/tcell_agent/rails/csrf_exception.rb +1 -1
  31. data/lib/tcell_agent/rails/dlp.rb +50 -54
  32. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +0 -1
  33. data/lib/tcell_agent/rails/middleware/context_middleware.rb +0 -1
  34. data/lib/tcell_agent/rails/middleware/global_middleware.rb +0 -1
  35. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +7 -10
  36. data/lib/tcell_agent/rails/on_start.rb +0 -1
  37. data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -4
  38. data/lib/tcell_agent/rails.rb +0 -2
  39. data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
  40. data/lib/tcell_agent/rust/libtcellagent-0.6.1.so +0 -0
  41. data/lib/tcell_agent/rust/models.rb +61 -0
  42. data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
  43. data/lib/tcell_agent/rust/whisperer.rb +112 -0
  44. data/lib/tcell_agent/sensor_events/appsensor_event.rb +25 -21
  45. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +31 -24
  46. data/lib/tcell_agent/sensor_events/command_injection.rb +58 -0
  47. data/lib/tcell_agent/sensor_events/discovery.rb +1 -1
  48. data/lib/tcell_agent/sensor_events/login_fraud.rb +3 -13
  49. data/lib/tcell_agent/sensor_events/sensor.rb +81 -77
  50. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +8 -0
  51. data/lib/tcell_agent/start_background_thread.rb +12 -3
  52. data/lib/tcell_agent/utils/io.rb +4 -1
  53. data/lib/tcell_agent/utils/params.rb +1 -0
  54. data/lib/tcell_agent/version.rb +1 -1
  55. data/lib/tcell_agent.rb +0 -1
  56. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +27 -9
  57. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +143 -193
  58. data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +67 -0
  59. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -10
  60. data/spec/lib/tcell_agent/cmdi_spec.rb +748 -0
  61. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +8 -0
  62. data/spec/lib/tcell_agent/configuration_spec.rb +138 -6
  63. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +357 -0
  64. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +70 -87
  65. data/spec/lib/tcell_agent/patches_spec.rb +9 -4
  66. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +186 -9
  67. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +309 -484
  68. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +736 -0
  69. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +222 -41
  70. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +56 -32
  71. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +161 -85
  72. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +40 -72
  73. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +267 -0
  74. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +20 -15
  75. data/spec/spec_helper.rb +0 -9
  76. data/tcell_agent.gemspec +8 -3
  77. metadata +40 -39
  78. data/lib/tcell_agent/appsensor/sensor.rb +0 -52
  79. data/lib/tcell_agent/policies/appsensor/database_sensor.rb +0 -56
  80. data/lib/tcell_agent/policies/appsensor/misc_sensor.rb +0 -59
  81. data/lib/tcell_agent/policies/appsensor/payloads_policy.rb +0 -150
  82. data/lib/tcell_agent/policies/appsensor/request_size_sensor.rb +0 -25
  83. data/lib/tcell_agent/policies/appsensor/response_codes_sensor.rb +0 -73
  84. data/lib/tcell_agent/policies/appsensor/response_size_sensor.rb +0 -25
  85. data/lib/tcell_agent/policies/appsensor/size_sensor.rb +0 -71
  86. data/lib/tcell_agent/policies/appsensor/user_agent_sensor.rb +0 -47
  87. data/lib/tcell_agent/rails/auth/hooks.rb +0 -79
  88. data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +0 -22
  89. data/spec/lib/tcell_agent/policies/appsensor/database_sensor_spec.rb +0 -165
  90. data/spec/lib/tcell_agent/policies/appsensor/misc_sensor_spec.rb +0 -429
  91. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_apply_spec.rb +0 -466
  92. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_from_json_spec.rb +0 -890
  93. data/spec/lib/tcell_agent/policies/appsensor/payloads_policy_log_spec.rb +0 -417
  94. data/spec/lib/tcell_agent/policies/appsensor/request_size_sensor_spec.rb +0 -236
  95. data/spec/lib/tcell_agent/policies/appsensor/response_codes_sensor_spec.rb +0 -297
  96. data/spec/lib/tcell_agent/policies/appsensor/response_size_sensor_spec.rb +0 -241
  97. data/spec/lib/tcell_agent/policies/appsensor/user_agent_sensor_spec.rb +0 -172
  98. data/spec/lib/tcell_agent/rails/auth/hooks_spec.rb +0 -246
  99. data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +0 -25
  100. data/spec/support/resources/baserules.json +0 -155
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef449abceb02a45432746a68e50989438292c9c0
4
- data.tar.gz: 1b8ce68123c46d3a12cbc2262e4125948973ecf5
3
+ metadata.gz: 521d6057316a3d03d8f1b69dab4419c22bd52f08
4
+ data.tar.gz: 8296679382ce95cbc764e8cddcc2f5a42b8ce87b
5
5
  SHA512:
6
- metadata.gz: ac50286364897b7743cfd3dcfa9ed539f425142311b2eb675167a3362a84ba23c581ddb72342923723c35eeb3fbef7f4d0bc3b10ef4ff4ad0490b44fcd68a2f9
7
- data.tar.gz: a0b0b0e374279de26805a4710f13217c7682f58901621dd8b430f64d6a322aef4b6aa15f4441c2c26043249dca75b1b5cb4f41525faeac84c22264438c719475
6
+ metadata.gz: b8c8463350c03e01fe5d0a3da334500df9c81047bf8b5ce20378c4840ee9659523aa1ee44233aa18f27ac8f51977d5f3a36c5cc4f566e5f641ab745ace18a5f1
7
+ data.tar.gz: 44fd7f23e32263bab9643e33a3befab20e1f3848258c80055e663911f4f1607a53672426fcfff066094bcc13e759bd6df8eaad41f2b777d54acf9b83f374df51
data/Readme.txt ADDED
@@ -0,0 +1,7 @@
1
+ Config goes in config/tcell_agent.config
2
+ Fill in API key, Company Name, App Name
3
+
4
+ You can add
5
+ "tcell_api_url":"http://10.0.2.2:8000/api/v1",
6
+ "tcell_input_url":"http://10.0.2.2:3000"
7
+ to specify other servers to use
data/bin/tcell_agent CHANGED
@@ -268,6 +268,15 @@ elsif (command == 'test')
268
268
  Kernel.exit(1)
269
269
  end
270
270
  puts "passed"
271
+
272
+ printf "%-50s", "Loading native library... "
273
+ require 'tcell_agent/rust/whisperer'
274
+ if !TCellAgent::Rust::Wrapper.common_lib_available?
275
+ puts "failed"
276
+ Kernel.exit(1)
277
+ end
278
+ puts "passed"
279
+
271
280
  puts
272
281
  puts "all tests passed, looks good."
273
282
  puts "done."
@@ -141,10 +141,13 @@ module TCellAgent
141
141
  new_policy = policy_class.from_json(policy_jsons[policy_type])
142
142
  if new_policy
143
143
  @lock.synchronize do
144
+ old_policy = @policies[policy_type]
144
145
  @policies[policy_type] = new_policy
145
146
  if cache_the_policy
146
147
  cache(policy_type, policy_jsons[policy_type])
147
148
  end
149
+
150
+ old_policy.free_native_memory if old_policy
148
151
  end
149
152
  end
150
153
  end
@@ -13,6 +13,7 @@ require "tcell_agent/policies/appsensor_policy"
13
13
  require "tcell_agent/policies/login_fraud_policy"
14
14
  require "tcell_agent/policies/dataloss_policy"
15
15
  require "tcell_agent/policies/patches_policy"
16
+ require "tcell_agent/policies/command_injection_policy"
16
17
 
17
18
  module TCellAgent
18
19
  class PolicyTypes
@@ -26,6 +27,7 @@ module TCellAgent
26
27
  LoginFraud = "login"
27
28
  DataLoss = "dlp"
28
29
  Patches = "patches"
30
+ CommandInjection = "cmdi"
29
31
 
30
32
  ClassMap = {
31
33
  CSP=>TCellAgent::Policies::ContentSecurityPolicy,
@@ -37,7 +39,8 @@ module TCellAgent
37
39
  HoneyTokens=>TCellAgent::Policies::HoneytokensPolicy,
38
40
  LoginFraud=>TCellAgent::Policies::LoginFraudPolicy,
39
41
  DataLoss=>TCellAgent::Policies::DataLossPolicy,
40
- Patches=>TCellAgent::Policies::PatchesPolicy
42
+ Patches=>TCellAgent::Policies::PatchesPolicy,
43
+ CommandInjection=>TCellAgent::Policies::CommandInjectionPolicy
41
44
  }
42
45
 
43
46
  end
@@ -1,3 +1,12 @@
1
+ require 'tcell_agent/policies/appsensor/cmdi_sensor'
2
+ require 'tcell_agent/policies/appsensor/fpt_sensor'
3
+ require 'tcell_agent/policies/appsensor/nullbyte_sensor'
4
+ require 'tcell_agent/policies/appsensor/retr_sensor'
5
+ require 'tcell_agent/policies/appsensor/sqli_sensor'
6
+ require 'tcell_agent/policies/appsensor/xss_sensor'
7
+ require 'tcell_agent/utils/params'
8
+
9
+
1
10
  module TCellAgent
2
11
  module AppSensor
3
12
 
@@ -7,6 +16,7 @@ module TCellAgent
7
16
  JSON_PARAM = TCellAgent::Utils::Params::JSON_PARAM
8
17
  COOKIE_PARAM = TCellAgent::Utils::Params::COOKIE_PARAM
9
18
  URI_PARAM = TCellAgent::Utils::Params::URI_PARAM
19
+ HEADER_PARAM = TCellAgent::Utils::Params::HEADER_PARAM
10
20
 
11
21
  DETECTION_POINTS_V2 = {
12
22
  "xss" => TCellAgent::Policies::XssSensor,
@@ -75,6 +85,16 @@ module TCellAgent
75
85
  yield(injection_attempt) if injection_attempt
76
86
  end
77
87
  end
88
+
89
+ meta_data.flattened_headers_dict.each do |param_name, param_value|
90
+ TCellAgent::Instrumentation.safe_block("AppSensor Check HEADER var injections") do
91
+ param_name = param_name[-1]
92
+ injection_attempt =
93
+ check_param_for_injections(HEADER_PARAM, meta_data, param_name, param_value)
94
+
95
+ yield(injection_attempt) if injection_attempt
96
+ end
97
+ end
78
98
  end
79
99
 
80
100
  def check_param_for_injections(param_type, appsensor_meta, param_name, param_value)
@@ -1,68 +1,27 @@
1
- require 'tcell_agent/appsensor/sensor'
2
- require 'tcell_agent/utils/params'
1
+ require 'tcell_agent/sensor_events/appsensor_event'
3
2
 
4
3
 
5
4
  module TCellAgent
6
5
  module AppSensor
7
6
 
8
- class InjectionsReporter
9
- GET_PARAM = TCellAgent::Utils::Params::GET_PARAM
10
- POST_PARAM = TCellAgent::Utils::Params::POST_PARAM
11
- JSON_PARAM = TCellAgent::Utils::Params::JSON_PARAM
12
- COOKIE_PARAM = TCellAgent::Utils::Params::COOKIE_PARAM
13
- URI_PARAM = TCellAgent::Utils::Params::URI_PARAM
14
-
15
- PARAM_TYPE_TO_L = {
16
- GET_PARAM => 'query',
17
- POST_PARAM => 'body',
18
- JSON_PARAM => 'body',
19
- URI_PARAM => 'uri',
20
- COOKIE_PARAM => 'cookie'
21
- }
22
-
23
- attr_accessor :injections_matcher, :payloads_policy, :collect_full_uri
24
-
25
- def initialize(injections_matcher, payloads_policy, collect_full_uri)
26
- @injections_matcher = injections_matcher
27
- @payloads_policy = payloads_policy
28
- @collect_full_uri = collect_full_uri
29
- end
30
-
31
- def check(appsensor_meta)
32
- @injections_matcher.each_injection(appsensor_meta) do |injection_attempt|
33
- vuln_param = injection_attempt.param_name
34
- type_of_param = injection_attempt.type_of_param
35
-
36
- meta = {"l" => PARAM_TYPE_TO_L[type_of_param]}
37
- pattern = injection_attempt.pattern
38
-
39
- payload = @payloads_policy.apply(
40
- injection_attempt.detection_point,
41
- appsensor_meta,
42
- type_of_param,
43
- vuln_param,
44
- injection_attempt.param_value,
45
- meta,
46
- pattern
7
+ module InjectionsReporter
8
+ def self.report_and_log(events)
9
+ (events || []).each do |event|
10
+ TCellAgent.send_event(
11
+ TCellAgent::SensorEvents::TCellAppSensorEvent.build_from_native_lib_event(event)
47
12
  )
48
13
 
49
- TCellAgent::AppSensor::Sensor.send_event(
50
- appsensor_meta,
51
- injection_attempt.detection_point,
52
- vuln_param,
53
- meta,
54
- payload,
55
- pattern,
56
- @collect_full_uri)
57
- end
58
- end
59
-
60
- def self.from_json(version, data_json, payloads_policy, collect_full_uri=false)
61
- injections_matcher = InjectionsMatcher.from_json(version, data_json)
14
+ if event.has_key?("full_payload")
15
+ event_to_log = {}.merge(event)
16
+ event_to_log["payload"] = event_to_log.delete("full_payload")
62
17
 
63
- InjectionsReporter.new(injections_matcher, payloads_policy, collect_full_uri)
18
+ cleaned_event = TCellAgent::SensorEvents::TCellAppSensorEvent.build_from_native_lib_event(
19
+ event_to_log
20
+ )
21
+ TCellAgent.logger.info(JSON.dump(cleaned_event))
22
+ end
23
+ end
64
24
  end
65
-
66
25
  end
67
26
 
68
27
  end
@@ -7,16 +7,52 @@ module TCellAgent
7
7
 
8
8
  class MetaData < TCellAgent::SensorEvents::TCellSensorEvent
9
9
 
10
- attr_accessor :get_dict, :post_dict, :body_dict, :cookie_dict, :path_parameters
10
+ attr_accessor :get_dict, :post_dict, :body_dict, :cookie_dict, :path_parameters,
11
+ :remote_address, :method, :route_id, :session_id, :user_id, :transaction_id
11
12
 
12
- def initialize
13
+ attr_reader :headers_dict
14
+
15
+ def initialize(method, remote_address, route_id, session_id, user_id, transaction_id)
13
16
  @send = false
14
17
 
18
+ @method = method
19
+ @remote_address = remote_address
20
+ @route_id = route_id
21
+ @session_id = session_id
22
+ @user_id = user_id
23
+ @transaction_id = transaction_id
24
+
15
25
  @body_dict = {}
16
26
  @get_dict = {}
17
27
  @post_dict = {}
18
28
  @cookie_dict = {}
19
29
  @path_parameters = {}
30
+ @headers_dict = {}
31
+ end
32
+
33
+ def get_dict=(value)
34
+ @flattened_get_dict = nil
35
+ @get_dict = value
36
+ end
37
+
38
+ def body_dict=(value)
39
+ @flattened_body_dict = nil
40
+ @body_dict = value
41
+ end
42
+
43
+ def post_dict=(value)
44
+ @flattened_post_dict = nil
45
+ @post_dict = value
46
+ end
47
+
48
+ def cookie_dict=(value)
49
+ @flattened_cookie_dict = nil
50
+ @cookie_dict = value
51
+ end
52
+
53
+ def path_parameters=(value)
54
+ @flattened_path_parameters = nil
55
+ @path_parameters = value
20
56
  end
21
57
 
22
58
  def flattened_path_parameters
@@ -47,6 +83,24 @@ module TCellAgent
47
83
  @flattened_cookie_dict
48
84
  end
49
85
 
86
+ def flattened_headers_dict
87
+ @flattened_headers_dict ||= TCellAgent::Utils::Params.flatten(@headers_dict)
88
+
89
+ @flattened_headers_dict
90
+ end
91
+
92
+ def set_headers_dict(env)
93
+ @flattened_headers_dict = nil
94
+ @headers_dict = env.select { |k,v|
95
+ header_downcased = k.downcase
96
+ (header_downcased != "http_cookie" && header_downcased.start_with?('http_')) ||
97
+ ["content_type", "content_length"].include?(header_downcased)
98
+ }.inject({}) { |memo, (k,v)|
99
+ memo[k.downcase.sub(/^http_/, '').gsub('_', '-')] = v
100
+ memo
101
+ }
102
+ end
103
+
50
104
  def set_body_dict(request_content_bytes_len, request_content_type, request_body)
51
105
  if request_content_bytes_len > 2000000
52
106
  @body_dict = {}