tcell_agent 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -22
  3. data/bin/tcell_agent +127 -132
  4. data/lib/tcell_agent/agent/event_processor.rb +23 -22
  5. data/lib/tcell_agent/agent/fork_pipe_manager.rb +7 -7
  6. data/lib/tcell_agent/agent/policy_manager.rb +20 -15
  7. data/lib/tcell_agent/agent/policy_types.rb +5 -11
  8. data/lib/tcell_agent/agent/static_agent.rb +5 -1
  9. data/lib/tcell_agent/agent.rb +6 -4
  10. data/lib/tcell_agent/api.rb +7 -9
  11. data/lib/tcell_agent/appsensor/meta_data.rb +11 -4
  12. data/lib/tcell_agent/authlogic.rb +3 -3
  13. data/lib/tcell_agent/cmdi.rb +6 -4
  14. data/lib/tcell_agent/config/unknown_options.rb +3 -1
  15. data/lib/tcell_agent/configuration.rb +47 -49
  16. data/lib/tcell_agent/devise.rb +2 -2
  17. data/lib/tcell_agent/hooks/login_fraud.rb +58 -29
  18. data/lib/tcell_agent/instrumentation.rb +11 -10
  19. data/lib/tcell_agent/logger.rb +2 -2
  20. data/lib/tcell_agent/patches/meta_data.rb +9 -13
  21. data/lib/tcell_agent/patches.rb +7 -10
  22. data/lib/tcell_agent/policies/clickjacking_policy.rb +4 -5
  23. data/lib/tcell_agent/policies/content_security_policy.rb +6 -12
  24. data/lib/tcell_agent/policies/dataloss_policy.rb +2 -2
  25. data/lib/tcell_agent/policies/http_redirect_policy.rb +2 -2
  26. data/lib/tcell_agent/policies/policy.rb +0 -2
  27. data/lib/tcell_agent/policies/rust_policies.rb +90 -0
  28. data/lib/tcell_agent/policies/secure_headers_policy.rb +2 -2
  29. data/lib/tcell_agent/rails/auth/authlogic.rb +42 -24
  30. data/lib/tcell_agent/rails/auth/devise.rb +44 -23
  31. data/lib/tcell_agent/rails/auth/doorkeeper.rb +33 -15
  32. data/lib/tcell_agent/rails/better_ip.rb +1 -1
  33. data/lib/tcell_agent/rails/csrf_exception.rb +2 -2
  34. data/lib/tcell_agent/rails/dlp/process_request.rb +1 -1
  35. data/lib/tcell_agent/rails/dlp.rb +6 -6
  36. data/lib/tcell_agent/rails/dlp_handler.rb +1 -1
  37. data/lib/tcell_agent/rails/js_agent_insert.rb +1 -1
  38. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +1 -1
  39. data/lib/tcell_agent/rails/middleware/context_middleware.rb +3 -2
  40. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +10 -9
  41. data/lib/tcell_agent/rails/routes/grape.rb +6 -6
  42. data/lib/tcell_agent/rails/routes.rb +8 -11
  43. data/lib/tcell_agent/rust/libtcellagent-0.11.1.dylib +0 -0
  44. data/lib/tcell_agent/rust/{libtcellagent-0.6.1.so → libtcellagent-0.11.1.so} +0 -0
  45. data/lib/tcell_agent/rust/models.rb +16 -0
  46. data/lib/tcell_agent/rust/tcellagent-0.11.1.dll +0 -0
  47. data/lib/tcell_agent/rust/whisperer.rb +119 -48
  48. data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +17 -20
  49. data/lib/tcell_agent/sensor_events/command_injection.rb +50 -5
  50. data/lib/tcell_agent/sensor_events/login_fraud.rb +34 -18
  51. data/lib/tcell_agent/sensor_events/patches.rb +21 -0
  52. data/lib/tcell_agent/sensor_events/server_agent.rb +3 -3
  53. data/lib/tcell_agent/sensor_events/util/utils.rb +4 -3
  54. data/lib/tcell_agent/servers/puma.rb +2 -2
  55. data/lib/tcell_agent/servers/unicorn.rb +1 -1
  56. data/lib/tcell_agent/utils/passwords.rb +28 -0
  57. data/lib/tcell_agent/version.rb +1 -1
  58. data/lib/tcell_agent.rb +1 -5
  59. data/spec/apps/rails-3.2/config/tcell_agent.config +15 -0
  60. data/spec/apps/rails-3.2/log/development.log +0 -0
  61. data/spec/apps/rails-3.2/log/test.log +12 -0
  62. data/spec/apps/rails-4.1/log/test.log +0 -0
  63. data/spec/lib/tcell_agent/agent/fork_pipe_manager_spec.rb +46 -45
  64. data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +276 -164
  65. data/spec/lib/tcell_agent/agent/static_agent_spec.rb +44 -47
  66. data/spec/lib/tcell_agent/api/api_spec.rb +16 -16
  67. data/spec/lib/tcell_agent/appsensor/injections_reporter_spec.rb +131 -116
  68. data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +55 -51
  69. data/spec/lib/tcell_agent/cmdi_spec.rb +413 -436
  70. data/spec/lib/tcell_agent/config/unknown_options_spec.rb +145 -128
  71. data/spec/lib/tcell_agent/configuration_spec.rb +165 -169
  72. data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +144 -153
  73. data/spec/lib/tcell_agent/instrumentation_spec.rb +84 -85
  74. data/spec/lib/tcell_agent/patches_spec.rb +70 -111
  75. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +313 -244
  76. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +28 -28
  77. data/spec/lib/tcell_agent/policies/command_injection_policy_spec.rb +643 -513
  78. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +55 -102
  79. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +111 -134
  80. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +141 -146
  81. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +8 -8
  82. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +15 -17
  83. data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +231 -559
  84. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +27 -27
  85. data/spec/lib/tcell_agent/rails/better_ip_spec.rb +30 -34
  86. data/spec/lib/tcell_agent/rails/logger_spec.rb +50 -49
  87. data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +182 -199
  88. data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +110 -84
  89. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +107 -85
  90. data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +68 -40
  91. data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +81 -67
  92. data/spec/lib/tcell_agent/rails/responses_spec.rb +33 -37
  93. data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +116 -121
  94. data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +25 -28
  95. data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +87 -85
  96. data/spec/lib/tcell_agent/rails_spec.rb +1 -6
  97. data/spec/lib/tcell_agent/rust/models_spec.rb +112 -0
  98. data/spec/lib/tcell_agent/rust/whisperer_spec.rb +502 -179
  99. data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +44 -33
  100. data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +4 -4
  101. data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +183 -169
  102. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +25 -25
  103. data/spec/lib/tcell_agent/utils/bounded_queue_spec.rb +17 -20
  104. data/spec/lib/tcell_agent/utils/params_spec.rb +28 -28
  105. data/spec/lib/tcell_agent/utils/passwords_spec.rb +143 -0
  106. data/spec/lib/tcell_agent/utils/strings_spec.rb +35 -35
  107. data/spec/lib/tcell_agent_spec.rb +8 -8
  108. data/spec/spec_helper.rb +4 -4
  109. data/spec/support/middleware_helper.rb +10 -10
  110. data/spec/support/static_agent_overrides.rb +16 -12
  111. data/tcell_agent.gemspec +17 -33
  112. metadata +43 -198
  113. data/LICENSE_libinjection +0 -32
  114. data/Readme.txt +0 -7
  115. data/ext/libinjection/extconf.rb +0 -3
  116. data/ext/libinjection/libinjection.h +0 -65
  117. data/ext/libinjection/libinjection_html5.c +0 -847
  118. data/ext/libinjection/libinjection_html5.h +0 -54
  119. data/ext/libinjection/libinjection_sqli.c +0 -2317
  120. data/ext/libinjection/libinjection_sqli.h +0 -295
  121. data/ext/libinjection/libinjection_sqli_data.h +0 -9004
  122. data/ext/libinjection/libinjection_wrap.c +0 -3525
  123. data/ext/libinjection/libinjection_xss.c +0 -531
  124. data/ext/libinjection/libinjection_xss.h +0 -21
  125. data/lib/tcell_agent/appsensor/injections_matcher.rb +0 -155
  126. data/lib/tcell_agent/appsensor/rules/appsensor_rule_manager.rb +0 -49
  127. data/lib/tcell_agent/appsensor/rules/appsensor_rule_set.rb +0 -67
  128. data/lib/tcell_agent/appsensor/rules/baserules.json +0 -467
  129. data/lib/tcell_agent/patches/block_rule.rb +0 -93
  130. data/lib/tcell_agent/patches/sensors_matcher.rb +0 -31
  131. data/lib/tcell_agent/policies/appsensor/cmdi_sensor.rb +0 -23
  132. data/lib/tcell_agent/policies/appsensor/fpt_sensor.rb +0 -23
  133. data/lib/tcell_agent/policies/appsensor/injection_sensor.rb +0 -117
  134. data/lib/tcell_agent/policies/appsensor/nullbyte_sensor.rb +0 -26
  135. data/lib/tcell_agent/policies/appsensor/retr_sensor.rb +0 -22
  136. data/lib/tcell_agent/policies/appsensor/sqli_sensor.rb +0 -34
  137. data/lib/tcell_agent/policies/appsensor/xss_sensor.rb +0 -34
  138. data/lib/tcell_agent/policies/appsensor_policy.rb +0 -49
  139. data/lib/tcell_agent/policies/command_injection_policy.rb +0 -196
  140. data/lib/tcell_agent/policies/honeytokens_policy.rb +0 -69
  141. data/lib/tcell_agent/policies/patches_policy.rb +0 -84
  142. data/lib/tcell_agent/rust/libtcellagent-0.6.1.dylib +0 -0
  143. data/lib/tcell_agent/rust/tcellagent-0.6.1.dll +0 -0
  144. data/spec/apps/rails-3.2/Gemfile +0 -25
  145. data/spec/apps/rails-3.2/Gemfile.lock +0 -126
  146. data/spec/apps/rails-3.2/Rakefile +0 -7
  147. data/spec/apps/rails-3.2/app/assets/images/rails.png +0 -0
  148. data/spec/apps/rails-3.2/app/assets/javascripts/application.js +0 -15
  149. data/spec/apps/rails-3.2/app/assets/stylesheets/application.css +0 -13
  150. data/spec/apps/rails-3.2/app/controllers/application_controller.rb +0 -3
  151. data/spec/apps/rails-3.2/app/controllers/t_cell_app_controller.rb +0 -5
  152. data/spec/apps/rails-3.2/app/helpers/application_helper.rb +0 -2
  153. data/spec/apps/rails-3.2/app/views/layouts/application.html.erb +0 -14
  154. data/spec/apps/rails-3.2/app/views/t_cell_app/index.html.erb +0 -1
  155. data/spec/apps/rails-3.2/config/application.rb +0 -63
  156. data/spec/apps/rails-3.2/config/boot.rb +0 -6
  157. data/spec/apps/rails-3.2/config/environment.rb +0 -5
  158. data/spec/apps/rails-3.2/config/environments/test.rb +0 -37
  159. data/spec/apps/rails-3.2/config/routes.rb +0 -11
  160. data/spec/apps/rails-3.2/config.ru +0 -4
  161. data/spec/apps/rails-4.1/Gemfile +0 -7
  162. data/spec/apps/rails-4.1/Gemfile.lock +0 -114
  163. data/spec/apps/rails-4.1/Rakefile +0 -6
  164. data/spec/apps/rails-4.1/app/assets/javascripts/application.js +0 -16
  165. data/spec/apps/rails-4.1/app/assets/stylesheets/application.css +0 -15
  166. data/spec/apps/rails-4.1/app/controllers/application_controller.rb +0 -5
  167. data/spec/apps/rails-4.1/app/controllers/t_cell_app_controller.rb +0 -5
  168. data/spec/apps/rails-4.1/app/helpers/application_helper.rb +0 -2
  169. data/spec/apps/rails-4.1/app/views/layouts/application.html.erb +0 -14
  170. data/spec/apps/rails-4.1/app/views/t_cell_app/index.html.erb +0 -1
  171. data/spec/apps/rails-4.1/config/application.rb +0 -24
  172. data/spec/apps/rails-4.1/config/boot.rb +0 -4
  173. data/spec/apps/rails-4.1/config/environment.rb +0 -5
  174. data/spec/apps/rails-4.1/config/environments/test.rb +0 -41
  175. data/spec/apps/rails-4.1/config/initializers/assets.rb +0 -8
  176. data/spec/apps/rails-4.1/config/initializers/backtrace_silencers.rb +0 -7
  177. data/spec/apps/rails-4.1/config/initializers/cookies_serializer.rb +0 -3
  178. data/spec/apps/rails-4.1/config/initializers/filter_parameter_logging.rb +0 -4
  179. data/spec/apps/rails-4.1/config/initializers/inflections.rb +0 -16
  180. data/spec/apps/rails-4.1/config/initializers/mime_types.rb +0 -4
  181. data/spec/apps/rails-4.1/config/initializers/session_store.rb +0 -3
  182. data/spec/apps/rails-4.1/config/initializers/wrap_parameters.rb +0 -14
  183. data/spec/apps/rails-4.1/config/locales/en.yml +0 -23
  184. data/spec/apps/rails-4.1/config/routes.rb +0 -12
  185. data/spec/apps/rails-4.1/config/secrets.yml +0 -22
  186. data/spec/apps/rails-4.1/config.ru +0 -4
  187. data/spec/controllers/application_controller.rb +0 -12
  188. data/spec/lib/tcell_agent/appsensor/injections_matcher_spec.rb +0 -522
  189. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_manager_spec.rb +0 -23
  190. data/spec/lib/tcell_agent/appsensor/rules/appsensor_rule_set_spec.rb +0 -159
  191. data/spec/lib/tcell_agent/patches/block_rule_spec.rb +0 -458
  192. data/spec/lib/tcell_agent/patches/sensors_matcher_spec.rb +0 -35
  193. data/spec/lib/tcell_agent/policies/appsensor/cmdi_sensor_spec.rb +0 -139
  194. data/spec/lib/tcell_agent/policies/appsensor/fpt_sensor_spec.rb +0 -139
  195. data/spec/lib/tcell_agent/policies/appsensor/nullbyte_sensor_spec.rb +0 -167
  196. data/spec/lib/tcell_agent/policies/appsensor/retr_sensor_spec.rb +0 -139
  197. data/spec/lib/tcell_agent/policies/appsensor/sqli_sensor_spec.rb +0 -246
  198. data/spec/lib/tcell_agent/policies/appsensor/xss_sensor_spec.rb +0 -882
  199. data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +0 -22
@@ -1,531 +0,0 @@
1
-
2
- #include "libinjection.h"
3
- #include "libinjection_xss.h"
4
- #include "libinjection_html5.h"
5
-
6
- #include <assert.h>
7
- #include <stdio.h>
8
-
9
- typedef enum attribute {
10
- TYPE_NONE
11
- , TYPE_BLACK /* ban always */
12
- , TYPE_ATTR_URL /* attribute value takes a URL-like object */
13
- , TYPE_STYLE
14
- , TYPE_ATTR_INDIRECT /* attribute *name* is given in *value* */
15
- } attribute_t;
16
-
17
-
18
- static attribute_t is_black_attr(const char* s, size_t len);
19
- static int is_black_tag(const char* s, size_t len);
20
- static int is_black_url(const char* s, size_t len);
21
- static int cstrcasecmp_with_null(const char *a, const char *b, size_t n);
22
- static int html_decode_char_at(const char* src, size_t len, size_t* consumed);
23
- static int htmlencode_startswith(const char* prefix, const char *src, size_t n);
24
-
25
-
26
- typedef struct stringtype {
27
- const char* name;
28
- attribute_t atype;
29
- } stringtype_t;
30
-
31
-
32
- static const int gsHexDecodeMap[256] = {
33
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
34
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
35
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
36
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
37
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256,
38
- 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256,
39
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
40
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
41
- 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256,
42
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
43
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
44
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
45
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
46
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
47
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
48
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
49
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
50
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
51
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
52
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
53
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
54
- 256, 256, 256, 256
55
- };
56
-
57
- static int html_decode_char_at(const char* src, size_t len, size_t* consumed)
58
- {
59
- int val = 0;
60
- size_t i;
61
- int ch;
62
-
63
- if (len == 0 || src == NULL) {
64
- *consumed = 0;
65
- return -1;
66
- }
67
-
68
- *consumed = 1;
69
- if (*src != '&' || len < 2) {
70
- return (unsigned char)(*src);
71
- }
72
-
73
-
74
- if (*(src+1) != '#') {
75
- /* normally this would be for named entities
76
- * but for this case we don't actually care
77
- */
78
- return '&';
79
- }
80
-
81
- if (*(src+2) == 'x' || *(src+2) == 'X') {
82
- ch = (unsigned char) (*(src+3));
83
- ch = gsHexDecodeMap[ch];
84
- if (ch == 256) {
85
- /* degenerate case '&#[?]' */
86
- return '&';
87
- }
88
- val = ch;
89
- i = 4;
90
- while (i < len) {
91
- ch = (unsigned char) src[i];
92
- if (ch == ';') {
93
- *consumed = i + 1;
94
- return val;
95
- }
96
- ch = gsHexDecodeMap[ch];
97
- if (ch == 256) {
98
- *consumed = i;
99
- return val;
100
- }
101
- val = (val * 16) + ch;
102
- if (val > 0x1000FF) {
103
- return '&';
104
- }
105
- ++i;
106
- }
107
- *consumed = i;
108
- return val;
109
- } else {
110
- i = 2;
111
- ch = (unsigned char) src[i];
112
- if (ch < '0' || ch > '9') {
113
- return '&';
114
- }
115
- val = ch - '0';
116
- i += 1;
117
- while (i < len) {
118
- ch = (unsigned char) src[i];
119
- if (ch == ';') {
120
- *consumed = i + 1;
121
- return val;
122
- }
123
- if (ch < '0' || ch > '9') {
124
- *consumed = i;
125
- return val;
126
- }
127
- val = (val * 10) + (ch - '0');
128
- if (val > 0x1000FF) {
129
- return '&';
130
- }
131
- ++i;
132
- }
133
- *consumed = i;
134
- return val;
135
- }
136
- }
137
-
138
-
139
- /*
140
- * view-source:
141
- * data:
142
- * javascript:
143
- */
144
- static stringtype_t BLACKATTR[] = {
145
- { "ACTION", TYPE_ATTR_URL } /* form */
146
- , { "ATTRIBUTENAME", TYPE_ATTR_INDIRECT } /* SVG allow indirection of attribute names */
147
- , { "BY", TYPE_ATTR_URL } /* SVG */
148
- , { "BACKGROUND", TYPE_ATTR_URL } /* IE6, O11 */
149
- , { "DATAFORMATAS", TYPE_BLACK } /* IE */
150
- , { "DATASRC", TYPE_BLACK } /* IE */
151
- , { "DYNSRC", TYPE_ATTR_URL } /* Obsolete img attribute */
152
- , { "FILTER", TYPE_STYLE } /* Opera, SVG inline style */
153
- , { "FORMACTION", TYPE_ATTR_URL } /* HTML 5 */
154
- , { "FOLDER", TYPE_ATTR_URL } /* Only on A tags, IE-only */
155
- , { "FROM", TYPE_ATTR_URL } /* SVG */
156
- , { "HANDLER", TYPE_ATTR_URL } /* SVG Tiny, Opera */
157
- , { "HREF", TYPE_ATTR_URL }
158
- , { "LOWSRC", TYPE_ATTR_URL } /* Obsolete img attribute */
159
- , { "POSTER", TYPE_ATTR_URL } /* Opera 10,11 */
160
- , { "SRC", TYPE_ATTR_URL }
161
- , { "STYLE", TYPE_STYLE }
162
- , { "TO", TYPE_ATTR_URL } /* SVG */
163
- , { "VALUES", TYPE_ATTR_URL } /* SVG */
164
- , { "XLINK:HREF", TYPE_ATTR_URL }
165
- , { NULL, TYPE_NONE }
166
- };
167
-
168
- /* xmlns */
169
- /* `xml-stylesheet` > <eval>, <if expr=> */
170
-
171
- /*
172
- static const char* BLACKATTR[] = {
173
- "ATTRIBUTENAME",
174
- "BACKGROUND",
175
- "DATAFORMATAS",
176
- "HREF",
177
- "SCROLL",
178
- "SRC",
179
- "STYLE",
180
- "SRCDOC",
181
- NULL
182
- };
183
- */
184
-
185
- static const char* BLACKTAG[] = {
186
- "APPLET"
187
- /* , "AUDIO" */
188
- , "BASE"
189
- , "COMMENT" /* IE http://html5sec.org/#38 */
190
- , "EMBED"
191
- /* , "FORM" */
192
- , "FRAME"
193
- , "FRAMESET"
194
- , "HANDLER" /* Opera SVG, effectively a script tag */
195
- , "IFRAME"
196
- , "IMPORT"
197
- , "ISINDEX"
198
- , "LINK"
199
- , "LISTENER"
200
- /* , "MARQUEE" */
201
- , "META"
202
- , "NOSCRIPT"
203
- , "OBJECT"
204
- , "SCRIPT"
205
- , "STYLE"
206
- /* , "VIDEO" */
207
- , "VMLFRAME"
208
- , "XML"
209
- , "XSS"
210
- , NULL
211
- };
212
-
213
-
214
- static int cstrcasecmp_with_null(const char *a, const char *b, size_t n)
215
- {
216
- char ca;
217
- char cb;
218
- /* printf("Comparing to %s %.*s\n", a, (int)n, b); */
219
- while (n-- > 0) {
220
- cb = *b++;
221
- if (cb == '\0') continue;
222
-
223
- ca = *a++;
224
-
225
- if (cb >= 'a' && cb <= 'z') {
226
- cb -= 0x20;
227
- }
228
- /* printf("Comparing %c vs %c with %d left\n", ca, cb, (int)n); */
229
- if (ca != cb) {
230
- return 1;
231
- }
232
- }
233
-
234
- if (*a == 0) {
235
- /* printf(" MATCH \n"); */
236
- return 0;
237
- } else {
238
- return 1;
239
- }
240
- }
241
-
242
- /*
243
- * Does an HTML encoded binary string (const char*, length) start with
244
- * a all uppercase c-string (null terminated), case insensitive!
245
- *
246
- * also ignore any embedded nulls in the HTML string!
247
- *
248
- * return 1 if match / starts with
249
- * return 0 if not
250
- */
251
- static int htmlencode_startswith(const char *a, const char *b, size_t n)
252
- {
253
- size_t consumed;
254
- int cb;
255
- int first = 1;
256
- /* printf("Comparing %s with %.*s\n", a,(int)n,b); */
257
- while (n > 0) {
258
- if (*a == 0) {
259
- /* printf("Match EOL!\n"); */
260
- return 1;
261
- }
262
- cb = html_decode_char_at(b, n, &consumed);
263
- b += consumed;
264
- n -= consumed;
265
-
266
- if (first && cb <= 32) {
267
- /* ignore all leading whitespace and control characters */
268
- continue;
269
- }
270
- first = 0;
271
-
272
- if (cb == 0) {
273
- /* always ignore null characters in user input */
274
- continue;
275
- }
276
-
277
- if (cb == 10) {
278
- /* always ignore vertical tab characters in user input */
279
- /* who allows this?? */
280
- continue;
281
- }
282
-
283
- if (cb >= 'a' && cb <= 'z') {
284
- /* upcase */
285
- cb -= 0x20;
286
- }
287
-
288
- if (*a != (char) cb) {
289
- /* printf(" %c != %c\n", *a, cb); */
290
- /* mismatch */
291
- return 0;
292
- }
293
- a++;
294
- }
295
-
296
- return (*a == 0) ? 1 : 0;
297
- }
298
-
299
- static int is_black_tag(const char* s, size_t len)
300
- {
301
- const char** black;
302
-
303
- if (len < 3) {
304
- return 0;
305
- }
306
-
307
- black = BLACKTAG;
308
- while (*black != NULL) {
309
- if (cstrcasecmp_with_null(*black, s, len) == 0) {
310
- /* printf("Got black tag %s\n", *black); */
311
- return 1;
312
- }
313
- black += 1;
314
- }
315
-
316
- /* anything SVG related */
317
- if ((s[0] == 's' || s[0] == 'S') &&
318
- (s[1] == 'v' || s[1] == 'V') &&
319
- (s[2] == 'g' || s[2] == 'G')) {
320
- /* printf("Got SVG tag \n"); */
321
- return 1;
322
- }
323
-
324
- /* Anything XSL(t) related */
325
- if ((s[0] == 'x' || s[0] == 'X') &&
326
- (s[1] == 's' || s[1] == 'S') &&
327
- (s[2] == 'l' || s[2] == 'L')) {
328
- /* printf("Got XSL tag\n"); */
329
- return 1;
330
- }
331
-
332
- return 0;
333
- }
334
-
335
- static attribute_t is_black_attr(const char* s, size_t len)
336
- {
337
- stringtype_t* black;
338
-
339
- if (len < 2) {
340
- return TYPE_NONE;
341
- }
342
-
343
- /* JavaScript on.* */
344
- if ((s[0] == 'o' || s[0] == 'O') && (s[1] == 'n' || s[1] == 'N')) {
345
- /* printf("Got JavaScript on- attribute name\n"); */
346
- return TYPE_BLACK;
347
- }
348
-
349
-
350
- if (len >= 5) {
351
- /* XMLNS can be used to create arbitrary tags */
352
- if (cstrcasecmp_with_null("XMLNS", s, 5) == 0 || cstrcasecmp_with_null("XLINK", s, 5) == 0) {
353
- /* printf("Got XMLNS and XLINK tags\n"); */
354
- return TYPE_BLACK;
355
- }
356
- }
357
-
358
- black = BLACKATTR;
359
- while (black->name != NULL) {
360
- if (cstrcasecmp_with_null(black->name, s, len) == 0) {
361
- /* printf("Got banned attribute name %s\n", black->name); */
362
- return black->atype;
363
- }
364
- black += 1;
365
- }
366
-
367
- return TYPE_NONE;
368
- }
369
-
370
- static int is_black_url(const char* s, size_t len)
371
- {
372
-
373
- static const char* data_url = "DATA";
374
- static const char* viewsource_url = "VIEW-SOURCE";
375
-
376
- /* obsolete but interesting signal */
377
- static const char* vbscript_url = "VBSCRIPT";
378
-
379
- /* covers JAVA, JAVASCRIPT, + colon */
380
- static const char* javascript_url = "JAVA";
381
-
382
- /* skip whitespace */
383
- while (len > 0 && (*s <= 32 || *s >= 127)) {
384
- /*
385
- * HEY: this is a signed character.
386
- * We are intentionally skipping high-bit characters too
387
- * since they are not ASCII, and Opera sometimes uses UTF-8 whitespace.
388
- *
389
- * Also in EUC-JP some of the high bytes are just ignored.
390
- */
391
- ++s;
392
- --len;
393
- }
394
-
395
- if (htmlencode_startswith(data_url, s, len)) {
396
- return 1;
397
- }
398
-
399
- if (htmlencode_startswith(viewsource_url, s, len)) {
400
- return 1;
401
- }
402
-
403
- if (htmlencode_startswith(javascript_url, s, len)) {
404
- return 1;
405
- }
406
-
407
- if (htmlencode_startswith(vbscript_url, s, len)) {
408
- return 1;
409
- }
410
- return 0;
411
- }
412
-
413
- int libinjection_is_xss(const char* s, size_t len, int flags)
414
- {
415
- h5_state_t h5;
416
- attribute_t attr = TYPE_NONE;
417
-
418
- libinjection_h5_init(&h5, s, len, (enum html5_flags) flags);
419
- while (libinjection_h5_next(&h5)) {
420
- if (h5.token_type != ATTR_VALUE) {
421
- attr = TYPE_NONE;
422
- }
423
-
424
- if (h5.token_type == DOCTYPE) {
425
- return 1;
426
- } else if (h5.token_type == TAG_NAME_OPEN) {
427
- if (is_black_tag(h5.token_start, h5.token_len)) {
428
- return 1;
429
- }
430
- } else if (h5.token_type == ATTR_NAME) {
431
- attr = is_black_attr(h5.token_start, h5.token_len);
432
- } else if (h5.token_type == ATTR_VALUE) {
433
- /*
434
- * IE6,7,8 parsing works a bit differently so
435
- * a whole <script> or other black tag might be hiding
436
- * inside an attribute value under HTML 5 parsing
437
- * See http://html5sec.org/#102
438
- * to avoid doing a full reparse of the value, just
439
- * look for "<". This probably need adjusting to
440
- * handle escaped characters
441
- */
442
- /*
443
- if (memchr(h5.token_start, '<', h5.token_len) != NULL) {
444
- return 1;
445
- }
446
- */
447
-
448
- switch (attr) {
449
- case TYPE_NONE:
450
- break;
451
- case TYPE_BLACK:
452
- return 1;
453
- case TYPE_ATTR_URL:
454
- if (is_black_url(h5.token_start, h5.token_len)) {
455
- return 1;
456
- }
457
- break;
458
- case TYPE_STYLE:
459
- return 1;
460
- case TYPE_ATTR_INDIRECT:
461
- /* an attribute name is specified in a _value_ */
462
- if (is_black_attr(h5.token_start, h5.token_len)) {
463
- return 1;
464
- }
465
- break;
466
- /*
467
- default:
468
- assert(0);
469
- */
470
- }
471
- attr = TYPE_NONE;
472
- } else if (h5.token_type == TAG_COMMENT) {
473
- /* IE uses a "`" as a tag ending char */
474
- if (memchr(h5.token_start, '`', h5.token_len) != NULL) {
475
- return 1;
476
- }
477
-
478
- /* IE conditional comment */
479
- if (h5.token_len > 3) {
480
- if (h5.token_start[0] == '[' &&
481
- (h5.token_start[1] == 'i' || h5.token_start[1] == 'I') &&
482
- (h5.token_start[2] == 'f' || h5.token_start[2] == 'F')) {
483
- return 1;
484
- }
485
- if ((h5.token_start[0] == 'x' || h5.token_start[0] == 'X') &&
486
- (h5.token_start[1] == 'm' || h5.token_start[1] == 'M') &&
487
- (h5.token_start[2] == 'l' || h5.token_start[2] == 'L')) {
488
- return 1;
489
- }
490
- }
491
-
492
- if (h5.token_len > 5) {
493
- /* IE <?import pseudo-tag */
494
- if (cstrcasecmp_with_null("IMPORT", h5.token_start, 6) == 0) {
495
- return 1;
496
- }
497
-
498
- /* XML Entity definition */
499
- if (cstrcasecmp_with_null("ENTITY", h5.token_start, 6) == 0) {
500
- return 1;
501
- }
502
- }
503
- }
504
- }
505
- return 0;
506
- }
507
-
508
-
509
- /*
510
- * wrapper
511
- */
512
- int libinjection_xss(const char* s, size_t len)
513
- {
514
- if (libinjection_is_xss(s, len, DATA_STATE)) {
515
- return 1;
516
- }
517
- if (libinjection_is_xss(s, len, VALUE_NO_QUOTE)) {
518
- return 1;
519
- }
520
- if (libinjection_is_xss(s, len, VALUE_SINGLE_QUOTE)) {
521
- return 1;
522
- }
523
- if (libinjection_is_xss(s, len, VALUE_DOUBLE_QUOTE)) {
524
- return 1;
525
- }
526
- if (libinjection_is_xss(s, len, VALUE_BACK_QUOTE)) {
527
- return 1;
528
- }
529
-
530
- return 0;
531
- }
@@ -1,21 +0,0 @@
1
- #ifndef LIBINJECTION_XSS
2
- #define LIBINJECTION_XSS
3
-
4
- #ifdef __cplusplus
5
- extern "C" {
6
- #endif
7
-
8
- /**
9
- * HEY THIS ISN'T DONE
10
- */
11
-
12
- /* pull in size_t */
13
-
14
- #include <string.h>
15
-
16
- int libinjection_is_xss(const char* s, size_t len, int flags);
17
-
18
- #ifdef __cplusplus
19
- }
20
- #endif
21
- #endif
@@ -1,155 +0,0 @@
1
- require 'tcell_agent/policies/appsensor/cmdi_sensor'
2
- require 'tcell_agent/policies/appsensor/fpt_sensor'
3
- require 'tcell_agent/policies/appsensor/nullbyte_sensor'
4
- require 'tcell_agent/policies/appsensor/retr_sensor'
5
- require 'tcell_agent/policies/appsensor/sqli_sensor'
6
- require 'tcell_agent/policies/appsensor/xss_sensor'
7
- require 'tcell_agent/utils/params'
8
-
9
-
10
- module TCellAgent
11
- module AppSensor
12
-
13
- class InjectionsMatcher
14
- GET_PARAM = TCellAgent::Utils::Params::GET_PARAM
15
- POST_PARAM = TCellAgent::Utils::Params::POST_PARAM
16
- JSON_PARAM = TCellAgent::Utils::Params::JSON_PARAM
17
- COOKIE_PARAM = TCellAgent::Utils::Params::COOKIE_PARAM
18
- URI_PARAM = TCellAgent::Utils::Params::URI_PARAM
19
- HEADER_PARAM = TCellAgent::Utils::Params::HEADER_PARAM
20
-
21
- DETECTION_POINTS_V2 = {
22
- "xss" => TCellAgent::Policies::XssSensor,
23
- "sqli" => TCellAgent::Policies::SqliSensor,
24
- "cmdi" => TCellAgent::Policies::CmdiSensor,
25
- "fpt" => TCellAgent::Policies::FptSensor,
26
- "nullbyte" => TCellAgent::Policies::NullbyteSensor,
27
- "retr" => TCellAgent::Policies::RetrSensor
28
- }
29
-
30
- attr_accessor :enabled, :sensors
31
-
32
- def initialize(sensors)
33
- @sensors = sensors
34
- @enabled = sensors.size > 0
35
- end
36
-
37
- def each_injection(meta_data)
38
- return unless @enabled
39
-
40
- meta_data.flattened_path_parameters.each do |param_name, param_value|
41
- TCellAgent::Instrumentation.safe_block("AppSensor Check Path Params injections") do
42
- param_name = param_name[-1]
43
- injection_attempt =
44
- check_param_for_injections(URI_PARAM, meta_data, param_name, param_value)
45
-
46
- yield(injection_attempt) if injection_attempt
47
- end
48
- end
49
-
50
- meta_data.flattened_get_dict.each do |param_name, param_value|
51
- TCellAgent::Instrumentation.safe_block("AppSensor Check GET var injections") do
52
- param_name = param_name[-1]
53
- injection_attempt =
54
- check_param_for_injections(GET_PARAM, meta_data, param_name, param_value)
55
-
56
- yield(injection_attempt) if injection_attempt
57
- end
58
- end
59
-
60
- meta_data.flattened_post_dict.each do |param_name, param_value|
61
- TCellAgent::Instrumentation.safe_block("AppSensor Check POST var injections") do
62
- param_name = param_name[-1]
63
- injection_attempt =
64
- check_param_for_injections(POST_PARAM, meta_data, param_name, param_value)
65
-
66
- yield(injection_attempt) if injection_attempt
67
- end
68
- end
69
-
70
- meta_data.flattened_body_dict.each do |param_name, param_value|
71
- TCellAgent::Instrumentation.safe_block("AppSensor Check JSON var injections") do
72
- param_name = param_name[-1]
73
- injection_attempt = check_param_for_injections(JSON_PARAM, meta_data, param_name, param_value)
74
-
75
- yield(injection_attempt) if injection_attempt
76
- end
77
- end
78
-
79
- meta_data.flattened_cookie_dict.each do |param_name, param_value|
80
- TCellAgent::Instrumentation.safe_block("AppSensor Check COOKIE var injections") do
81
- param_name = param_name[-1]
82
- injection_attempt =
83
- check_param_for_injections(COOKIE_PARAM, meta_data, param_name, param_value)
84
-
85
- yield(injection_attempt) if injection_attempt
86
- end
87
- end
88
-
89
- meta_data.flattened_headers_dict.each do |param_name, param_value|
90
- TCellAgent::Instrumentation.safe_block("AppSensor Check HEADER var injections") do
91
- param_name = param_name[-1]
92
- injection_attempt =
93
- check_param_for_injections(HEADER_PARAM, meta_data, param_name, param_value)
94
-
95
- yield(injection_attempt) if injection_attempt
96
- end
97
- end
98
- end
99
-
100
- def check_param_for_injections(param_type, appsensor_meta, param_name, param_value)
101
- @sensors.each do |sensor|
102
- next unless sensor.applicable_for_param_type?(param_type)
103
-
104
- injection_attempt = sensor.get_injection_attempt(param_type, appsensor_meta, param_name, param_value)
105
- return injection_attempt if injection_attempt
106
- end
107
-
108
- return nil
109
- end
110
-
111
- def self.from_json(version, sensors_json)
112
- sensors_json = sensors_json || {}
113
- sensors = []
114
-
115
- if version == 1
116
- options_json = sensors_json.fetch("options", {})
117
-
118
- (options_json || {}).each do |sensor_key, enabled|
119
- next unless enabled
120
-
121
- if sensor_key == "null"
122
- sensor_key = "nullbyte"
123
- end
124
-
125
- clazz = DETECTION_POINTS_V2[sensor_key]
126
-
127
- next unless clazz
128
-
129
- sensors.push(clazz.new(
130
- {
131
- "enabled" => enabled,
132
- "v1_compatability_enabled" => true
133
- }
134
- ))
135
- end
136
-
137
- elsif version == 2
138
- sensors_json.each do |sensor_key, settings|
139
- clazz = DETECTION_POINTS_V2[sensor_key]
140
-
141
- next unless clazz
142
-
143
- updated_settings = {"enabled" => true}.merge(settings)
144
- if updated_settings["enabled"]
145
- sensors.push(clazz.new(updated_settings))
146
- end
147
- end
148
- end
149
-
150
- InjectionsMatcher.new(sensors)
151
- end
152
- end
153
-
154
- end
155
- end