Blame apache2/libinjection/libinjection_sqli.h

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