tcell_agent 0.4.0 → 1.0.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 (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