rack-libinjection 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +55 -0
  3. data/CHANGELOG.md +112 -0
  4. data/GET_STARTED.md +418 -0
  5. data/LICENSE-libinjection.txt +33 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +68 -0
  8. data/SECURITY.md +65 -0
  9. data/ext/libinjection/extconf.rb +113 -0
  10. data/ext/libinjection/libinjection_ext.c +1132 -0
  11. data/ext/libinjection/vendor/libinjection/.vendored +5 -0
  12. data/ext/libinjection/vendor/libinjection/COPYING +33 -0
  13. data/ext/libinjection/vendor/libinjection/MIGRATION.md +393 -0
  14. data/ext/libinjection/vendor/libinjection/README.md +251 -0
  15. data/ext/libinjection/vendor/libinjection/src/libinjection.h +70 -0
  16. data/ext/libinjection/vendor/libinjection/src/libinjection_error.h +26 -0
  17. data/ext/libinjection/vendor/libinjection/src/libinjection_html5.c +830 -0
  18. data/ext/libinjection/vendor/libinjection/src/libinjection_html5.h +56 -0
  19. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli.c +2342 -0
  20. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli.h +297 -0
  21. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli_data.h +9651 -0
  22. data/ext/libinjection/vendor/libinjection/src/libinjection_xss.c +1203 -0
  23. data/ext/libinjection/vendor/libinjection/src/libinjection_xss.h +23 -0
  24. data/lib/libinjection/version.rb +6 -0
  25. data/lib/libinjection.rb +31 -0
  26. data/lib/rack/libinjection.rb +586 -0
  27. data/lib/rack-libinjection.rb +3 -0
  28. data/samples/README.md +67 -0
  29. data/samples/libinjection_detect_raw_hot_path.rb +161 -0
  30. data/samples/rack_all_surfaces_hot_path.rb +198 -0
  31. data/samples/rack_params_hot_path.rb +166 -0
  32. data/samples/rack_query_hot_path.rb +176 -0
  33. data/samples/results/.gitkeep +0 -0
  34. data/script/fuzz_smoke.rb +39 -0
  35. data/script/vendor_libs.rb +227 -0
  36. data/test/test_helper.rb +7 -0
  37. data/test/test_libinjection.rb +223 -0
  38. data/test/test_middleware.rb +404 -0
  39. metadata +148 -0
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Copyright 2012-2016 Nick Galbreath
3
+ * nickg@client9.com
4
+ * BSD License -- see `COPYING.txt` for details
5
+ *
6
+ * https://libinjection.client9.com/
7
+ *
8
+ */
9
+
10
+ #ifndef LIBINJECTION_SQLI_H
11
+ #define LIBINJECTION_SQLI_H
12
+
13
+ #ifdef __cplusplus
14
+ extern "C" {
15
+ #endif
16
+
17
+ /*
18
+ * Pull in size_t
19
+ */
20
+ #include <string.h>
21
+
22
+ #include "libinjection_error.h"
23
+
24
+ enum sqli_flags {
25
+ FLAG_NONE = 0,
26
+ FLAG_QUOTE_NONE = 1, /* 1 << 0 */
27
+ FLAG_QUOTE_SINGLE = 2, /* 1 << 1 */
28
+ FLAG_QUOTE_DOUBLE = 4, /* 1 << 2 */
29
+ FLAG_SQL_ANSI = 8, /* 1 << 3 */
30
+ FLAG_SQL_MYSQL = 16 /* 1 << 4 */
31
+ };
32
+
33
+ enum lookup_type {
34
+ LOOKUP_WORD = 1,
35
+ LOOKUP_TYPE = 2,
36
+ LOOKUP_OPERATOR = 3,
37
+ LOOKUP_FINGERPRINT = 4
38
+ };
39
+
40
+ struct libinjection_sqli_token { // cppcheck-suppress syntaxError
41
+ #ifdef SWIG
42
+ %immutable;
43
+ #endif
44
+ /*
45
+ * position and length of token
46
+ * in original string
47
+ */
48
+ size_t pos;
49
+ size_t len;
50
+
51
+ /* count:
52
+ * in type 'v', used for number of opening '@'
53
+ * but maybe used in other contexts
54
+ */
55
+ int count;
56
+
57
+ char type;
58
+ char str_open;
59
+ char str_close;
60
+ char val[32];
61
+ };
62
+
63
+ typedef struct libinjection_sqli_token stoken_t;
64
+
65
+ /**
66
+ * Pointer to function, takes c-string input,
67
+ * returns '\0' for no match, else a char
68
+ */
69
+ struct libinjection_sqli_state;
70
+ typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state *, int lookuptype,
71
+ const char *word, size_t len);
72
+
73
+ struct libinjection_sqli_state {
74
+ #ifdef SWIG
75
+ %immutable;
76
+ #endif
77
+
78
+ /*
79
+ * input, does not need to be null terminated.
80
+ * it is also not modified.
81
+ */
82
+ const char *s;
83
+
84
+ /*
85
+ * input length
86
+ */
87
+ size_t slen;
88
+
89
+ /*
90
+ * How to lookup a word or fingerprint
91
+ */
92
+ ptr_lookup_fn lookup;
93
+ void *userdata;
94
+
95
+ /*
96
+ *
97
+ */
98
+ int flags;
99
+
100
+ /*
101
+ * pos is the index in the string during tokenization
102
+ */
103
+ size_t pos;
104
+
105
+ #ifndef SWIG
106
+ /* for SWIG.. don't use this.. use functional API instead */
107
+
108
+ /* MAX TOKENS + 1 since we use one extra token
109
+ * to determine the type of the previous token
110
+ */
111
+ struct libinjection_sqli_token tokenvec[8];
112
+ #endif
113
+
114
+ /*
115
+ * Pointer to token position in tokenvec, above
116
+ */
117
+ struct libinjection_sqli_token *current;
118
+
119
+ /*
120
+ * fingerprint pattern c-string
121
+ * +1 for ending null
122
+ * Minimum of 8 bytes to add gcc's -fstack-protector to work
123
+ */
124
+ char fingerprint[8];
125
+
126
+ /*
127
+ * Line number of code that said decided if the input was SQLi or
128
+ * not. Most of the time it's line that said "it's not a matching
129
+ * fingerprint" but there is other logic that sometimes approves
130
+ * an input. This is only useful for debugging.
131
+ *
132
+ */
133
+ int reason;
134
+
135
+ /* Number of ddw (dash-dash-white) comments
136
+ * These comments are in the form of
137
+ * '--[whitespace]' or '--[EOF]'
138
+ *
139
+ * All databases treat this as a comment.
140
+ */
141
+ int stats_comment_ddw;
142
+
143
+ /* Number of ddx (dash-dash-[notwhite]) comments
144
+ *
145
+ * ANSI SQL treats these are comments, MySQL treats this as
146
+ * two unary operators '-' '-'
147
+ *
148
+ * If you are parsing result returns FALSE and
149
+ * stats_comment_dd > 0, you should reparse with
150
+ * COMMENT_MYSQL
151
+ *
152
+ */
153
+ int stats_comment_ddx;
154
+
155
+ /*
156
+ * c-style comments found /x .. x/
157
+ */
158
+ int stats_comment_c;
159
+
160
+ /* '#' operators or MySQL EOL comments found
161
+ *
162
+ */
163
+ int stats_comment_hash;
164
+
165
+ /*
166
+ * number of tokens folded away
167
+ */
168
+ int stats_folds;
169
+
170
+ /*
171
+ * total tokens processed
172
+ */
173
+ int stats_tokens;
174
+ };
175
+
176
+ typedef struct libinjection_sqli_state sfilter;
177
+
178
+ struct libinjection_sqli_token *
179
+ libinjection_sqli_get_token(struct libinjection_sqli_state *sql_state, int i);
180
+
181
+ /*
182
+ * Version info.
183
+ *
184
+ * This is moved into a function to allow SWIG and other auto-generated
185
+ * binding to not be modified during minor release changes. We change
186
+ * change the version number in the c source file, and not regenerated
187
+ * the binding
188
+ *
189
+ * See python's normalized version
190
+ * http://www.python.org/dev/peps/pep-0386/#normalizedversion
191
+ */
192
+ const char *libinjection_version(void);
193
+
194
+ /**
195
+ *
196
+ */
197
+ void libinjection_sqli_init(struct libinjection_sqli_state *sf, const char *s,
198
+ size_t len, int flags);
199
+
200
+ /**
201
+ * Main API: tests for SQLi in three possible contexts, no quotes,
202
+ * single quote and double quote
203
+ *
204
+ * \param sql_state core data structure
205
+ *
206
+ * \return injection_result_t
207
+ */
208
+ injection_result_t
209
+ libinjection_is_sqli(struct libinjection_sqli_state *sql_state);
210
+
211
+ /* FOR HACKERS ONLY
212
+ * provides deep hooks into the decision making process
213
+ */
214
+ void libinjection_sqli_callback(struct libinjection_sqli_state *sf,
215
+ ptr_lookup_fn fn, void *userdata);
216
+
217
+ /*
218
+ * Resets state, but keeps initial string and callbacks
219
+ */
220
+ static void libinjection_sqli_reset(struct libinjection_sqli_state *sf,
221
+ int flags);
222
+
223
+ /**
224
+ *
225
+ */
226
+
227
+ /**
228
+ * This detects SQLi in a single context, mostly useful for custom
229
+ * logic and debugging.
230
+ *
231
+ * \param sql_state Main data structure
232
+ * \param flags flags to adjust parsing
233
+ *
234
+ * \returns a pointer to sfilter.fingerprint as convenience
235
+ * do not free!
236
+ *
237
+ */
238
+ const char *
239
+ libinjection_sqli_fingerprint(struct libinjection_sqli_state *sql_state,
240
+ int flags);
241
+
242
+ /**
243
+ * The default "word" to token-type or fingerprint function. This
244
+ * uses a ASCII case-insensitive binary tree.
245
+ */
246
+ static char
247
+ libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state,
248
+ int lookup_type, const char *str, size_t len);
249
+
250
+ /* Streaming tokenization interface.
251
+ *
252
+ * sql_state->current is updated with the current token.
253
+ *
254
+ * \returns 1, has a token, keep going, or 0 no tokens
255
+ *
256
+ */
257
+ int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf);
258
+
259
+ /**
260
+ * parses and folds input, up to 5 tokens
261
+ *
262
+ */
263
+ int libinjection_sqli_fold(struct libinjection_sqli_state *sf);
264
+
265
+ /** The built-in default function to match fingerprints
266
+ * and do false negative/positive analysis. This calls the following
267
+ * two functions. With this, you over-ride one part or the other.
268
+ *
269
+ * return libinjection_sqli_blacklist(sql_state) &&
270
+ * libinjection_sqli_not_whitelist(sql_state);
271
+ *
272
+ * \param sql_state should be filled out after libinjection_sqli_fingerprint is
273
+ * called
274
+ */
275
+ int libinjection_sqli_check_fingerprint(
276
+ struct libinjection_sqli_state *sql_state);
277
+
278
+ /* Given a pattern determine if it's a SQLi pattern.
279
+ *
280
+ * \return TRUE if sqli, false otherwise
281
+ */
282
+ static int
283
+ libinjection_sqli_blacklist(struct libinjection_sqli_state *sql_state);
284
+
285
+ /* Given a positive match for a pattern (i.e. pattern is SQLi), this function
286
+ * does additional analysis to reduce false positives.
287
+ *
288
+ * \return TRUE if SQLi, false otherwise
289
+ */
290
+ static int
291
+ libinjection_sqli_not_whitelist(struct libinjection_sqli_state *sql_state);
292
+
293
+ #ifdef __cplusplus
294
+ }
295
+ #endif
296
+
297
+ #endif /* LIBINJECTION_SQLI_H */