github.com/TeaOSLab/EdgeNode@v1.3.8/internal/waf/injectionutils/libinjection/src/libinjection_sqli.h (about) 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 enum sqli_flags { 23 FLAG_NONE = 0 24 , FLAG_QUOTE_NONE = 1 /* 1 << 0 */ 25 , FLAG_QUOTE_SINGLE = 2 /* 1 << 1 */ 26 , FLAG_QUOTE_DOUBLE = 4 /* 1 << 2 */ 27 28 , FLAG_SQL_ANSI = 8 /* 1 << 3 */ 29 , FLAG_SQL_MYSQL = 16 /* 1 << 4 */ 30 }; 31 32 enum lookup_type { 33 LOOKUP_WORD = 1 34 , LOOKUP_TYPE = 2 35 , LOOKUP_OPERATOR = 3 36 , LOOKUP_FINGERPRINT = 4 37 }; 38 39 struct libinjection_sqli_token { 40 #ifdef SWIG 41 %immutable; 42 #endif 43 /* 44 * position and length of token 45 * in original string 46 */ 47 size_t pos; 48 size_t len; 49 50 /* count: 51 * in type 'v', used for number of opening '@' 52 * but maybe used in other contexts 53 */ 54 int count; 55 56 char type; 57 char str_open; 58 char str_close; 59 char val[32]; 60 }; 61 62 typedef struct libinjection_sqli_token stoken_t; 63 64 /** 65 * Pointer to function, takes c-string input, 66 * returns '\0' for no match, else a char 67 */ 68 struct libinjection_sqli_state; 69 typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state*, int lookuptype, const char* word, size_t len); 70 71 struct libinjection_sqli_state { 72 #ifdef SWIG 73 %immutable; 74 #endif 75 76 /* 77 * input, does not need to be null terminated. 78 * it is also not modified. 79 */ 80 const char *s; 81 82 /* 83 * input length 84 */ 85 size_t slen; 86 87 /* 88 * How to lookup a word or fingerprint 89 */ 90 ptr_lookup_fn lookup; 91 void* userdata; 92 93 /* 94 * 95 */ 96 int flags; 97 98 /* 99 * pos is the index in the string during tokenization 100 */ 101 size_t pos; 102 103 #ifndef SWIG 104 /* for SWIG.. don't use this.. use functional API instead */ 105 106 /* MAX TOKENS + 1 since we use one extra token 107 * to determine the type of the previous token 108 */ 109 struct libinjection_sqli_token tokenvec[8]; 110 #endif 111 112 /* 113 * Pointer to token position in tokenvec, above 114 */ 115 struct libinjection_sqli_token *current; 116 117 /* 118 * fingerprint pattern c-string 119 * +1 for ending null 120 * Minimum of 8 bytes to add gcc's -fstack-protector to work 121 */ 122 char fingerprint[8]; 123 124 /* 125 * Line number of code that said decided if the input was SQLi or 126 * not. Most of the time it's line that said "it's not a matching 127 * fingerprint" but there is other logic that sometimes approves 128 * an input. This is only useful for debugging. 129 * 130 */ 131 int reason; 132 133 /* Number of ddw (dash-dash-white) comments 134 * These comments are in the form of 135 * '--[whitespace]' or '--[EOF]' 136 * 137 * All databases treat this as a comment. 138 */ 139 int stats_comment_ddw; 140 141 /* Number of ddx (dash-dash-[notwhite]) comments 142 * 143 * ANSI SQL treats these are comments, MySQL treats this as 144 * two unary operators '-' '-' 145 * 146 * If you are parsing result returns FALSE and 147 * stats_comment_dd > 0, you should reparse with 148 * COMMENT_MYSQL 149 * 150 */ 151 int stats_comment_ddx; 152 153 /* 154 * c-style comments found /x .. x/ 155 */ 156 int stats_comment_c; 157 158 /* '#' operators or MySQL EOL comments found 159 * 160 */ 161 int stats_comment_hash; 162 163 /* 164 * number of tokens folded away 165 */ 166 int stats_folds; 167 168 /* 169 * total tokens processed 170 */ 171 int stats_tokens; 172 173 }; 174 175 typedef struct libinjection_sqli_state sfilter; 176 177 struct libinjection_sqli_token* libinjection_sqli_get_token( 178 struct libinjection_sqli_state* sql_state, int i); 179 180 /* 181 * Version info. 182 * 183 * This is moved into a function to allow SWIG and other auto-generated 184 * binding to not be modified during minor release changes. We change 185 * change the version number in the c source file, and not regenerated 186 * the binding 187 * 188 * See python's normalized version 189 * http://www.python.org/dev/peps/pep-0386/#normalizedversion 190 */ 191 const char* libinjection_version(void); 192 193 /** 194 * 195 */ 196 void libinjection_sqli_init(struct libinjection_sqli_state *sf, 197 const char* s, size_t len, 198 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 1 (true) if SQLi, 0 (false) if benign 207 */ 208 int libinjection_is_sqli(struct libinjection_sqli_state* sql_state); 209 210 /* FOR HACKERS ONLY 211 * provides deep hooks into the decision making process 212 */ 213 void libinjection_sqli_callback(struct libinjection_sqli_state *sf, 214 ptr_lookup_fn fn, 215 void* userdata); 216 217 218 /* 219 * Resets state, but keeps initial string and callbacks 220 */ 221 void libinjection_sqli_reset(struct libinjection_sqli_state *sf, 222 int flags); 223 224 /** 225 * 226 */ 227 228 /** 229 * This detects SQLi in a single context, mostly useful for custom 230 * logic and debugging. 231 * 232 * \param sql_state Main data structure 233 * \param flags flags to adjust parsing 234 * 235 * \returns a pointer to sfilter.fingerprint as convenience 236 * do not free! 237 * 238 */ 239 const char* 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 char libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state, 247 int lookup_type, 248 const char* str, 249 size_t len); 250 251 /* Streaming tokenization interface. 252 * 253 * sql_state->current is updated with the current token. 254 * 255 * \returns 1, has a token, keep going, or 0 no tokens 256 * 257 */ 258 int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf); 259 260 /** 261 * parses and folds input, up to 5 tokens 262 * 263 */ 264 int libinjection_sqli_fold(struct libinjection_sqli_state *sf); 265 266 /** The built-in default function to match fingerprints 267 * and do false negative/positive analysis. This calls the following 268 * two functions. With this, you over-ride one part or the other. 269 * 270 * return libinjection_sqli_blacklist(sql_state) && 271 * libinjection_sqli_not_whitelist(sql_state); 272 * 273 * \param sql_state should be filled out after libinjection_sqli_fingerprint is called 274 */ 275 int libinjection_sqli_check_fingerprint(struct libinjection_sqli_state * sql_state); 276 277 /* Given a pattern determine if it's a SQLi pattern. 278 * 279 * \return TRUE if sqli, false otherwise 280 */ 281 int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state); 282 283 /* Given a positive match for a pattern (i.e. pattern is SQLi), this function 284 * does additional analysis to reduce false positives. 285 * 286 * \return TRUE if SQLi, false otherwise 287 */ 288 int libinjection_sqli_not_whitelist(struct libinjection_sqli_state * sql_state); 289 290 #ifdef __cplusplus 291 } 292 #endif 293 294 #endif /* LIBINJECTION_SQLI_H */