tcell_agent 0.2.29 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,231 +1,47 @@
1
1
  require 'tcell_agent/instrumentation'
2
2
  require 'tcell_agent/appsensor/injections_reporter'
3
- require 'tcell_agent/policies/appsensor/cmdi_sensor'
4
- require 'tcell_agent/policies/appsensor/database_sensor'
5
- require 'tcell_agent/policies/appsensor/fpt_sensor'
6
- require 'tcell_agent/policies/appsensor/misc_sensor'
7
- require 'tcell_agent/policies/appsensor/nullbyte_sensor'
8
- require 'tcell_agent/policies/appsensor/payloads_policy'
9
- require 'tcell_agent/policies/appsensor/request_size_sensor'
10
- require 'tcell_agent/policies/appsensor/response_codes_sensor'
11
- require 'tcell_agent/policies/appsensor/response_size_sensor'
12
- require 'tcell_agent/policies/appsensor/retr_sensor'
13
- require 'tcell_agent/policies/appsensor/sqli_sensor'
14
- require 'tcell_agent/policies/appsensor/user_agent_sensor'
15
- require 'tcell_agent/policies/appsensor/xss_sensor'
16
- require 'tcell_agent/utils/params'
3
+ require 'tcell_agent/rust/models'
4
+ require 'tcell_agent/rust/whisperer'
5
+ require 'tcell_agent/policies/policy'
17
6
 
18
7
 
19
8
  module TCellAgent
20
9
  module Policies
21
10
 
22
- class AppSensorPolicy
23
- DETECTION_POINTS_V1 = [
24
- "req_res_size",
25
- "resp_codes",
26
- "ua",
27
- "errors",
28
- "database"]
11
+ class AppSensorPolicy < Policy
12
+ attr_reader :appfirewall_enabled, :appfirewall_ptr
29
13
 
30
- DETECTION_POINTS_V2 = {
31
- "req_size" => RequestSizeSensor,
32
- "resp_size" => ResponseSizeSensor,
33
- "resp_codes" => ResponseCodesSensor,
34
- "xss" => XssSensor,
35
- "sqli" => SqliSensor,
36
- "cmdi" => CmdiSensor,
37
- "fpt" => FptSensor,
38
- "nullbyte" => NullbyteSensor,
39
- "retr" => RetrSensor,
40
- "ua" => UserAgentSensor,
41
- "errors" => MiscSensor,
42
- "database" => DatabaseSensor
43
- }
44
-
45
- DETECTION_POINTS_V2_NON_INJECTION = {
46
- "req_size" => RequestSizeSensor,
47
- "resp_size" => ResponseSizeSensor,
48
- "resp_codes" => ResponseCodesSensor,
49
- "ua" => UserAgentSensor,
50
- "errors" => MiscSensor,
51
- "database" => DatabaseSensor
52
- }
53
-
54
- attr_accessor :policy_id, :options, :enabled, :injections_reporter
55
-
56
- def initialize
57
- @policy_id = nil
58
- @options = Hash.new
59
- @enabled = false
60
- @injections_reporter =
61
- TCellAgent::AppSensor::InjectionsReporter.from_json(0, {}, PayloadsPolicy.new)
14
+ def initialize(appfirewall_enabled=false, appfirewall_ptr=nil)
15
+ @appfirewall_ptr = appfirewall_ptr
16
+ @appfirewall_enabled = appfirewall_enabled
62
17
  end
63
18
 
64
19
  def process_meta_event(appsensor_meta)
65
- return unless @enabled
66
-
67
- check_user_agent(appsensor_meta)
68
- check_request_size(appsensor_meta)
69
- check_response_size(appsensor_meta)
70
- check_response_code(appsensor_meta)
71
-
72
- @injections_reporter.check(appsensor_meta)
73
- end
74
-
75
- def process_db_rows(tcell_data, number_of_records)
76
- return unless @enabled
77
-
78
- TCellAgent::Instrumentation.safe_block("AppSensor Testing Number of DB Rows") do
79
- if self.options.has_key?("database")
80
- self.options["database"].check(tcell_data, number_of_records)
81
- end
82
- end
83
- end
84
-
85
- def check_user_agent(appsensor_meta)
86
- TCellAgent::Instrumentation.safe_block("AppSensor Checking User Agent") do
87
- if self.options.has_key?("ua")
88
- self.options["ua"].check(appsensor_meta)
89
- end
90
- end
91
- end
92
-
93
- def check_request_size(appsensor_meta)
94
- TCellAgent::Instrumentation.safe_block("AppSensor Testing Response Size") do
95
- if self.options.has_key?("req_size")
96
- self.options["req_size"].check(appsensor_meta)
97
- end
98
- end
99
- end
100
-
101
- def check_response_size(appsensor_meta)
102
- return unless @enabled
103
-
104
- TCellAgent::Instrumentation.safe_block("AppSensor Testing Response Size") do
105
- if self.options.has_key?("resp_size")
106
- self.options["resp_size"].check(appsensor_meta)
107
- end
108
- end
109
- end
110
-
111
- def check_response_code(appsensor_meta)
112
- TCellAgent::Instrumentation.safe_block("AppSensor Testing Response Code") do
113
- if self.options.has_key?("resp_codes")
114
- self.options["resp_codes"].check(appsensor_meta, appsensor_meta.response_code)
115
- end
116
- end
117
- end
20
+ return unless @appfirewall_enabled && @appfirewall_ptr
118
21
 
119
- def csrf_rejected(tcell_data, exception_class)
120
- TCellAgent::Instrumentation.safe_block("AppSensor CSRF Exception processing") do
121
- if self.options.has_key?("errors")
122
- self.options["errors"].csrf_rejected(tcell_data, exception_class)
123
- end
22
+ TCellAgent::Instrumentation.safe_block("AppSensor inspection") do
23
+ request_response = TCellAgent::Rust::Models.create_request_response(appsensor_meta)
24
+ whisper = TCellAgent::Rust::Whisperer.apply_appfirewall(@appfirewall_ptr, request_response)
25
+ TCellAgent::AppSensor::InjectionsReporter.report_and_log(whisper["apply_response"])
124
26
  end
125
27
  end
126
28
 
127
- def sql_exception_detected(tcell_data, exception)
128
- TCellAgent::Instrumentation.safe_block("AppSensor SQL Exception processing") do
129
- if self.options.has_key?("errors")
130
- self.options["errors"].sql_exception_detected(tcell_data, exception)
131
- end
132
- end
29
+ def free_native_memory
30
+ TCellAgent::Rust::Whisperer.free_appfirewall(@appfirewall_ptr) if @appfirewall_ptr
133
31
  end
134
32
 
135
33
  def self.from_json(policy_json)
136
34
  return nil unless policy_json
137
- policy_json = policy_json.deep_dup
138
35
 
139
- sensor_policy = AppSensorPolicy.new
140
- if policy_json.has_key?("policy_id")
141
- sensor_policy.policy_id = policy_json["policy_id"]
36
+ whisper = TCellAgent::Rust::Whisperer.init_appfirewall(
37
+ policy_json, TCellAgent.configuration.allow_payloads
38
+ )
39
+ if whisper["error"]
40
+ TCellAgent.logger.debug("Error initializing AppFirewall Policy: #{whisper['error']}")
41
+ return AppSensorPolicy.new
142
42
  else
143
- raise "Policy ID missing"
144
- end
145
-
146
- if policy_json.has_key?("data")
147
- data_json = policy_json["data"]
148
-
149
- if policy_json["version"] && policy_json["version"] == 2
150
- if data_json
151
- sensors_json = data_json.fetch("sensors", {})
152
-
153
- if sensors_json.empty?
154
- sensor_policy.enabled = false
155
-
156
- else
157
- sensor_policy.enabled = true
158
-
159
- options_hash = data_json.fetch("options", {})
160
- collect_full_uri = options_hash.fetch("uri_options", {}).fetch("collect_full_uri", false)
161
-
162
- DETECTION_POINTS_V2_NON_INJECTION.each do |sensor_name, sensor_class|
163
- settings = sensors_json.fetch(sensor_name, {})
164
- updated_settings = {
165
- "enabled" => sensors_json.has_key?(sensor_name),
166
- "collect_full_uri" => collect_full_uri
167
- }.merge(settings)
168
-
169
- sensor_policy.options[sensor_name] =
170
- sensor_class.new(updated_settings)
171
- end
172
-
173
- payloads_policy = PayloadsPolicy.from_json(options_hash)
174
- sensor_policy.injections_reporter =
175
- TCellAgent::AppSensor::InjectionsReporter.from_json(
176
- 2, sensors_json, payloads_policy, collect_full_uri)
177
- end
178
- end
179
-
180
- else
181
- if data_json
182
- options_json = data_json.fetch("options", {})
183
-
184
- if options_json.empty?
185
- sensor_policy.enabled = false
186
-
187
- else
188
- sensor_policy.enabled = true
189
-
190
- payloads_policy = PayloadsPolicy.from_json({
191
- "payloads" => {
192
- "send_payloads" => true,
193
- "log_payloads" => true
194
- }
195
- })
196
-
197
- sensor_policy.injections_reporter =
198
- TCellAgent::AppSensor::InjectionsReporter.from_json(1, data_json, payloads_policy)
199
-
200
- enabled = options_json.fetch("req_res_size", false)
201
- sensor_policy.options["req_size"] = RequestSizeSensor.new({"enabled" => enabled})
202
- sensor_policy.options["resp_size"] = ResponseSizeSensor.new({"enabled" => enabled})
203
-
204
- enabled = options_json.fetch("resp_codes", false)
205
- sensor_policy.options["resp_codes"] = ResponseCodesSensor.new({
206
- "enabled" => enabled,
207
- "series_400_enabled" => true,
208
- "series_500_enabled" => true})
209
-
210
- sensor_policy.options["ua"] = UserAgentSensor.new({
211
- "enabled" => false, "empty_enabled" => false
212
- })
213
-
214
- sensor_policy.options["errors"] = MiscSensor.new({
215
- "enabled" => false,
216
- "csrf_exception_enabled" => false,
217
- "sql_exception_enabled" => false
218
- })
219
-
220
- sensor_policy.options["database"] = DatabaseSensor.new({
221
- "enabled" => false
222
- })
223
- end
224
- end
225
- end
43
+ return AppSensorPolicy.new(whisper["enabled"], whisper["policy_ptr"])
226
44
  end
227
-
228
- return sensor_policy
229
45
  end
230
46
  end
231
47
 
@@ -2,10 +2,11 @@
2
2
  # See the file "LICENSE" for the full license governing this code.
3
3
 
4
4
  require 'uri'
5
+ require 'tcell_agent/policies/policy'
5
6
 
6
7
  module TCellAgent
7
8
  module Policies
8
- class ClickjackingPolicy
9
+ class ClickjackingPolicy < Policy
9
10
  class ContentSecurityPolicyHeader
10
11
  @@approved_headers = [
11
12
  "csp"
@@ -71,8 +72,9 @@ module TCellAgent
71
72
  end
72
73
  result.each(&block)
73
74
  end
75
+
74
76
  def self.from_json(policy_json)
75
- if (!policy_json)
77
+ if (!policy_json)
76
78
  return nil
77
79
  end
78
80
  csp = ClickjackingPolicy.new
@@ -0,0 +1,196 @@
1
+ require 'tcell_agent/rust/whisperer'
2
+ require 'tcell_agent/sensor_events/command_injection'
3
+ require 'tcell_agent/policies/policy'
4
+
5
+
6
+ module TCellAgent
7
+ module Policies
8
+
9
+ class CommandRule
10
+ IGNORE = "ignore"
11
+ REPORT = "report"
12
+ BLOCK = "block"
13
+
14
+ attr_reader :rule_id, :action, :command
15
+
16
+ def initialize(policy_json)
17
+ @rule_id = nil
18
+ @action = nil
19
+ @command = nil
20
+
21
+ if policy_json
22
+ @rule_id = policy_json["rule_id"]
23
+ @action = policy_json["action"]
24
+ @command = policy_json["command"]
25
+ end
26
+ end
27
+
28
+ def ignore?
29
+ @action == IGNORE
30
+ end
31
+
32
+ def report?
33
+ @action == REPORT
34
+ end
35
+
36
+ def block?
37
+ @action == BLOCK
38
+ end
39
+
40
+ def valid?
41
+ !!@rule_id && [IGNORE, REPORT, BLOCK].include?(@action)
42
+ end
43
+ end
44
+
45
+ class CommandInjectionPolicy < Policy
46
+ attr_accessor :policy_id, :version, :enabled, :overall_action, :command_rules, :compound_statement_rule,
47
+ :collect_full_commandline
48
+
49
+ def initialize
50
+ @enabled = false
51
+ @version = nil
52
+ @policy_id = nil
53
+ @overall_action = nil
54
+ @command_rules = {}
55
+ @compound_statement_rule = nil
56
+ @collect_full_commandline = false
57
+ end
58
+
59
+ def self.from_json(policy_json)
60
+ return nil unless policy_json
61
+ policy_json = policy_json.deep_dup
62
+
63
+ policy_id = policy_json["policy_id"]
64
+
65
+ raise "Policy ID missing" unless policy_id
66
+
67
+ command_injection_policy = CommandInjectionPolicy.new
68
+ command_injection_policy.policy_id = policy_id
69
+ command_injection_policy.version = policy_json["version"]
70
+
71
+ if 1 != command_injection_policy.version
72
+ TCellAgent.logger.error("Command Injection not supported: #{command_injection_policy.version}")
73
+ return command_injection_policy
74
+ end
75
+
76
+ policy_data = policy_json["data"]
77
+ command_rules = {}
78
+ overall_action = nil
79
+ compound_statement_rule = nil
80
+ if policy_data
81
+ command_injection_policy.collect_full_commandline = !!policy_data["collect_full_commandline"]
82
+
83
+ (policy_data["command_rules"] or []).each do |command_rule_policy|
84
+ command_rule = CommandRule.new(command_rule_policy)
85
+ if command_rule.valid?
86
+ command = command_rule.command
87
+ if command
88
+ if command_rules.has_key?(command)
89
+ TCellAgent.logger.warn(
90
+ "CommandInjectionPolicy multiple rules for one " +
91
+ "command (dropping rule): #{command} #{command_rule.action}"
92
+ )
93
+ else
94
+ command_rules[command] = command_rule
95
+ end
96
+ elsif !command_rule.ignore?
97
+ overall_action = command_rule
98
+ end
99
+ end
100
+ end
101
+
102
+ compound_statement_rules = policy_data["compound_statement_rules"]
103
+ if compound_statement_rules && compound_statement_rules.size > 0
104
+ compound_statement_rule = CommandRule.new(compound_statement_rules[0])
105
+ if !compound_statement_rule.valid? || compound_statement_rule.ignore?
106
+ compound_statement_rule = nil
107
+ end
108
+ end
109
+
110
+ command_injection_policy.command_rules = command_rules
111
+ command_injection_policy.overall_action = overall_action
112
+ command_injection_policy.compound_statement_rule = compound_statement_rule
113
+ command_injection_policy.enabled = !overall_action.nil? || !compound_statement_rule.nil? || command_rules.size > 0
114
+ end
115
+
116
+ command_injection_policy
117
+ end
118
+
119
+ def block?(cmd, tcell_context)
120
+ return false unless @enabled
121
+
122
+ commands = parse_cmd(cmd).fetch('commands', [])
123
+
124
+ command_injection_match_events = []
125
+ block_command = false
126
+
127
+ if commands.size > 1 && !!@compound_statement_rule
128
+ if !@compound_statement_rule.ignore?
129
+ command_injection_match_events.push(
130
+ TCellAgent::SensorEvents::CommandInjectionMatchEvent.new(
131
+ @compound_statement_rule.rule_id, @compound_statement_rule.command
132
+ )
133
+ )
134
+ block_command = block_command || @compound_statement_rule.block?
135
+ end
136
+ end
137
+
138
+ commands.each do |command_info|
139
+ command = command_info["command"]
140
+ command_rule = command_rules[command] || @overall_action
141
+ if command_rule && !command_rule.ignore?
142
+ command_injection_match_events.push(
143
+ TCellAgent::SensorEvents::CommandInjectionMatchEvent.new(
144
+ command_rule.rule_id,
145
+ command
146
+ )
147
+ )
148
+ block_command = block_command || command_rule.block?
149
+ end
150
+ end
151
+
152
+ if command_injection_match_events.size > 0
153
+ method, remote_address, route_id, session_id, user_id, full_commandline = nil
154
+ if tcell_context
155
+ method = tcell_context.request_method
156
+ remote_address = tcell_context.ip_address
157
+ route_id = tcell_context.route_id
158
+ session_id = tcell_context.hmac_session_id
159
+ user_id = tcell_context.user_id
160
+ end
161
+
162
+ if @collect_full_commandline
163
+ full_commandline = cmd
164
+ end
165
+
166
+ TCellAgent.send_event(
167
+ TCellAgent::SensorEvents::CommandInjectionEvent.new(
168
+ commands,
169
+ block_command,
170
+ command_injection_match_events,
171
+ method=method,
172
+ remote_address=remote_address,
173
+ route_id=route_id,
174
+ session_id=session_id,
175
+ user_id=user_id,
176
+ full_commandline=full_commandline
177
+ )
178
+ )
179
+ end
180
+
181
+ block_command
182
+ end
183
+
184
+ private
185
+ def parse_cmd(cmd)
186
+ TCellAgent::Instrumentation.safe_block("Call Rust Parse Command") do
187
+ require "tcell_agent/rust/whisperer"
188
+
189
+ return TCellAgent::Rust::Whisperer.parse_cmd(cmd)
190
+ end
191
+
192
+ return {}
193
+ end
194
+ end
195
+ end
196
+ end
@@ -2,13 +2,14 @@
2
2
  # See the file "LICENSE" for the full license governing this code.
3
3
 
4
4
  require 'uri'
5
- require 'tcell_agent/sensor_events/util/sanitizer_utilities'
6
5
  require 'tcell_agent/configuration'
6
+ require 'tcell_agent/policies/policy'
7
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
7
8
 
8
9
  module TCellAgent
9
10
  module Policies
10
11
 
11
- class ContentSecurityPolicy
12
+ class ContentSecurityPolicy < Policy
12
13
  class ContentSecurityPolicyHeader
13
14
  @@approved_headers = [
14
15
  "csp",
@@ -1,8 +1,10 @@
1
1
  require 'set'
2
+ require 'tcell_agent/policies/policy'
3
+
2
4
 
3
5
  module TCellAgent
4
6
  module Policies
5
- class DataLossPolicy
7
+ class DataLossPolicy < Policy
6
8
  class FilterActions
7
9
  attr_accessor :body_event
8
10
  attr_accessor :body_redact
@@ -10,10 +10,12 @@
10
10
  #+"}";
11
11
  require 'pbkdf2'
12
12
  require 'openssl'
13
+ require 'tcell_agent/policies/policy'
14
+
13
15
 
14
16
  module TCellAgent
15
17
  module Policies
16
- class HoneytokensPolicy
18
+ class HoneytokensPolicy < Policy
17
19
  attr_accessor :policy_id
18
20
  attr_accessor :token_salt
19
21
  attr_accessor :cred_tokens
@@ -1,58 +1,59 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
  require 'uri'
3
- require 'tcell_agent/logger'
4
- require 'tcell_agent/sensor_events/util/redirect_utils'
5
- # See the file "LICENSE" for the full license governing this code.
6
3
 
7
- #{}"http-tx": {
8
- # "policy_id":"afh023",
9
- # "types": {
10
- # "firehose": { enabled: true },
11
- #{}"auth_framework_only": {enabled: true},
12
- #{}"{}structure": {enabled: true },
13
- #{}"fingerprint": {enabled: true }
14
- #}
15
- #},
4
+ require 'tcell_agent/policies/policy'
5
+ require 'tcell_agent/logger'
16
6
 
17
7
  module TCellAgent
18
8
  module Policies
19
- class HttpRedirectPolicy
20
- attr_accessor :policy_id
21
- attr_accessor :enabled
22
- attr_accessor :whitelist
23
- attr_accessor :block
9
+
10
+ class HttpRedirectPolicy < Policy
11
+ attr_accessor :policy_id, :enabled, :whitelist, :block, :data_scheme_allowed
12
+
24
13
  def initialize
25
14
  @policy_id = nil
26
15
  @enabled = false
27
16
  @whitelist = []
28
17
  @block = false
18
+ @data_scheme_allowed = false
29
19
  end
30
- def check(host, current_host)
20
+
21
+ def suspicious_redirect?(host, current_host)
31
22
  if (!(host) || host == "" || host == current_host)
32
23
  # local redirect
33
24
  return false
34
25
  end
35
- if (whitelist)
36
- whitelist.each do |domain|
37
- if (TCellAgent::SensorEvents::Util.wildcardMatch(host, domain))
38
- return false
39
- end
26
+
27
+ whitelist.each do |whitelist_regex|
28
+ if (host =~ whitelist_regex) || ("www.#{host}" =~ whitelist_regex)
29
+ return false
40
30
  end
41
31
  end
42
- return true
32
+
33
+ true
43
34
  end
44
- def enforce(target_url, current_host, current_path, method, route_id, status_code, remote_addr, hmac_session_id=nil)
45
- if @enabled == false
46
- return nil
47
- end
48
- uri = URI.parse(target_url)
49
- host = uri.host
50
- if self.check(host, current_host) == false
51
- return nil
35
+
36
+ def enforce(target_uri, request_uri, current_path, method, route_id, status_code, remote_addr, hmac_session_id=nil)
37
+ return nil unless @enabled
38
+
39
+ current_host = URI.parse(request_uri).host
40
+ if target_uri.downcase.start_with?("data:")
41
+ if @data_scheme_allowed
42
+ return nil
43
+ end
44
+
45
+ target_host = target_uri.split(",")[0]
46
+
47
+ else
48
+ target_host = URI.parse(target_uri).host
49
+ if !self.suspicious_redirect?(target_host, current_host)
50
+ return nil
51
+ end
52
52
  end
53
+
53
54
  begin
54
55
  event = TCellAgent::SensorEvents::TCellRedirectSensorEvent.new(
55
- host,
56
+ target_host,
56
57
  current_host,
57
58
  current_path,
58
59
  method,
@@ -66,29 +67,42 @@ module TCellAgent
66
67
  rescue Exception => ie
67
68
  TCellAgent.logger.error("uncaught exception while creating redirect event: #{ie.message}")
68
69
  end
69
- if @block == true
70
+
71
+ if @block
70
72
  return "/"
73
+ else
74
+ return nil
71
75
  end
72
- return nil
73
76
  end
77
+
74
78
  def self.from_json(policy_json)
75
- if (!policy_json)
79
+ if (!policy_json)
76
80
  return nil
77
81
  end
82
+
78
83
  http_redirect_policy = HttpRedirectPolicy.new
79
84
  if policy_json.has_key?("policy_id")
80
85
  http_redirect_policy.policy_id = policy_json["policy_id"]
81
86
  else
82
87
  raise "Policy ID missing"
83
88
  end
89
+
84
90
  if policy_json.has_key?("data")
85
91
  policy_data_json = policy_json["data"]
86
92
  http_redirect_policy.enabled = policy_data_json.fetch("enabled", false)
87
- http_redirect_policy.whitelist = policy_data_json.fetch("whitelist", [])
88
93
  http_redirect_policy.block = policy_data_json.fetch("block", false)
94
+ http_redirect_policy.data_scheme_allowed = policy_data_json.fetch("dataSchemeAllowed", false)
95
+
96
+ http_redirect_policy.whitelist = []
97
+ policy_data_json.fetch("whitelist", []).each do |regex_pattern|
98
+ escaped = Regexp.escape(regex_pattern).gsub('\*','.*?')
99
+ http_redirect_policy.whitelist.push(Regexp.new("^#{escaped}$", Regexp::IGNORECASE))
100
+ end
89
101
  end
102
+
90
103
  return http_redirect_policy
91
104
  end
92
105
  end
106
+
93
107
  end
94
108
  end
@@ -8,9 +8,12 @@
8
8
  #}
9
9
  #},
10
10
 
11
+ require 'tcell_agent/policies/policy'
12
+
13
+
11
14
  module TCellAgent
12
15
  module Policies
13
- class HttpTxPolicy
16
+ class HttpTxPolicy < Policy
14
17
  attr_accessor :policy_id
15
18
  attr_accessor :firehose
16
19
  attr_accessor :auth_framework
@@ -23,6 +26,7 @@ module TCellAgent
23
26
  @profile = {"enabled"=>false }
24
27
  @fingerprint = {"enabled"=>false, "hmacUserAgent"=>false, "hmacUserId"=>false, "sampling"=>nil }
25
28
  end
29
+
26
30
  def self.from_json(policy_json)
27
31
  if (!policy_json)
28
32
  return nil