tcell_agent 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +4 -0
- data/README.md +43 -0
- data/Rakefile +7 -0
- data/bin/tcell_agent +171 -0
- data/config/initializers/authlogic_auth.rb +51 -0
- data/config/initializers/devise_auth.rb +167 -0
- data/config/initializers/init.rb +8 -0
- data/lib/tcell_agent.rb +33 -0
- data/lib/tcell_agent/agent.rb +79 -0
- data/lib/tcell_agent/agent/event_processor.rb +133 -0
- data/lib/tcell_agent/agent/policy_manager.rb +138 -0
- data/lib/tcell_agent/agent/policy_types.rb +42 -0
- data/lib/tcell_agent/agent/static_agent.rb +22 -0
- data/lib/tcell_agent/api.rb +101 -0
- data/lib/tcell_agent/appsensor.rb +42 -0
- data/lib/tcell_agent/appsensor/cmdi.rb +32 -0
- data/lib/tcell_agent/appsensor/path_traversal.rb +33 -0
- data/lib/tcell_agent/appsensor/sqli.rb +55 -0
- data/lib/tcell_agent/appsensor/xss.rb +40 -0
- data/lib/tcell_agent/authlogic.rb +26 -0
- data/lib/tcell_agent/configuration.rb +148 -0
- data/lib/tcell_agent/dataloss.rb +0 -0
- data/lib/tcell_agent/devise.rb +83 -0
- data/lib/tcell_agent/instrumentation.rb +44 -0
- data/lib/tcell_agent/logger.rb +46 -0
- data/lib/tcell_agent/policies/add_script_tag_policy.rb +47 -0
- data/lib/tcell_agent/policies/appsensor_policy.rb +76 -0
- data/lib/tcell_agent/policies/clickjacking_policy.rb +113 -0
- data/lib/tcell_agent/policies/content_security_policy.rb +119 -0
- data/lib/tcell_agent/policies/dataloss_policy.rb +175 -0
- data/lib/tcell_agent/policies/honeytokens_policy.rb +67 -0
- data/lib/tcell_agent/policies/http_redirect_policy.rb +84 -0
- data/lib/tcell_agent/policies/http_tx_policy.rb +60 -0
- data/lib/tcell_agent/policies/login_fraud_policy.rb +42 -0
- data/lib/tcell_agent/policies/secure_headers_policy.rb +64 -0
- data/lib/tcell_agent/rails.rb +146 -0
- data/lib/tcell_agent/rails/devise.rb +0 -0
- data/lib/tcell_agent/rails/dlp.rb +204 -0
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +69 -0
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +50 -0
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +53 -0
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +176 -0
- data/lib/tcell_agent/rails/routes.rb +130 -0
- data/lib/tcell_agent/rails/settings_reporter.rb +40 -0
- data/lib/tcell_agent/sensor_events/app_config.rb +16 -0
- data/lib/tcell_agent/sensor_events/app_sensor.rb +240 -0
- data/lib/tcell_agent/sensor_events/dlp.rb +58 -0
- data/lib/tcell_agent/sensor_events/honeytokens.rb +16 -0
- data/lib/tcell_agent/sensor_events/login_fraud.rb +43 -0
- data/lib/tcell_agent/sensor_events/metrics.rb +24 -0
- data/lib/tcell_agent/sensor_events/sensor.rb +85 -0
- data/lib/tcell_agent/sensor_events/server_agent.rb +101 -0
- data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +22 -0
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +153 -0
- data/lib/tcell_agent/sensor_events/util/utils.rb +21 -0
- data/lib/tcell_agent/sinatra.rb +41 -0
- data/lib/tcell_agent/start_background_thread.rb +63 -0
- data/lib/tcell_agent/userinfo.rb +8 -0
- data/lib/tcell_agent/utils/queue_with_timeout.rb +60 -0
- data/lib/tcell_agent/version.rb +5 -0
- data/spec/controllers/application_controller.rb +12 -0
- data/spec/lib/tcell_agent/api/api_spec.rb +36 -0
- data/spec/lib/tcell_agent/appsensor_spec.rb +66 -0
- data/spec/lib/tcell_agent/policies/add_script_tag_policy_spec.rb +37 -0
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +40 -0
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +71 -0
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +71 -0
- data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +88 -0
- data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +22 -0
- data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +62 -0
- data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +22 -0
- data/spec/lib/tcell_agent/policies/login_policy_spec.rb +42 -0
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +67 -0
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +187 -0
- data/spec/lib/tcell_agent/rails_spec.rb +57 -0
- data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +14 -0
- data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +25 -0
- data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +57 -0
- data/spec/lib/tcell_agent_spec.rb +22 -0
- data/spec/resources/normal_config.json +13 -0
- data/spec/spec_helper.rb +4 -0
- data/tcell_agent.gemspec +29 -0
- metadata +249 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module TCellAgent
|
4
|
+
module Policies
|
5
|
+
class DataLossPolicy
|
6
|
+
class FilterActions
|
7
|
+
attr_accessor :body_event
|
8
|
+
attr_accessor :body_redact
|
9
|
+
attr_accessor :body_hash
|
10
|
+
|
11
|
+
attr_accessor :log_event
|
12
|
+
attr_accessor :log_redact
|
13
|
+
attr_accessor :log_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :session_id_filter_actions
|
17
|
+
attr_accessor :request_filter_actions
|
18
|
+
attr_accessor :database_filter_actions
|
19
|
+
|
20
|
+
# {
|
21
|
+
# {"context":[]}
|
22
|
+
# }
|
23
|
+
|
24
|
+
attr_accessor :policy_id
|
25
|
+
|
26
|
+
attr_accessor :table_field_actions
|
27
|
+
attr_accessor :session_id_actions
|
28
|
+
|
29
|
+
attr_accessor :field_redact_body
|
30
|
+
attr_accessor :field_alerts
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
self.init_options
|
34
|
+
end
|
35
|
+
def init_options
|
36
|
+
@policy_id = nil
|
37
|
+
|
38
|
+
@table_field_actions = {}
|
39
|
+
@session_id_actions = []
|
40
|
+
|
41
|
+
@field_redact_body = Set.new #["work_infos.SSN"].to_set #
|
42
|
+
@field_alerts = Set.new
|
43
|
+
|
44
|
+
@session_id_filter_actions = nil
|
45
|
+
@request_filter_actions = {
|
46
|
+
"form"=>Hash.new{|h,k| h[k] = FilterActions.new},
|
47
|
+
"cookie"=>Hash.new{|h,k| h[k] = FilterActions.new},
|
48
|
+
"header"=>Hash.new{|h,k| h[k] = FilterActions.new}
|
49
|
+
}
|
50
|
+
@log_actions = nil
|
51
|
+
end
|
52
|
+
def get_actions_for_session_id(route_id=nil)
|
53
|
+
return @session_id_filter_actions
|
54
|
+
end
|
55
|
+
def get_actions_for_request(context, route_id=nil)
|
56
|
+
return @request_filter_actions.fetch(context)
|
57
|
+
end
|
58
|
+
def get_actions_for(table, field)
|
59
|
+
actions = Set.new
|
60
|
+
key = "#{table}.#{field}"
|
61
|
+
actions.merge(@table_field_actions.fetch(key,[].to_set))
|
62
|
+
#if (@field_redact_body.include?(key))
|
63
|
+
# actions += ["body_redact"]
|
64
|
+
#end
|
65
|
+
#if (@field_redact_log.include?(key))
|
66
|
+
# actions += ["log_redact"]
|
67
|
+
#end
|
68
|
+
return actions
|
69
|
+
end
|
70
|
+
def self.fromJson(policy_json)
|
71
|
+
if (!policy_json)
|
72
|
+
return nil
|
73
|
+
end
|
74
|
+
policy = DataLossPolicy.new
|
75
|
+
if policy_json.has_key?("policy_id")
|
76
|
+
policy.policy_id = policy_json["policy_id"]
|
77
|
+
else
|
78
|
+
raise "Policy ID missing"
|
79
|
+
end
|
80
|
+
if policy_json.has_key?("data")
|
81
|
+
data_json = policy_json["data"]
|
82
|
+
if data_json.has_key?("session_id_protection")
|
83
|
+
session_id_protection = data_json["session_id_protection"]
|
84
|
+
if session_id_protection.fetch("body",nil)
|
85
|
+
if (session_id_protection["body"].include? "redact")
|
86
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
87
|
+
policy.session_id_filter_actions.body_redact = true
|
88
|
+
end
|
89
|
+
if (session_id_protection["body"].include? "event")
|
90
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
91
|
+
policy.session_id_filter_actions.body_event = true
|
92
|
+
end
|
93
|
+
if (session_id_protection["body"].include? "hash")
|
94
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
95
|
+
policy.session_id_filter_actions.body_hash = true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
if session_id_protection.fetch("log",nil)
|
99
|
+
if (session_id_protection["log"].include? "redact")
|
100
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
101
|
+
policy.session_id_filter_actions.log_redact = true
|
102
|
+
end
|
103
|
+
if (session_id_protection["log"].include? "event")
|
104
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
105
|
+
policy.session_id_filter_actions.log_event = true
|
106
|
+
end
|
107
|
+
if (session_id_protection["log"].include? "hash")
|
108
|
+
policy.session_id_filter_actions ||= FilterActions.new
|
109
|
+
policy.session_id_filter_actions.log_hash = true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
if data_json.has_key?("request_protections")
|
114
|
+
data_json["request_protections"].each do |protection|
|
115
|
+
context = protection.fetch('context', nil)
|
116
|
+
variable = protection.fetch('variable', nil)
|
117
|
+
scope = protection.fetch('scope', "global")
|
118
|
+
options = protection.fetch('options', nil)
|
119
|
+
if scope != "global"
|
120
|
+
next
|
121
|
+
end
|
122
|
+
if context && policy.request_filter_actions.has_key?(context) && variable && options
|
123
|
+
if options.has_key?("log")
|
124
|
+
if (options["log"].include? "redact")
|
125
|
+
policy.request_filter_actions[context][variable].log_redact = true
|
126
|
+
end
|
127
|
+
if (options["log"].include? "event")
|
128
|
+
policy.request_filter_actions[context][variable].log_event = true
|
129
|
+
end
|
130
|
+
if (options["log"].include? "hash")
|
131
|
+
policy.request_filter_actions[context][variable].log_hash = true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
if options.has_key?("body")
|
135
|
+
if (options["body"].include? "redact")
|
136
|
+
policy.request_filter_actions[context][variable].body_redact = true
|
137
|
+
end
|
138
|
+
if (options["body"].include? "event")
|
139
|
+
policy.request_filter_actions[context][variable].body_event = true
|
140
|
+
end
|
141
|
+
if (options["body"].include? "hash")
|
142
|
+
policy.request_filter_actions[context][variable].body_hash = true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
if data_json.has_key?("protections")
|
149
|
+
protections_json = data_json["protections"]
|
150
|
+
protections_json.each do |protection|
|
151
|
+
_table = protection.fetch("table", nil)
|
152
|
+
_field = protection.fetch("field", nil)
|
153
|
+
actions = protection.fetch("actions", {})
|
154
|
+
if actions.fetch("body",nil)
|
155
|
+
if (actions["body"].include? "redact")
|
156
|
+
if (_table && _field)
|
157
|
+
(policy.table_field_actions["#{_table}.#{_field}"] ||= []) << "body_redact"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
if actions.fetch("log",nil)
|
162
|
+
if (actions["log"].include? "redact")
|
163
|
+
if (_table && _field)
|
164
|
+
(policy.table_field_actions["#{_table}.#{_field}"] ||= []) << "log_redact"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
return policy
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
#String sh_policy_string = ""
|
4
|
+
#+"{"
|
5
|
+
#+"\"policy_id\":\"00a1\","
|
6
|
+
#+"\"token_salt\":\"salt123\","
|
7
|
+
#+"\"tokens\": ["
|
8
|
+
#+" {\"type\":\"cred\", \"id\":\"deny\", \"token\":\"abcdefgh\"}"
|
9
|
+
#+" ]"
|
10
|
+
#+"}";
|
11
|
+
require 'pbkdf2'
|
12
|
+
require 'openssl'
|
13
|
+
|
14
|
+
module TCellAgent
|
15
|
+
module Policies
|
16
|
+
class HoneytokensPolicy
|
17
|
+
attr_accessor :policy_id
|
18
|
+
attr_accessor :token_salt
|
19
|
+
attr_accessor :cred_tokens
|
20
|
+
|
21
|
+
def id_for_credentialstring(credential_string)
|
22
|
+
if cred_tokens
|
23
|
+
credential_hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), token_salt, credential_string)
|
24
|
+
if cred_tokens.has_key?(credential_hmac)
|
25
|
+
return cred_tokens[credential_hmac]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.fromJson(policy_json)
|
32
|
+
if (!policy_json)
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
|
36
|
+
honeytokens_policy = HoneytokensPolicy.new
|
37
|
+
if policy_json.has_key?("policy_id")
|
38
|
+
honeytokens_policy.policy_id = policy_json["policy_id"]
|
39
|
+
else
|
40
|
+
raise "Policy ID missing"
|
41
|
+
end
|
42
|
+
|
43
|
+
if policy_json.has_key?("token_salt")
|
44
|
+
honeytokens_policy.token_salt = policy_json["token_salt"]
|
45
|
+
else
|
46
|
+
raise "Token Salt missing"
|
47
|
+
end
|
48
|
+
|
49
|
+
if policy_json.has_key?("tokens")
|
50
|
+
tokens = policy_json["tokens"]
|
51
|
+
tokens.each do |token|
|
52
|
+
if (token.has_key?("type") && token.has_key?("id") && token.has_key?("token"))
|
53
|
+
if (token["type"] == "cred")
|
54
|
+
if honeytokens_policy.cred_tokens == nil
|
55
|
+
honeytokens_policy.cred_tokens = {}
|
56
|
+
end
|
57
|
+
honeytokens_policy.cred_tokens[token["token"]] = token["id"]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
return honeytokens_policy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
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
|
+
|
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
|
+
#},
|
16
|
+
|
17
|
+
module TCellAgent
|
18
|
+
module Policies
|
19
|
+
class HttpRedirectPolicy
|
20
|
+
attr_accessor :policy_id
|
21
|
+
attr_accessor :enabled
|
22
|
+
attr_accessor :whitelist
|
23
|
+
attr_accessor :block
|
24
|
+
def initialize
|
25
|
+
@policy_id = nil
|
26
|
+
@enabled = false
|
27
|
+
@whitelist = []
|
28
|
+
@block = false
|
29
|
+
end
|
30
|
+
def check(host, current_host)
|
31
|
+
if (!(host) || host == "" || host == current_host)
|
32
|
+
# local redirect
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
if (whitelist)
|
36
|
+
whitelist.each do |domain|
|
37
|
+
if (TCellAgent::SensorEvents::Util.wildcardMatch(host, domain))
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
def enforce(target_url, current_host, current_path, method, status_code, remote_addr)
|
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
|
52
|
+
end
|
53
|
+
begin
|
54
|
+
event = TCellAgent::SensorEvents::TCellRedirectSensorEvent.new(host, current_host, current_path, method, status_code, remote_addr)
|
55
|
+
TCellAgent.send_event(event)
|
56
|
+
rescue Exception => ie
|
57
|
+
TCellAgent.logger.error("uncaught exception while creating redirect event: #{ie.message}")
|
58
|
+
end
|
59
|
+
if @block == true
|
60
|
+
return "/"
|
61
|
+
end
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
def self.fromJson(policy_json)
|
65
|
+
if (!policy_json)
|
66
|
+
return nil
|
67
|
+
end
|
68
|
+
http_redirect_policy = HttpRedirectPolicy.new
|
69
|
+
if policy_json.has_key?("policy_id")
|
70
|
+
http_redirect_policy.policy_id = policy_json["policy_id"]
|
71
|
+
else
|
72
|
+
raise "Policy ID missing"
|
73
|
+
end
|
74
|
+
if policy_json.has_key?("data")
|
75
|
+
policy_data_json = policy_json["data"]
|
76
|
+
http_redirect_policy.enabled = policy_data_json.fetch("enabled", false)
|
77
|
+
http_redirect_policy.whitelist = policy_data_json.fetch("whitelist", [])
|
78
|
+
http_redirect_policy.block = policy_data_json.fetch("block", false)
|
79
|
+
end
|
80
|
+
return http_redirect_policy
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#{}"http-tx": {
|
2
|
+
# "policy_id":"afh023",
|
3
|
+
# "types": {
|
4
|
+
# "firehose": { enabled: true },
|
5
|
+
#{}"auth_framework_only": {enabled: true},
|
6
|
+
#{}"{}structure": {enabled: true },
|
7
|
+
#{}"fingerprint": {enabled: true }
|
8
|
+
#}
|
9
|
+
#},
|
10
|
+
|
11
|
+
module TCellAgent
|
12
|
+
module Policies
|
13
|
+
class HttpTxPolicy
|
14
|
+
attr_accessor :policy_id
|
15
|
+
attr_accessor :firehose
|
16
|
+
attr_accessor :auth_framework
|
17
|
+
attr_accessor :profile
|
18
|
+
attr_accessor :fingerprint
|
19
|
+
|
20
|
+
def initialize()
|
21
|
+
@firehose = {"enabled"=>false, "lite"=>false }
|
22
|
+
@auth_framework = {"enabled"=>false, "lite"=>false }
|
23
|
+
@profile = {"enabled"=>false }
|
24
|
+
@fingerprint = {"enabled"=>false, "hmacUserAgent"=>false, "hmacUserId"=>false, "sampling"=>nil }
|
25
|
+
end
|
26
|
+
def self.fromJson(policy_json)
|
27
|
+
if (!policy_json)
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
http_tx_policy = HttpTxPolicy.new
|
31
|
+
if policy_json.has_key?("policy_id")
|
32
|
+
http_tx_policy.policy_id = policy_json["policy_id"]
|
33
|
+
else
|
34
|
+
raise "Policy ID missing"
|
35
|
+
end
|
36
|
+
if policy_json.has_key?("types")
|
37
|
+
types = policy_json["types"]
|
38
|
+
if types.has_key?("firehose")
|
39
|
+
http_tx_policy.firehose["enabled"] = types["firehose"].fetch("enabled", false)
|
40
|
+
http_tx_policy.firehose["lite"] = types["firehose"].fetch("lite", false)
|
41
|
+
end
|
42
|
+
if types.has_key?("auth_framework")
|
43
|
+
http_tx_policy.auth_framework["enabled"] = types["auth_framework"].fetch("enabled", false)
|
44
|
+
http_tx_policy.auth_framework["lite"] = types["auth_framework"].fetch("lite", false)
|
45
|
+
end
|
46
|
+
if types.has_key?("profile")
|
47
|
+
http_tx_policy.profile["enabled"] = types["profile"].fetch("enabled", false)
|
48
|
+
end
|
49
|
+
if types.has_key?("fingerprint")
|
50
|
+
http_tx_policy.fingerprint["enabled"] = types["fingerprint"].fetch("enabled", false)
|
51
|
+
http_tx_policy.fingerprint["hmacUserAgent"] = types["fingerprint"].fetch("hmacUserAgent", false)
|
52
|
+
http_tx_policy.fingerprint["hmacUserId"] = types["fingerprint"].fetch("hmacUserId", false)
|
53
|
+
http_tx_policy.fingerprint["sampling"] = types["fingerprint"].fetch("sampling", 0)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
return http_tx_policy
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module TCellAgent
|
2
|
+
module Policies
|
3
|
+
class LoginFraudPolicy
|
4
|
+
attr_accessor :policy_id
|
5
|
+
|
6
|
+
attr_accessor :login_success_enabled
|
7
|
+
attr_accessor :login_failed_enabled
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.init_options
|
11
|
+
end
|
12
|
+
def init_options
|
13
|
+
@policy_id = nil
|
14
|
+
@login_success_enabled = false
|
15
|
+
@login_failed_enabled = false
|
16
|
+
end
|
17
|
+
def enabled
|
18
|
+
@login_success_enabled || @login_failed_enabled
|
19
|
+
end
|
20
|
+
def self.fromJson(policy_json)
|
21
|
+
if (!policy_json)
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
sensor_policy = LoginFraudPolicy.new
|
25
|
+
if policy_json.has_key?("policy_id")
|
26
|
+
sensor_policy.policy_id = policy_json["policy_id"]
|
27
|
+
else
|
28
|
+
raise "Policy ID missing"
|
29
|
+
end
|
30
|
+
if policy_json.has_key?("data")
|
31
|
+
data_json = policy_json["data"]
|
32
|
+
if data_json.has_key?("options")
|
33
|
+
options_json = data_json["options"]
|
34
|
+
sensor_policy.login_failed_enabled = options_json.fetch("login_failed_enabled", false)
|
35
|
+
sensor_policy.login_success_enabled = options_json.fetch("login_success_enabled", false)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return sensor_policy
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# See the file "LICENSE" for the full license governing this code.
|
3
|
+
module TCellAgent
|
4
|
+
module Policies
|
5
|
+
class SecureHeadersPolicy
|
6
|
+
class SecurityHeader
|
7
|
+
@@approved_headers = [
|
8
|
+
"strict-transport-security",
|
9
|
+
"x-frame-options",
|
10
|
+
"x-xss-protection",
|
11
|
+
"x-content-type-options",
|
12
|
+
"x-permitted-cross-domain-policies",
|
13
|
+
"x-download-options"
|
14
|
+
]
|
15
|
+
attr_accessor :name
|
16
|
+
attr_accessor :value
|
17
|
+
def initialize(name, value)
|
18
|
+
if !(name && value)
|
19
|
+
raise "Name and value were not set"
|
20
|
+
end
|
21
|
+
if not @@approved_headers.include?(name.downcase)
|
22
|
+
raise "Name was not included in approved_headers"
|
23
|
+
end
|
24
|
+
if value != value.gsub(/[^\p{L}\w\d\-_\ :\/,;.'\*"%?@#=$]/,'')
|
25
|
+
raise "Value is not valid"
|
26
|
+
end
|
27
|
+
self.name = name
|
28
|
+
self.value = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :headers
|
33
|
+
attr_accessor :policy_id
|
34
|
+
|
35
|
+
def self.fromJson(policy_json)
|
36
|
+
if (!policy_json)
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
security_headers_policy = SecureHeadersPolicy.new
|
40
|
+
if policy_json.has_key?("policy_id")
|
41
|
+
security_headers_policy.policy_id = policy_json["policy_id"]
|
42
|
+
else
|
43
|
+
raise "Policy ID missing"
|
44
|
+
end
|
45
|
+
security_headers = []
|
46
|
+
if policy_json.has_key?("headers")
|
47
|
+
headers = policy_json["headers"]
|
48
|
+
headers.each do |header|
|
49
|
+
if header.has_key?("name") && header.has_key?("value")
|
50
|
+
begin
|
51
|
+
security_header = SecurityHeader.new(header["name"], header["value"])
|
52
|
+
security_headers.push(security_header)
|
53
|
+
rescue Exception => secure_header_exception
|
54
|
+
TCellAgent.logger.debug("Could not load secure header:" + secure_header_exception.message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
security_headers_policy.headers = security_headers
|
60
|
+
return security_headers_policy
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|