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,58 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
|
+
require 'tcell_agent/sensor_events/sensor'
|
5
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
6
|
+
module TCellAgent
|
7
|
+
module SensorEvents
|
8
|
+
class DlpEvent < TCellSensorEvent
|
9
|
+
FOUND_IN_BODY = "body"
|
10
|
+
FOUND_IN_LOG = "log"
|
11
|
+
FOUND_IN_CONSOLE = "console"
|
12
|
+
|
13
|
+
FRAMEWORK_VARIABLE_SESSION_ID="session_id"
|
14
|
+
|
15
|
+
REQUEST_CONTEXT_FORM = "form"
|
16
|
+
REQUEST_CONTEXT_COOKIE = "cookie"
|
17
|
+
REQUEST_CONTEXT_HEADER = "header"
|
18
|
+
|
19
|
+
def initialize(route_id, raw_uri, found_in, hmac_session_id=nil, user_id=nil)
|
20
|
+
super("dlp")
|
21
|
+
self["rid"] = route_id
|
22
|
+
self["found_in"] = found_in
|
23
|
+
@raw_uri = raw_uri
|
24
|
+
if hmac_session_id
|
25
|
+
self["sid"] = hmac_session_id
|
26
|
+
end
|
27
|
+
if user_id
|
28
|
+
self["uid"] = user_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
def for_database(database, schema, table, field)
|
32
|
+
self["type"] = "db"
|
33
|
+
self["db"] = database
|
34
|
+
self["schema"] = schema
|
35
|
+
self["table"] = table
|
36
|
+
self["field"] = field
|
37
|
+
return self
|
38
|
+
end
|
39
|
+
def for_framework(variable)
|
40
|
+
self["type"] = "framework"
|
41
|
+
self["context"] = "framework"
|
42
|
+
self["variable"] = variable
|
43
|
+
return self
|
44
|
+
end
|
45
|
+
def for_request(variable_context, variable)
|
46
|
+
self["type"] = "request"
|
47
|
+
self["context"] = variable_context
|
48
|
+
self["variable"] = variable
|
49
|
+
return self
|
50
|
+
end
|
51
|
+
def post_process
|
52
|
+
if @raw_uri
|
53
|
+
self["uri"] = Util.strip_uri_values(@raw_uri)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
|
+
require 'tcell_agent/sensor_events/sensor'
|
5
|
+
|
6
|
+
module TCellAgent
|
7
|
+
module SensorEvents
|
8
|
+
class HoneytokensSensorEvent < TCellSensorEvent
|
9
|
+
def initialize(request, token_id)
|
10
|
+
super("honeytoken")
|
11
|
+
self["id"] = token_id
|
12
|
+
self["ip"] = request.remote_ip
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
|
+
require 'tcell_agent/sensor_events/sensor'
|
5
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
6
|
+
module TCellAgent
|
7
|
+
module SensorEvents
|
8
|
+
|
9
|
+
class LoginFailure < TCellSensorEvent
|
10
|
+
def initialize(request, response, user_id, hmac_session_id)
|
11
|
+
super("login")
|
12
|
+
headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
|
13
|
+
.collect {|k,v| k.sub(/^HTTP_/, '') }
|
14
|
+
self["event_name"] = "login-failure"
|
15
|
+
self["user_agent"] = request.env['HTTP_USER_AGENT']
|
16
|
+
self["referrer"] = request.referer
|
17
|
+
self["remote_addr"] = request.remote_ip
|
18
|
+
self["header_keys"] = headers
|
19
|
+
self["user_id"] = user_id
|
20
|
+
self["document_uri"] = TCellAgent::SensorEvents::Util.strip_uri_values(request.path)
|
21
|
+
self["session"] = hmac_session_id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class LoginSuccess < TCellSensorEvent
|
26
|
+
attr_accessor :event_name
|
27
|
+
def initialize(request, response, user_id, hmac_session_id)
|
28
|
+
super("login")
|
29
|
+
headers = request.env.select {|k,v| k.start_with? 'HTTP_'}
|
30
|
+
.collect {|k,v| k.sub(/^HTTP_/, '') }
|
31
|
+
self["event_name"] = "login-success"
|
32
|
+
self["user_agent"] = request.env['HTTP_USER_AGENT']
|
33
|
+
self["referrer"] = request.referer
|
34
|
+
self["remote_addr"] = request.remote_ip
|
35
|
+
self["header_keys"] = headers
|
36
|
+
self["user_id"] = user_id
|
37
|
+
self["document_uri"] = TCellAgent::SensorEvents::Util.strip_uri_values(request.path)
|
38
|
+
self["session"] = hmac_session_id
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
module TCellAgent
|
4
|
+
module SensorEvents
|
5
|
+
class RequestRouteTimer < TCellSensorEvent
|
6
|
+
attr_accessor :route_id
|
7
|
+
attr_accessor :response_time
|
8
|
+
def initialize(route_id, response_time)
|
9
|
+
super("RequestRouteTimer")
|
10
|
+
self.route_id = route_id
|
11
|
+
self.response_time = response_time
|
12
|
+
@send = false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class MetricsEvent < TCellSensorEvent
|
16
|
+
def initialize()
|
17
|
+
super("metrics")
|
18
|
+
end
|
19
|
+
def set_route_count_table(route_count_table)
|
20
|
+
self["rct"] = route_count_table
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
|
+
require 'tcell_agent/logger'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module TCellAgent
|
8
|
+
module SensorEvents
|
9
|
+
class TCellSensorEvent < Hash
|
10
|
+
attr_accessor :send
|
11
|
+
attr_accessor :flush
|
12
|
+
attr_accessor :ensure
|
13
|
+
def initialize(event_type)
|
14
|
+
@send = true
|
15
|
+
@flush = false
|
16
|
+
@ensure = false
|
17
|
+
@timestamp = DateTime.now.to_time.to_i
|
18
|
+
self["event_type"] = event_type
|
19
|
+
end
|
20
|
+
def calculateOffset(from_timestamp)
|
21
|
+
self["offset"] = from_timestamp - @timestamp
|
22
|
+
end
|
23
|
+
def post_process
|
24
|
+
# This is called in the background thread, so any
|
25
|
+
# santization, analysis, etc doesn't get in the way
|
26
|
+
end
|
27
|
+
end
|
28
|
+
class TCellHttpTxSensorEvent < TCellSensorEvent
|
29
|
+
def initialize(request, response)
|
30
|
+
super("http_tx")
|
31
|
+
@raw_request = request
|
32
|
+
@raw_response = response
|
33
|
+
end
|
34
|
+
def post_process
|
35
|
+
if defined?@raw_request
|
36
|
+
self["request"] = Util.request_sanitized_json(@raw_request)
|
37
|
+
end
|
38
|
+
if defined?@raw_response
|
39
|
+
self["response"] = Util.response_sanitized_json(@raw_response)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
class TCellRedirectSensorEvent < TCellSensorEvent
|
44
|
+
def initialize(redirect_domain, original_domain, original_url, method, status_code, remote_addr, user_id=nil, session_id=nil)
|
45
|
+
super("redirect")
|
46
|
+
@raw_original_url = original_url
|
47
|
+
self["method"] = method
|
48
|
+
self["from_domain"] = original_domain
|
49
|
+
self["status_code"] = status_code
|
50
|
+
self["remote_addr"] = remote_addr
|
51
|
+
@raw_redirect_domain = redirect_domain
|
52
|
+
@user_id = user_id
|
53
|
+
@raw_session_id = session_id
|
54
|
+
end
|
55
|
+
def post_process
|
56
|
+
self["from"] = Util.strip_uri_values(@raw_original_url)
|
57
|
+
self["to"] = @raw_redirect_domain
|
58
|
+
if @raw_session_id
|
59
|
+
hmac_key = Util.getHmacKey()
|
60
|
+
self["sid"] = Util.hmac(@raw_session_id, hmac_key)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
class TCellFingerprintSensorEvent < TCellSensorEvent
|
65
|
+
def initialize(request, session_id, user_id=nil)
|
66
|
+
super("fingerprint")
|
67
|
+
@raw_request = request
|
68
|
+
@raw_session_id = session_id
|
69
|
+
@user_id = user_id
|
70
|
+
end
|
71
|
+
def post_process
|
72
|
+
if !(@raw_request.headers.key?("HTTP_USER_AGENT"))
|
73
|
+
raise "User Agent not Found!"
|
74
|
+
end
|
75
|
+
self["ua"] = @raw_request.headers["HTTP_USER_AGENT"]
|
76
|
+
self["ip"] = @raw_request.remote_ip
|
77
|
+
hmac_key = Util.getHmacKey()
|
78
|
+
self["sid"] = Util.hmac(@raw_session_id, hmac_key)
|
79
|
+
if @user_id
|
80
|
+
self["uid"] = @user_id
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'tcell_agent/sensor_events/util/sanitizer_utilities'
|
4
|
+
require 'tcell_agent/sensor_events/sensor'
|
5
|
+
require 'tcell_agent/sensor_events/util/utils'
|
6
|
+
require 'etc'
|
7
|
+
|
8
|
+
module TCellAgent
|
9
|
+
module SensorEvents
|
10
|
+
class ServerAgentDetailsSensorEvent < TCellSensorEvent
|
11
|
+
def initialize
|
12
|
+
super("server_agent_details")
|
13
|
+
@flush = true
|
14
|
+
@ensure = true
|
15
|
+
login = Etc.getlogin
|
16
|
+
self["user"] = Etc.getlogin
|
17
|
+
info = Etc.getpwnam(login)
|
18
|
+
self["group"] = info.gid.to_s
|
19
|
+
end
|
20
|
+
end
|
21
|
+
class ServerAgentAppFrameworkEvent < TCellSensorEvent
|
22
|
+
def initialize(framework_name, framework_version)
|
23
|
+
super("server_agent_details")
|
24
|
+
@flush = true
|
25
|
+
@ensure = true
|
26
|
+
self["app_framework"] = framework_name
|
27
|
+
self["app_framework_version"] = framework_version
|
28
|
+
end
|
29
|
+
end
|
30
|
+
class ServerAgentPackagesSensorEvent < TCellSensorEvent
|
31
|
+
def initialize
|
32
|
+
super("server_agent_packages")
|
33
|
+
@flush = true
|
34
|
+
@ensure = true
|
35
|
+
packages = []
|
36
|
+
Gem.loaded_specs.values.map { |x|
|
37
|
+
package = {"n"=>x.name, "v"=>x.version.version}
|
38
|
+
packages.push(package)
|
39
|
+
}
|
40
|
+
self["packages"] = packages
|
41
|
+
end
|
42
|
+
end
|
43
|
+
class AppFramework < TCellSensorEvent
|
44
|
+
def initialize(name, version)
|
45
|
+
super("appserver_framework")
|
46
|
+
@flush = false
|
47
|
+
@ensure = true
|
48
|
+
self["n"] = name
|
49
|
+
self["v"] = version
|
50
|
+
end
|
51
|
+
end
|
52
|
+
class AppAuthFramework < TCellSensorEvent
|
53
|
+
def initialize(name, version)
|
54
|
+
super("appserver_auth_framework")
|
55
|
+
@flush = false
|
56
|
+
@ensure = true
|
57
|
+
self["n"] = name
|
58
|
+
self["v"] = version
|
59
|
+
end
|
60
|
+
end
|
61
|
+
class AppFrameworkSetting < TCellSensorEvent
|
62
|
+
def initialize(framework_name, setting, value)
|
63
|
+
super("appserver_framework_setting")
|
64
|
+
@flush = false
|
65
|
+
@ensure = true
|
66
|
+
self["framework"] = framework_name
|
67
|
+
self["s"] = setting
|
68
|
+
self["v"] = value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
class AppCookie < TCellSensorEvent
|
72
|
+
def initialize(name, value, secure, http_only, session)
|
73
|
+
super("appserver_framework_setting")
|
74
|
+
@flush = false
|
75
|
+
@ensure = true
|
76
|
+
self["n"] = name
|
77
|
+
self["v"] = value
|
78
|
+
self["http_only"] = http_only
|
79
|
+
self["secure"] = secure
|
80
|
+
self["session"] = session
|
81
|
+
end
|
82
|
+
end
|
83
|
+
class AppRoutesSensorEvent < TCellSensorEvent
|
84
|
+
def initialize(uri, method, route_id, params=nil, destination=nil)
|
85
|
+
super("appserver_routes")
|
86
|
+
@flush = false
|
87
|
+
@ensure = true
|
88
|
+
method = method.downcase
|
89
|
+
self["uri"] = uri
|
90
|
+
self["method"] = method
|
91
|
+
self["rid"] = route_id
|
92
|
+
if (params)
|
93
|
+
self["params"] = params
|
94
|
+
end
|
95
|
+
if (destination)
|
96
|
+
self["destination"] = destination
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# See the file "LICENSE" for the full license governing this code.
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'cgi'
|
5
|
+
require 'uri'
|
6
|
+
require 'openssl'
|
7
|
+
|
8
|
+
module TCellAgent
|
9
|
+
module SensorEvents
|
10
|
+
module Util
|
11
|
+
def self.wildcardMatch(target, wildcardPattern)
|
12
|
+
escaped = Regexp.escape(wildcardPattern).gsub('\*','.*?')
|
13
|
+
regex = Regexp.new "^#{escaped}$", Regexp::IGNORECASE
|
14
|
+
!!(target =~ regex)
|
15
|
+
end
|
16
|
+
def self.domainFromUrl(url)
|
17
|
+
uri = URI.parse(url)
|
18
|
+
uri.host
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# See the file "LICENSE" for the full license governing this code.
|
4
|
+
|
5
|
+
require 'logger'
|
6
|
+
require 'cgi'
|
7
|
+
require 'uri'
|
8
|
+
require 'openssl'
|
9
|
+
|
10
|
+
module TCellAgent
|
11
|
+
module SensorEvents
|
12
|
+
module Util
|
13
|
+
def self.getHmacKey
|
14
|
+
if (TCellAgent.configuration.hmac_key)
|
15
|
+
return TCellAgent.configuration.hmac_key
|
16
|
+
elsif (TCellAgent.configuration.app_id)
|
17
|
+
return TCellAgent.configuration.app_id
|
18
|
+
end
|
19
|
+
return "tcell_hmac_key"
|
20
|
+
end
|
21
|
+
def self.hmac(data, hmacKey)
|
22
|
+
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), hmacKey.to_s, data)
|
23
|
+
return hmac
|
24
|
+
end
|
25
|
+
def self.request_sanitized_json(request)
|
26
|
+
sanitized_headers = Hash.new
|
27
|
+
headers = request.headers.select {|k,v| k.start_with? 'HTTP_'}
|
28
|
+
.collect {|pair| [pair[0].sub(/^HTTP_/, ''), pair[1]]}
|
29
|
+
.sort
|
30
|
+
headers.each do |header_name, header_value|
|
31
|
+
lower_header_name = header_name.downcase
|
32
|
+
if lower_header_name == "cookie"
|
33
|
+
sanitized_headers[header_name] = [self.santize_request_cookie_string(header_value)]
|
34
|
+
elsif ["content_type", "content_length","user_agent","csp"].include?(lower_header_name)
|
35
|
+
sanitized_headers[header_name] = [header_value]
|
36
|
+
else
|
37
|
+
sanitized_headers[header_name] = []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
new_request = {"method"=>request.request_method,
|
41
|
+
"uri"=>self.sanitize_uri(request.fullpath),
|
42
|
+
"headers"=>sanitized_headers}
|
43
|
+
request_body = request.body.read
|
44
|
+
if request_body
|
45
|
+
new_request["post_data"] = sanitize_query_string(request_body)
|
46
|
+
end
|
47
|
+
new_request
|
48
|
+
end
|
49
|
+
def self.response_sanitized_json(response)
|
50
|
+
status, headers, body = *response
|
51
|
+
sanitized_headers = Hash.new
|
52
|
+
content_type = "unknown"
|
53
|
+
headers.each do |header_name, header_value|
|
54
|
+
lower_header_name = header_name.downcase
|
55
|
+
if lower_header_name == "set-cookie"
|
56
|
+
sanitized_headers[header_name] = [self.santize_response_cookie_string(header_value)]
|
57
|
+
else
|
58
|
+
if lower_header_name == "content-type"
|
59
|
+
content_type = header_value
|
60
|
+
end
|
61
|
+
if ["content-type", "content-length"].include?(lower_header_name)
|
62
|
+
sanitized_headers[header_name] = [header_value]
|
63
|
+
else
|
64
|
+
sanitized_headers[header_name] = []
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
new_response = {"status"=> status,
|
69
|
+
"headers"=>sanitized_headers}
|
70
|
+
new_response
|
71
|
+
end
|
72
|
+
def self.santize_request_cookie_string(request_cookie_string)
|
73
|
+
hmacKey = Util.getHmacKey()
|
74
|
+
sanitized_cookies = Hash.new
|
75
|
+
cookies = CGI::Cookie::parse(request_cookie_string)
|
76
|
+
cookies.each do |cookie_name, cookie_value|
|
77
|
+
if cookie_value.length != 1
|
78
|
+
next
|
79
|
+
end
|
80
|
+
sanitized_cookies[cookie_name] = Util.hmac(cookie_value[0], hmacKey)
|
81
|
+
end
|
82
|
+
sanitized_cookies.map{|k,v| "#{k}=#{v}"}.join(';')
|
83
|
+
end
|
84
|
+
def self.santize_response_cookie_string(response_cookie_string_value)
|
85
|
+
hmacKey = Util.getHmacKey()
|
86
|
+
cookie_parts = response_cookie_string_value.split('; ')
|
87
|
+
cookie_string = cookie_parts[0]
|
88
|
+
cookies = CGI::Cookie::parse(cookie_string)
|
89
|
+
if cookies.length != 1
|
90
|
+
return "[COOKIEMALFORMED]"
|
91
|
+
end
|
92
|
+
cookie_name = cookies.keys.first
|
93
|
+
cookie_values = cookies.values.first
|
94
|
+
if (cookie_values.length != 1)
|
95
|
+
return "[COOKIEHADTOOMANYVALUES]"
|
96
|
+
end
|
97
|
+
h = Util.hmac(cookie_values[0], hmacKey)
|
98
|
+
new_cookie_string = "#{cookie_name}=#{h}"
|
99
|
+
cookie_parts[0] = new_cookie_string
|
100
|
+
cookie_parts.map{|k,v| "#{k}=#{v}"}.join('; ')
|
101
|
+
end
|
102
|
+
def self.sanitize_query_string(query)
|
103
|
+
hmacKey = Util.getHmacKey()
|
104
|
+
params = CGI::parse(query)
|
105
|
+
params.each do |param_name, param_values|
|
106
|
+
if param_values == nil || param_values.length == 0
|
107
|
+
next
|
108
|
+
end
|
109
|
+
if (param_name.match(/password/i) ||
|
110
|
+
param_name.match(/passwd/i) ||
|
111
|
+
param_name.match(/token/i) ||
|
112
|
+
param_name.match(/sessionid/i))
|
113
|
+
params[param_name] = ["?"]
|
114
|
+
next
|
115
|
+
end
|
116
|
+
new_param_values = []
|
117
|
+
param_values.each do |param_value|
|
118
|
+
h = Util.hmac(param_value, hmacKey)
|
119
|
+
new_param_values.push << h
|
120
|
+
end
|
121
|
+
params[param_name] = new_param_values
|
122
|
+
end
|
123
|
+
params.map{|k,v| "#{k}=#{v.join(',')}"}.join('&')
|
124
|
+
end
|
125
|
+
def self.strip_values_query_string(query)
|
126
|
+
params = CGI::parse(query)
|
127
|
+
params.each do |param_name, param_values|
|
128
|
+
if param_values == nil || param_values.length == 0
|
129
|
+
next
|
130
|
+
end
|
131
|
+
params[param_name] = [""]
|
132
|
+
end
|
133
|
+
params.map{|k,v| "#{k}=#{v.join(',')}"}.join('&')
|
134
|
+
end
|
135
|
+
def self.sanitize_uri(uri_string)
|
136
|
+
uri = URI(uri_string)
|
137
|
+
query = uri.query
|
138
|
+
if (query)
|
139
|
+
uri.query = sanitize_query_string(query)
|
140
|
+
end
|
141
|
+
return uri.to_s
|
142
|
+
end
|
143
|
+
def self.strip_uri_values(uri_string)
|
144
|
+
uri = URI(uri_string)
|
145
|
+
query = uri.query
|
146
|
+
if (query)
|
147
|
+
uri.query = strip_values_query_string(query)
|
148
|
+
end
|
149
|
+
return uri.to_s
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|