aboutsummaryrefslogtreecommitdiff
path: root/src/lib/third_party/include/libinjection_sqli.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/third_party/include/libinjection_sqli.h')
-rw-r--r--src/lib/third_party/include/libinjection_sqli.h294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/lib/third_party/include/libinjection_sqli.h b/src/lib/third_party/include/libinjection_sqli.h
new file mode 100644
index 000000000..b9746555a
--- /dev/null
+++ b/src/lib/third_party/include/libinjection_sqli.h
@@ -0,0 +1,294 @@
+/**
+ * Copyright 2012-2016 Nick Galbreath
+ * nickg@client9.com
+ * BSD License -- see `COPYING.txt` for details
+ *
+ * https://libinjection.client9.com/
+ *
+ */
+
+#ifndef LIBINJECTION_SQLI_H
+#define LIBINJECTION_SQLI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Pull in size_t
+ */
+#include <string.h>
+
+enum sqli_flags {
+ FLAG_NONE = 0
+ , FLAG_QUOTE_NONE = 1 /* 1 << 0 */
+ , FLAG_QUOTE_SINGLE = 2 /* 1 << 1 */
+ , FLAG_QUOTE_DOUBLE = 4 /* 1 << 2 */
+
+ , FLAG_SQL_ANSI = 8 /* 1 << 3 */
+ , FLAG_SQL_MYSQL = 16 /* 1 << 4 */
+};
+
+enum lookup_type {
+ LOOKUP_WORD = 1
+ , LOOKUP_TYPE = 2
+ , LOOKUP_OPERATOR = 3
+ , LOOKUP_FINGERPRINT = 4
+};
+
+struct libinjection_sqli_token {
+#ifdef SWIG
+%immutable;
+#endif
+ /*
+ * position and length of token
+ * in original string
+ */
+ size_t pos;
+ size_t len;
+
+ /* count:
+ * in type 'v', used for number of opening '@'
+ * but maybe used in other contexts
+ */
+ int count;
+
+ char type;
+ char str_open;
+ char str_close;
+ char val[32];
+};
+
+typedef struct libinjection_sqli_token stoken_t;
+
+/**
+ * Pointer to function, takes c-string input,
+ * returns '\0' for no match, else a char
+ */
+struct libinjection_sqli_state;
+typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state*, int lookuptype, const char* word, size_t len);
+
+struct libinjection_sqli_state {
+#ifdef SWIG
+%immutable;
+#endif
+
+ /*
+ * input, does not need to be null terminated.
+ * it is also not modified.
+ */
+ const char *s;
+
+ /*
+ * input length
+ */
+ size_t slen;
+
+ /*
+ * How to lookup a word or fingerprint
+ */
+ ptr_lookup_fn lookup;
+ void* userdata;
+
+ /*
+ *
+ */
+ int flags;
+
+ /*
+ * pos is the index in the string during tokenization
+ */
+ size_t pos;
+
+#ifndef SWIG
+ /* for SWIG.. don't use this.. use functional API instead */
+
+ /* MAX TOKENS + 1 since we use one extra token
+ * to determine the type of the previous token
+ */
+ struct libinjection_sqli_token tokenvec[8];
+#endif
+
+ /*
+ * Pointer to token position in tokenvec, above
+ */
+ struct libinjection_sqli_token *current;
+
+ /*
+ * fingerprint pattern c-string
+ * +1 for ending null
+ * Minimum of 8 bytes to add gcc's -fstack-protector to work
+ */
+ char fingerprint[8];
+
+ /*
+ * Line number of code that said decided if the input was SQLi or
+ * not. Most of the time it's line that said "it's not a matching
+ * fingerprint" but there is other logic that sometimes approves
+ * an input. This is only useful for debugging.
+ *
+ */
+ int reason;
+
+ /* Number of ddw (dash-dash-white) comments
+ * These comments are in the form of
+ * '--[whitespace]' or '--[EOF]'
+ *
+ * All databases treat this as a comment.
+ */
+ int stats_comment_ddw;
+
+ /* Number of ddx (dash-dash-[notwhite]) comments
+ *
+ * ANSI SQL treats these are comments, MySQL treats this as
+ * two unary operators '-' '-'
+ *
+ * If you are parsing result returns FALSE and
+ * stats_comment_dd > 0, you should reparse with
+ * COMMENT_MYSQL
+ *
+ */
+ int stats_comment_ddx;
+
+ /*
+ * c-style comments found /x .. x/
+ */
+ int stats_comment_c;
+
+ /* '#' operators or MySQL EOL comments found
+ *
+ */
+ int stats_comment_hash;
+
+ /*
+ * number of tokens folded away
+ */
+ int stats_folds;
+
+ /*
+ * total tokens processed
+ */
+ int stats_tokens;
+
+};
+
+typedef struct libinjection_sqli_state sfilter;
+
+struct libinjection_sqli_token* libinjection_sqli_get_token(
+ struct libinjection_sqli_state* sqlistate, int i);
+
+/*
+ * Version info.
+ *
+ * This is moved into a function to allow SWIG and other auto-generated
+ * binding to not be modified during minor release changes. We change
+ * change the version number in the c source file, and not regenerated
+ * the binding
+ *
+ * See python's normalized version
+ * http://www.python.org/dev/peps/pep-0386/#normalizedversion
+ */
+const char* libinjection_version(void);
+
+/**
+ *
+ */
+void libinjection_sqli_init(struct libinjection_sqli_state* sql_state,
+ const char* s, size_t slen,
+ int flags);
+
+/**
+ * Main API: tests for SQLi in three possible contexts, no quotes,
+ * single quote and double quote
+ *
+ * \param sql_state core data structure
+ *
+ * \return 1 (true) if SQLi, 0 (false) if benign
+ */
+int libinjection_is_sqli(struct libinjection_sqli_state* sql_state);
+
+/* FOR HACKERS ONLY
+ * provides deep hooks into the decision making process
+ */
+void libinjection_sqli_callback(struct libinjection_sqli_state* sql_state,
+ ptr_lookup_fn fn,
+ void* userdata);
+
+
+/*
+ * Resets state, but keeps initial string and callbacks
+ */
+void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state,
+ int flags);
+
+/**
+ *
+ */
+
+/**
+ * This detects SQLi in a single context, mostly useful for custom
+ * logic and debugging.
+ *
+ * \param sql_state Main data structure
+ * \param flags flags to adjust parsing
+ *
+ * \returns a pointer to sfilter.fingerprint as convenience
+ * do not free!
+ *
+ */
+const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state* sql_state,
+ int flags);
+
+/**
+ * The default "word" to token-type or fingerprint function. This
+ * uses a ASCII case-insensitive binary tree.
+ */
+char libinjection_sqli_lookup_word(struct libinjection_sqli_state* sql_state,
+ int lookup_type,
+ const char* s,
+ size_t slen);
+
+/* Streaming tokenization interface.
+ *
+ * sql_state->current is updated with the current token.
+ *
+ * \returns 1, has a token, keep going, or 0 no tokens
+ *
+ */
+int libinjection_sqli_tokenize(struct libinjection_sqli_state * sql_state);
+
+/**
+ * parses and folds input, up to 5 tokens
+ *
+ */
+int libinjection_sqli_fold(struct libinjection_sqli_state * sql_state);
+
+/** The built-in default function to match fingerprints
+ * and do false negative/positive analysis. This calls the following
+ * two functions. With this, you over-ride one part or the other.
+ *
+ * return libinjection_sqli_blacklist(sql_state) &&
+ * libinjection_sqli_not_whitelist(sql_state);
+ *
+ * \param sql_state should be filled out after libinjection_sqli_fingerprint is called
+ */
+int libinjection_sqli_check_fingerprint(struct libinjection_sqli_state * sql_state);
+
+/* Given a pattern determine if it's a SQLi pattern.
+ *
+ * \return TRUE if sqli, false otherwise
+ */
+int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state);
+
+/* Given a positive match for a pattern (i.e. pattern is SQLi), this function
+ * does additional analysis to reduce false positives.
+ *
+ * \return TRUE if SQLi, false otherwise
+ */
+int libinjection_sqli_not_whitelist(struct libinjection_sqli_state * sql_state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBINJECTION_SQLI_H */