tcell_agent 1.0.0 → 1.1.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.txt +7 -0
  3. data/bin/tcell_agent +6 -2
  4. data/lib/tcell_agent.rb +0 -3
  5. data/lib/tcell_agent/agent/event_processor.rb +1 -4
  6. data/lib/tcell_agent/agent/policy_manager.rb +5 -8
  7. data/lib/tcell_agent/agent/policy_types.rb +1 -7
  8. data/lib/tcell_agent/agent/static_agent.rb +2 -2
  9. data/lib/tcell_agent/api.rb +7 -9
  10. data/lib/tcell_agent/configuration.rb +42 -6
  11. data/lib/tcell_agent/policies/rust_policies.rb +33 -8
  12. data/lib/tcell_agent/rails/js_agent_insert.rb +17 -18
  13. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +18 -59
  14. data/lib/tcell_agent/rails/tcell_body_proxy.rb +10 -6
  15. data/lib/tcell_agent/rust/libtcellagent-0.19.5.dylib +0 -0
  16. data/lib/tcell_agent/rust/{libtcellagent-0.11.1.so → libtcellagent-0.19.5.so} +0 -0
  17. data/lib/tcell_agent/rust/tcellagent-0.19.5.dll +0 -0
  18. data/lib/tcell_agent/rust/whisperer.rb +165 -39
  19. data/lib/tcell_agent/sensor_events/patches.rb +2 -0
  20. data/lib/tcell_agent/sinatra.rb +17 -14
  21. data/lib/tcell_agent/version.rb +1 -1
  22. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +17 -0
  23. data/spec/lib/tcell_agent/api/api_spec.rb +10 -7
  24. data/spec/lib/tcell_agent/cmdi_spec.rb +91 -80
  25. data/spec/lib/tcell_agent/instrumentation_spec.rb +20 -0
  26. data/spec/lib/tcell_agent/patches_spec.rb +33 -15
  27. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +150 -99
  28. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +13 -1
  29. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +12 -0
  30. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +2 -39
  31. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +6 -2
  32. data/spec/lib/tcell_agent/rails_spec.rb +0 -31
  33. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +234 -120
  34. data/tcell_agent.gemspec +1 -1
  35. metadata +21 -40
  36. data/lib/tcell_agent/policies/clickjacking_policy.rb +0 -114
  37. data/lib/tcell_agent/policies/content_security_policy.rb +0 -166
  38. data/lib/tcell_agent/policies/secure_headers_policy.rb +0 -67
  39. data/lib/tcell_agent/rust/libtcellagent-0.11.1.dylib +0 -0
  40. data/lib/tcell_agent/rust/tcellagent-0.11.1.dll +0 -0
  41. data/spec/apps/rails-3.2/config/tcell_agent.config +0 -15
  42. data/spec/apps/rails-3.2/log/development.log +0 -0
  43. data/spec/apps/rails-3.2/log/test.log +0 -12
  44. data/spec/apps/rails-4.1/log/test.log +0 -0
  45. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +0 -71
  46. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +0 -130
  47. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +0 -67
  48. data/spec/lib/tcell_agent_spec.rb +0 -22
@@ -1,67 +0,0 @@
1
- # encoding: utf-8
2
- # See the file "LICENSE" for the full license governing this code.
3
- require 'tcell_agent/policies/policy'
4
-
5
-
6
- module TCellAgent
7
- module Policies
8
- class SecureHeadersPolicy < Policy
9
- class SecurityHeader
10
- @@approved_headers = [
11
- "strict-transport-security",
12
- "x-frame-options",
13
- "x-xss-protection",
14
- "x-content-type-options",
15
- "x-permitted-cross-domain-policies",
16
- "x-download-options"
17
- ]
18
- attr_accessor :name
19
- attr_accessor :value
20
- def initialize(name, value)
21
- if !(name && value)
22
- raise "Name and value were not set"
23
- end
24
- if !@@approved_headers.include?(name.downcase)
25
- raise "Name was not included in approved_headers"
26
- end
27
- if value != value.gsub(/[^\p{L}\w\d\-_\ :\/,;.'\*"%?@#=$]/,'')
28
- raise "Value is not valid"
29
- end
30
- self.name = name
31
- self.value = value
32
- end
33
- end
34
-
35
- attr_accessor :headers
36
- attr_accessor :policy_id
37
-
38
- def self.from_json(policy_json)
39
- if (!policy_json)
40
- return nil
41
- end
42
- security_headers_policy = SecureHeadersPolicy.new
43
- if policy_json.has_key?("policy_id")
44
- security_headers_policy.policy_id = policy_json["policy_id"]
45
- else
46
- raise "Policy ID missing"
47
- end
48
- security_headers = []
49
- if policy_json.has_key?("headers")
50
- headers = policy_json["headers"]
51
- headers.each do |header|
52
- if header.has_key?("name") && header.has_key?("value")
53
- begin
54
- security_header = SecurityHeader.new(header["name"], header["value"])
55
- security_headers.push(security_header)
56
- rescue StandardError => secure_header_exception
57
- TCellAgent.logger.debug("Could not load secure header:" + secure_header_exception.message)
58
- end
59
- end
60
- end
61
- end
62
- security_headers_policy.headers = security_headers
63
- return security_headers_policy
64
- end
65
- end
66
- end
67
- end
@@ -1,15 +0,0 @@
1
- {
2
- "version":1,
3
- "applications":
4
- [
5
- {
6
- "name":"<name>",
7
- "api_key":"<apikey>",
8
- "fetch_policies_from_tcell":false,
9
- "tcell_input_url":"https://localhost/",
10
- "preload_policy_filename":"config/tcell_preload.json",
11
- "logging_options":{"enabled":true, "level":"DEBUG"}
12
- }
13
- ]
14
- }
15
-
File without changes
@@ -1,12 +0,0 @@
1
- Connecting to database specified by DATABASE_URL
2
- Connecting to database specified by DATABASE_URL
3
- Connecting to database specified by DATABASE_URL
4
- Connecting to database specified by DATABASE_URL
5
- Connecting to database specified by DATABASE_URL
6
- Connecting to database specified by DATABASE_URL
7
- Connecting to database specified by DATABASE_URL
8
- Connecting to database specified by DATABASE_URL
9
- Connecting to database specified by DATABASE_URL
10
- Connecting to database specified by DATABASE_URL
11
- Connecting to database specified by DATABASE_URL
12
- Connecting to database specified by DATABASE_URL
File without changes
@@ -1,71 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TCellAgent
4
- module Policies
5
- describe ClickjackingPolicy do
6
- content_security_policy_json = {
7
- 'policy_id' => '00a1',
8
- 'headers' => [
9
- { 'name' => 'csp', 'value' => 'csp header value' }
10
- ]
11
- }
12
- csp_from_json = ClickjackingPolicy.from_json(content_security_policy_json)
13
- context 'initialized with 3 items' do
14
- it 'returns true' do
15
- expect(csp_from_json.policy_id).to eq('00a1')
16
- expect(csp_from_json.headers[0].type).to eq('csp')
17
- expect(csp_from_json.headers[0].value).to eq('csp header value')
18
- end
19
- end
20
- context 'headers match up appropriately' do
21
- it 'returns content-security-policy headers' do
22
- expect(ClickjackingPolicy.cspHeadersForType('csp')).to match_array(['Content-Security-Policy']) # ,"X-Content-Security-Policy","X-WebKit-CSP"])
23
- end
24
- end
25
- end
26
- describe ContentSecurityPolicy do
27
- content_security_policy_json = {
28
- 'policy_id' => '01a1',
29
- 'headers' => [
30
- { 'name' => 'csp-header-is-bad', 'value' => 'csp header value' }
31
- ]
32
- }
33
- csp_policy = ClickjackingPolicy.from_json(content_security_policy_json)
34
- context 'csp header example, invalid header' do
35
- it 'returns false' do
36
- expect(csp_policy.headers.length).to eq(0)
37
- end
38
- end
39
- end
40
- describe ClickjackingPolicy do
41
- content_security_policy_json = {
42
- 'policy_id' => '01a1',
43
- 'headers' => [
44
- { 'name' => 'csp', 'value' => 'value123\\nabc' }
45
- ]
46
- }
47
- csp_policy = ClickjackingPolicy.from_json(content_security_policy_json)
48
- context 'secure header, value is bad' do
49
- it 'returns false' do
50
- expect(csp_policy.headers.length).to eq(0)
51
- end
52
- end
53
- end
54
- describe ClickjackingPolicy do
55
- content_security_policy_json = {
56
- 'policy_id' => '01a1',
57
- 'headers' => [
58
- { 'name' => 'csp', 'value' => 'value normal', 'report-uri' => 'https://example.com/abcdde' }
59
- ]
60
- }
61
- csp_policy = ClickjackingPolicy.from_json(content_security_policy_json)
62
- context 'secure header, report-uri seperate' do
63
- it 'returns false' do
64
- expect(csp_policy.headers.length).to eq(1)
65
- expect(csp_policy.headers[0].value).to eq('value normal; report-uri https://example.com/abcdde')
66
- expect(csp_policy.headers[0].value('1', '2', '3')).to eq('value normal; report-uri https://example.com/abcdde?tid=1&sid=2&uid=3')
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,130 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TCellAgent
4
- module Policies
5
- describe ContentSecurityPolicy do
6
- context 'test empty agent' do
7
- it 'enabled is false' do
8
- policy_json_empty = {
9
- 'policy_id' => '01a1',
10
- 'data' => {
11
- 'options' => {
12
-
13
- }
14
- }
15
- }
16
-
17
- empty_policy = ContentSecurityPolicy.from_json(policy_json_empty)
18
-
19
- expect(empty_policy.policy_id).to eq('01a1')
20
- expect(empty_policy.js_agent_api_key).to eq(nil)
21
- end
22
- end
23
-
24
- context 'tests xss is true and enabled true' do
25
- it 'returns true' do
26
- policy_json_one = {
27
- 'policy_id' => '01a1',
28
- 'data' => {
29
- 'options' => {
30
- 'js_agent_api_key' => '000-000-1'
31
- }
32
- }
33
- }
34
-
35
- from_json = ContentSecurityPolicy.from_json(policy_json_one)
36
-
37
- expect(from_json.policy_id).to eq('01a1')
38
- expect(from_json.js_agent_api_key).to eq('000-000-1')
39
- end
40
- end
41
-
42
- context 'initialized with 3 items' do
43
- it 'returns true' do
44
- content_security_policy_json = {
45
- 'policy_id' => '00a1',
46
- 'headers' => [
47
- { 'name' => 'csp', 'value' => 'csp header value' }
48
- ]
49
- }
50
-
51
- csp_from_json = ContentSecurityPolicy.from_json(content_security_policy_json)
52
-
53
- expect(csp_from_json.policy_id).to eq('00a1')
54
- expect(csp_from_json.headers[0].type).to eq('csp')
55
- expect(csp_from_json.headers[0].value).to eq('csp header value')
56
- end
57
- end
58
-
59
- context 'headers match up appropriately' do
60
- it 'returns content-security-policy headers' do
61
- expect(ContentSecurityPolicy.cspHeadersForType('csp')).to match_array(['Content-Security-Policy'])
62
- end
63
- end
64
-
65
- context 'csp header example, invalid header' do
66
- it 'returns false' do
67
- content_security_policy_json = {
68
- 'policy_id' => '01a1',
69
- 'headers' => [
70
- { 'name' => 'csp-header-is-bad', 'value' => 'csp header value' }
71
- ]
72
- }
73
-
74
- csp_policy = ContentSecurityPolicy.from_json(content_security_policy_json)
75
-
76
- expect(csp_policy.headers.length).to eq(0)
77
- end
78
- end
79
-
80
- context 'secure header, value is bad' do
81
- it 'returns false' do
82
- content_security_policy_json = {
83
- 'policy_id' => '01a1',
84
- 'headers' => [
85
- { 'name' => 'csp', 'value' => 'value123\\nabc' }
86
- ]
87
- }
88
- csp_policy = ContentSecurityPolicy.from_json(content_security_policy_json)
89
- expect(csp_policy.headers.length).to eq(0)
90
- end
91
- end
92
-
93
- context 'secure header, report-uri seperate' do
94
- it 'returns false' do
95
- content_security_policy_json = {
96
- 'policy_id' => '01a1',
97
- 'headers' => [
98
- { 'name' => 'csp', 'value' => 'value normal', 'report-uri' => 'https://example.com/abcdde' }
99
- ]
100
- }
101
-
102
- csp_policy = ContentSecurityPolicy.from_json(content_security_policy_json)
103
-
104
- expect(csp_policy.headers.length).to eq(1)
105
- expect(csp_policy.headers[0].value).to eq('value normal; report-uri https://example.com/abcdde?c=-815891691')
106
- expect(csp_policy.headers[0].value('1', '2', '3')).to eq('value normal; report-uri https://example.com/abcdde?tid=1&sid=3&rid=2&c=1777384531')
107
- end
108
- end
109
-
110
- context 'default js_agent_url' do
111
- it 'should have the configuration set to the default js_agent_url value' do
112
- expect(TCellAgent.configuration.js_agent_url).to eq('https://jsagent.tcell.io/tcellagent.min.js')
113
-
114
- content_security_policy_json = {
115
- 'policy_id' => '01a1',
116
- 'headers' => [
117
- { 'name' => 'csp', 'value' => "script-src 'unsafe-inline' 'unsafe-eval' 'self' https://api.tcell.io/" }
118
- ]
119
- }
120
-
121
- csp_policy = ContentSecurityPolicy.from_json(content_security_policy_json)
122
-
123
- expect(csp_policy.headers.length).to eq(1)
124
- expect(csp_policy.headers[0].value).to eq("script-src 'unsafe-inline' 'unsafe-eval' 'self' https://api.tcell.io/")
125
- expect(TCellAgent.configuration.js_agent_url).to eq('https://jsagent.tcell.io/tcellagent.min.js')
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TCellAgent
4
- module Policies
5
- describe SecureHeadersPolicy do
6
- secure_headers_policy_json = {
7
- 'policy_id' => '01a1',
8
- 'headers' => [
9
- { 'name' => 'x-permitted-cross-domain-policies', 'value' => 'value123' }
10
- ]
11
- }
12
- secure_headers_policy = SecureHeadersPolicy.from_json(secure_headers_policy_json)
13
- context 'secure header example' do
14
- it 'returns true' do
15
- expect(secure_headers_policy.headers[0].name).to eq('x-permitted-cross-domain-policies')
16
- expect(secure_headers_policy.headers[0].value).to eq('value123')
17
- end
18
- end
19
- end
20
- describe SecureHeadersPolicy do
21
- secure_headers_policy_json = {
22
- 'policy_id' => '01a1',
23
- 'headers' => [
24
- { 'name' => 'x-frame-options', 'value' => 'DENY' },
25
- { 'name' => 'x-xss-protection', 'value' => '1; mode=block' }
26
- ]
27
- }
28
- secure_headers_policy = SecureHeadersPolicy.from_json(secure_headers_policy_json)
29
- context 'secure headers (2) example' do
30
- it 'returns true' do
31
- expect(secure_headers_policy.headers[0].name).to eq('x-frame-options')
32
- expect(secure_headers_policy.headers[0].value).to eq('DENY')
33
- expect(secure_headers_policy.headers[1].name).to eq('x-xss-protection')
34
- expect(secure_headers_policy.headers[1].value).to eq('1; mode=block')
35
- end
36
- end
37
- end
38
- describe SecureHeadersPolicy do
39
- secure_headers_policy_json = {
40
- 'policy_id' => '01a1',
41
- 'headers' => [
42
- { 'name' => 'bad-header', 'value' => 'value123' }
43
- ]
44
- }
45
- secure_headers_policy = SecureHeadersPolicy.from_json(secure_headers_policy_json)
46
- context 'secure header example, invalid header' do
47
- it 'returns false' do
48
- expect(secure_headers_policy.headers.length).to eq(0)
49
- end
50
- end
51
- end
52
- describe SecureHeadersPolicy do
53
- secure_headers_policy_json = {
54
- 'policy_id' => '01a1',
55
- 'headers' => [
56
- { 'name' => 'x-permitted-cross-domain-policies', 'value' => 'value123\\nabc' }
57
- ]
58
- }
59
- secure_headers_policy = SecureHeadersPolicy.from_json(secure_headers_policy_json)
60
- context 'secure header, value is bad' do
61
- it 'returns false' do
62
- expect(secure_headers_policy.headers.length).to eq(0)
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TCellAgent
4
- describe Agent do
5
- context 'Agent Read File' do
6
- agent_worker = Agent.new(0)
7
- it 'Reads in a policy file' do
8
- policy_file_json = {
9
- 'csp-headers' => {
10
- 'policy_id' => '00a1',
11
- 'headers' => [
12
- { 'name' => 'csp', 'value' => 'csp loaded header' }
13
- ]
14
- }
15
- }
16
- agent_worker.processPolicyJson(policy_file_json)
17
- expect(agent_worker.policies[TCellAgent::PolicyTypes::CSP].headers[0].type).to eq('csp')
18
- expect(agent_worker.policies[TCellAgent::PolicyTypes::CSP].headers[0].value).to eq('csp loaded header')
19
- end
20
- end
21
- end
22
- end