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,8 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require 'tcell_agent/logger'
4
+ require 'tcell_agent/configuration'
5
+
6
+ if (TCellAgent.configuration.enabled)
7
+ require 'tcell_agent/start_background_thread'
8
+ end
@@ -0,0 +1,33 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require 'tcell_agent/logger'
4
+ require 'tcell_agent/configuration'
5
+
6
+ module TCellAgent
7
+ TCellAgent.logger.debug("Instrumenting")
8
+ #if (TCellAgent.configuration.enabled && TCellAgent.configuration.instrument_for_events)
9
+ require 'tcell_agent/rails' if defined?(Rails)
10
+ require 'tcell_agent/sinatra' if defined?(Sinatra)
11
+ #end
12
+ end
13
+
14
+ require 'tcell_agent/agent'
15
+
16
+ require 'tcell_agent/policies/content_security_policy'
17
+ require 'tcell_agent/policies/http_tx_policy'
18
+ require 'tcell_agent/policies/http_redirect_policy'
19
+ require 'tcell_agent/policies/secure_headers_policy'
20
+ require 'tcell_agent/policies/honeytokens_policy'
21
+ require 'tcell_agent/policies/clickjacking_policy'
22
+ require 'tcell_agent/policies/appsensor_policy'
23
+ require 'tcell_agent/policies/add_script_tag_policy'
24
+ require 'tcell_agent/policies/login_fraud_policy'
25
+ require 'tcell_agent/policies/dataloss_policy'
26
+
27
+ require 'tcell_agent/sensor_events/app_sensor'
28
+ require 'tcell_agent/sensor_events/dlp'
29
+ require 'tcell_agent/appsensor'
30
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
31
+ require 'tcell_agent/sensor_events/util/redirect_utils'
32
+
33
+ require 'tcell_agent/dataloss'
@@ -0,0 +1,79 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require "tcell_agent/logger"
4
+ require "tcell_agent/version"
5
+ require "tcell_agent/api"
6
+ require "tcell_agent/configuration"
7
+
8
+ require "tcell_agent/sensor_events/server_agent"
9
+ require "tcell_agent/utils/queue_with_timeout"
10
+
11
+ require "tcell_agent/agent/event_processor"
12
+ require "tcell_agent/agent/policy_manager"
13
+ require "tcell_agent/agent/static_agent"
14
+ require "tcell_agent/agent/policy_types"
15
+
16
+ require 'net/http'
17
+ require 'thread'
18
+ require 'logger'
19
+ require 'json'
20
+
21
+ module TCellAgent
22
+ class Agent
23
+
24
+ attr_accessor :start_pid
25
+ attr_accessor :eventQueue
26
+ attr_accessor :policies
27
+ attr_accessor :eventProcessorThread
28
+ attr_accessor :route_counter_table
29
+
30
+ def initialize(start_pid)
31
+ @start_pid = start_pid
32
+ @lock = Monitor.new
33
+ @metricsLock = Monitor.new
34
+ @policies = {}
35
+ @route_counter_table = {}
36
+
37
+ @dispatchEventsTimeout = TCellAgent.configuration.event_time_limit_seconds || 30
38
+ @dispatchEventsLimit = TCellAgent.configuration.event_batch_size_limit || 20
39
+ @dispatchEvents = []
40
+
41
+ @eventQueue = QueueWithTimeout.new
42
+
43
+ if TCellAgent.configuration.preload_policy_filename != nil
44
+ TCellAgent.logger.info("Preloading a policy file");
45
+ begin
46
+ policy_file = open(TCellAgent.configuration.preload_policy_filename).read
47
+ policy_jsons = JSON.parse(policy_file)
48
+ if policy_jsons.key?("result")
49
+ policy_jsons = policy_jsons["result"]
50
+ end
51
+ processPolicyJson(policy_jsons, false)
52
+ rescue Exception => e
53
+ TCellAgent.logger.error(e.message)
54
+ end
55
+ end
56
+ cached_policies = policies_from_cachefile
57
+ if (cached_policies)
58
+ processPolicyJson(cached_policies, false)
59
+ end
60
+ end
61
+
62
+ def start
63
+ if (TCellAgent.configuration.api_key == nil ||
64
+ TCellAgent.configuration.app_id == nil)
65
+ puts " ********* ********* ********* *********"
66
+ puts "* tCell.io *"
67
+ puts "* Confiuration info is missing, you may *"
68
+ puts "* need to download config file and place *"
69
+ puts "* it in the config/ directory *"
70
+ puts " ********* ********* ********* *********"
71
+ return
72
+ end
73
+ self.start_event_processor()
74
+ self.start_policy_polling()
75
+
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,133 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require "tcell_agent/logger"
4
+ require "tcell_agent/version"
5
+ require "tcell_agent/api"
6
+ require "tcell_agent/configuration"
7
+
8
+ require "tcell_agent/policies/content_security_policy"
9
+ require "tcell_agent/policies/clickjacking_policy"
10
+ require "tcell_agent/policies/http_tx_policy"
11
+ require "tcell_agent/policies/http_redirect_policy"
12
+ require "tcell_agent/policies/secure_headers_policy"
13
+ require "tcell_agent/policies/honeytokens_policy"
14
+ require "tcell_agent/policies/appsensor_policy"
15
+ require "tcell_agent/policies/add_script_tag_policy"
16
+
17
+ require "tcell_agent/sensor_events/server_agent"
18
+ require "tcell_agent/sensor_events/metrics"
19
+
20
+ require "tcell_agent/utils/queue_with_timeout"
21
+
22
+ require 'net/http'
23
+ require 'thread'
24
+ require 'logger'
25
+ require 'json'
26
+
27
+
28
+ module TCellAgent
29
+ class Agent
30
+
31
+ def reset_dispatch
32
+ @dispatchEvents = []
33
+ end
34
+ def start_event_processor(send_empties=true)
35
+ @events_send_empties = send_empties
36
+
37
+ @eventProcessorThread = Thread.new do
38
+ TCellAgent.logger.debug("starting background event listener")
39
+ tapi = TCellApi.new
40
+
41
+ def dispatch(tapi, events)
42
+ if (@events_send_empties || events.length > 0)
43
+ metrics_event = TCellAgent::SensorEvents::MetricsEvent.new
44
+ metrics_event.set_route_count_table(@eventQueue.get_response_time_table)
45
+ events.push( metrics_event )
46
+ @eventQueue.reset_response_time_table
47
+ return tapi.sendEventSet(events)
48
+ end
49
+ return true
50
+ end
51
+
52
+ begin
53
+ event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
54
+ TCellAgent.send_event(event)
55
+
56
+ event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
57
+ TCellAgent.send_event(event)
58
+ rescue Exception => te
59
+ TCellAgent.logger.error("Exception sending initial events: #{te.message}")
60
+ TCellAgent.logger.debug(te.backtrace)
61
+ end
62
+ timeout_flag = false
63
+ last_run_time = Time.now
64
+ # orig = (Time.now.to_f * 1000).to_i
65
+ # response = @app.call(env)
66
+ # response_time = (Time.now.to_f * 1000).to_i - orig
67
+
68
+ loop do
69
+ begin
70
+ begin
71
+ now = Time.now
72
+ wait_for = @dispatchEventsTimeout - (now - last_run_time).to_i.abs
73
+ #puts "---- ---- "
74
+ #puts wait_for
75
+
76
+ event = @eventQueue.pop_with_timeout([wait_for, 0].max)
77
+ # puts "Hey, found event"
78
+ # puts event
79
+ if event["event_type"] == "RequestRouteTimer"
80
+ # puts "Request"
81
+ # puts event
82
+ route_id = event.route_id
83
+ # puts "Route"
84
+ # puts route_id
85
+ response_time = event.response_time
86
+ # puts "ROUTE"
87
+ #puts response_time
88
+ @eventQueue.add_response_time(route_id, response_time)
89
+ #puts @eventQueue.get_response_time_table
90
+ # puts "xxxx"
91
+ end
92
+ event.post_process
93
+ if event.send == true
94
+ @dispatchEvents.push(event)
95
+ end
96
+ if (event.flush or @dispatchEvents.length >= @dispatchEventsLimit or wait_for < 0)
97
+ last_run_time = Time.now
98
+ if ( dispatch(tapi, @dispatchEvents) )
99
+ self.reset_dispatch
100
+ else
101
+ @dispatchEvents = @dispatchEvents.find_all{|item| item.ensure == true }
102
+ end
103
+ end
104
+ rescue ThreadError => te
105
+ last_run_time = Time.now
106
+ if ( dispatch(tapi, @dispatchEvents) )
107
+ self.reset_dispatch
108
+ else
109
+ @dispatchEvents = @dispatchEvents.find_all{|item| item.ensure == true }
110
+ end
111
+ end
112
+ #puts "AFTER "
113
+ #puts Thread.current
114
+ rescue Exception => e
115
+ last_run_time = Time.now
116
+ TCellAgent.logger.error("Exception while processing events: #{e.message}")
117
+ TCellAgent.logger.debug(e.backtrace)
118
+ @dispatchEvents = @dispatchEvents.find_all{|item| item.ensure == true }
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ def queueSensorEvent(event)
125
+ if @eventProcessorThread != nil
126
+ if @eventQueue.length < 200
127
+ @eventQueue << event
128
+ end
129
+ end
130
+ end
131
+
132
+ end
133
+ end
@@ -0,0 +1,138 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require "tcell_agent/logger"
4
+ require "tcell_agent/version"
5
+ require "tcell_agent/api"
6
+ require "tcell_agent/configuration"
7
+
8
+ require "tcell_agent/agent/policy_types"
9
+
10
+ require "tcell_agent/policies/content_security_policy"
11
+ require "tcell_agent/policies/clickjacking_policy"
12
+ require "tcell_agent/policies/http_tx_policy"
13
+ require "tcell_agent/policies/http_redirect_policy"
14
+ require "tcell_agent/policies/secure_headers_policy"
15
+ require "tcell_agent/policies/honeytokens_policy"
16
+ require "tcell_agent/policies/appsensor_policy"
17
+ require "tcell_agent/policies/add_script_tag_policy"
18
+
19
+ require "tcell_agent/sensor_events/server_agent"
20
+
21
+ require "tcell_agent/utils/queue_with_timeout"
22
+
23
+ require 'net/http'
24
+ require 'thread'
25
+ require 'logger'
26
+ require 'json'
27
+
28
+ module TCellAgent
29
+ class Agent
30
+
31
+ def start_policy_polling
32
+ if TCellAgent.configuration.fetch_policies_from_tcell == true
33
+ TCellAgent.logger.debug("starting background polling thread")
34
+ @thread = Thread.new do
35
+ last_poll_time = 0
36
+ tapi = TCellApi.new
37
+ last_run = Time.now
38
+ loop do
39
+ begin
40
+ if (TCellAgent.configuration.version == 0)
41
+ policy_jsons = tapi.pollOldAPI(last_poll_time)
42
+ else
43
+ policy_jsons = tapi.pollAPI(last_poll_time)
44
+ end
45
+ if policy_jsons.key?("last_timestamp")
46
+ if policy_jsons["last_timestamp"] != 0
47
+ last_poll_time = policy_jsons["last_timestamp"]
48
+ end
49
+ elsif policy_jsons.key?("last_id")
50
+ if policy_jsons["last_id"] != 0
51
+ last_poll_time = policy_jsons["last_id"]
52
+ end
53
+ end
54
+ processPolicyJson(policy_jsons)
55
+ rescue Exception => e
56
+ TCellAgent.logger.error("uncaught exception while handling connection: #{e.message}")
57
+ TCellAgent.logger.debug(e.backtrace)
58
+ TCellAgent.logger.debug("Sleeping 60 seconds because the tCell.io request failed...")
59
+ sleep(60) #wait a minute before trying again
60
+ end
61
+ # A little rate limiting
62
+ if (Time.now - last_run) < 1
63
+ TCellAgent.logger.debug("Rate limiting: sleeping 30 seconds")
64
+ sleep(30)
65
+ end
66
+ last_run = Time.now
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def processPolicyJson(policy_jsons, cache_the_policy=true)
73
+
74
+ if policy_jsons == nil
75
+ return
76
+ end
77
+
78
+ if policy_jsons.key?("data")
79
+ policy_data = policy_jsons["data"]
80
+ end
81
+
82
+ TCellAgent::PolicyTypes::ClassMap.each do | policy_type, policy_class |
83
+ if (policy_jsons.key?(policy_type))
84
+ new_policy = policy_class.fromJson(policy_jsons[policy_type])
85
+ if new_policy
86
+ @lock.synchronize do
87
+ @policies[policy_type] = new_policy
88
+ if cache_the_policy
89
+ cache(policy_type, policy_jsons[policy_type])
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ end # end of processPolicyJson
97
+
98
+ def cache(policy_name, policy)
99
+ cache_filename = TCellAgent.configuration.cache_filename
100
+ if TCellAgent.configuration.app_id
101
+ cache_filename = cache_filename + '.' + TCellAgent.configuration.app_id
102
+ end
103
+ policy_cache = policies_from_cachefile()
104
+ if !policy_cache
105
+ policy_cache = {}
106
+ end
107
+ policy_cache[policy_name] = policy
108
+ begin
109
+ File.write(cache_filename, JSON.dump(policy_cache))
110
+ rescue Exception => e
111
+ TCellAgent.logger.error(e.message)
112
+ end
113
+ end
114
+
115
+ def policies_from_cachefile
116
+ cache_filename = TCellAgent.configuration.cache_filename
117
+ if TCellAgent.configuration.app_id
118
+ cache_filename = cache_filename + '.' + TCellAgent.configuration.app_id
119
+ end
120
+ cache_exists = File.exist?(cache_filename)
121
+ if !cache_exists
122
+ return nil
123
+ end
124
+ begin
125
+ policy_filedata = open(cache_filename).read
126
+ policy_jsons = JSON.parse(policy_filedata)
127
+ if policy_jsons.key?("result")
128
+ return policy_jsons["result"]
129
+ end
130
+ return policy_jsons
131
+ rescue Exception => e
132
+ TCellAgent.logger.error(e.message)
133
+ end
134
+ return nil
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,42 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require "tcell_agent/policies/content_security_policy"
4
+ require "tcell_agent/policies/clickjacking_policy"
5
+
6
+ require "tcell_agent/policies/http_tx_policy"
7
+ require "tcell_agent/policies/http_redirect_policy"
8
+ require "tcell_agent/policies/secure_headers_policy"
9
+ require "tcell_agent/policies/honeytokens_policy"
10
+ require "tcell_agent/policies/appsensor_policy"
11
+ require "tcell_agent/policies/add_script_tag_policy"
12
+ require "tcell_agent/policies/login_fraud_policy"
13
+ require "tcell_agent/policies/dataloss_policy"
14
+
15
+ module TCellAgent
16
+ class PolicyTypes
17
+ CSP = "csp-headers"
18
+ Clickjacking = "clickjacking"
19
+ SecureHeaders = "secure-headers"
20
+ HttpTx = "http-tx"
21
+ HttpRedirect = "http-redirect"
22
+ AppSensor = "appsensor"
23
+ AddScriptTag = "add-jsagent-script-tag"
24
+ HoneyTokens = "exp-honeytokens"
25
+ LoginFraud = "exp-login-fraud"
26
+ DataLoss = "dlp"
27
+
28
+ ClassMap = {
29
+ CSP=>TCellAgent::Policies::ContentSecurityPolicy,
30
+ Clickjacking=>TCellAgent::Policies::ClickjackingPolicy,
31
+ SecureHeaders=>TCellAgent::Policies::SecureHeadersPolicy,
32
+ HttpTx=>TCellAgent::Policies::HttpTxPolicy,
33
+ HttpRedirect=>TCellAgent::Policies::HttpRedirectPolicy,
34
+ AppSensor=>TCellAgent::Policies::AppSensorPolicy,
35
+ AddScriptTag=>TCellAgent::Policies::AddScriptTagPolicy,
36
+ HoneyTokens=>TCellAgent::Policies::HoneytokensPolicy,
37
+ LoginFraud=>TCellAgent::Policies::LoginFraudPolicy,
38
+ DataLoss=>TCellAgent::Policies::DataLossPolicy
39
+ }
40
+
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+ require 'tcell_agent/sensor_events/metrics'
3
+
4
+ module TCellAgent
5
+ class << self
6
+ attr_accessor :thread_agent
7
+ end
8
+ def self.send_event(event)
9
+ if (self.thread_agent != nil)
10
+ self.thread_agent.queueSensorEvent(event)
11
+ end
12
+ end
13
+ def self.policy(policy_type)
14
+ if (self.thread_agent != nil)
15
+ self.thread_agent.policies.fetch(policy_type, nil)
16
+ end
17
+ end
18
+ def self.increment_route(route_id, response_time)
19
+ event = TCellAgent::SensorEvents::RequestRouteTimer.new(route_id, response_time)
20
+ self.send_event(event)
21
+ end
22
+ end