Skip to content

Commit

Permalink
Update libinjection code
Browse files Browse the repository at this point in the history
Update libinjection code to the current master libinjection/libinjection@7e4b74e

The goal is to finally fix ntop#1820
See: libinjection/libinjection#33

Close ntop#1820
  • Loading branch information
IvanNardi committed Mar 27, 2023
1 parent 9ea8a57 commit 0c1d0e9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 33 deletions.
22 changes: 11 additions & 11 deletions src/lib/third_party/include/libinjection_sqli.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ struct libinjection_sqli_state {
typedef struct libinjection_sqli_state sfilter;

struct libinjection_sqli_token* libinjection_sqli_get_token(
struct libinjection_sqli_state* sqlistate, int i);
struct libinjection_sqli_state* sql_state, int i);

/*
* Version info.
Expand All @@ -193,8 +193,8 @@ const char* libinjection_version(void);
/**
*
*/
void libinjection_sqli_init(struct libinjection_sqli_state* sql_state,
const char* s, size_t slen,
void libinjection_sqli_init(struct libinjection_sqli_state *sf,
const char* s, size_t len,
int flags);

/**
Expand All @@ -210,15 +210,15 @@ 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,
void libinjection_sqli_callback(struct libinjection_sqli_state *sf,
ptr_lookup_fn fn,
void* userdata);


/*
* Resets state, but keeps initial string and callbacks
*/
void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state,
void libinjection_sqli_reset(struct libinjection_sqli_state *sf,
int flags);

/**
Expand All @@ -236,17 +236,17 @@ void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state,
* do not free!
*
*/
const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state* sql_state,
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,
char libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state,
int lookup_type,
const char* s,
size_t slen);
const char* str,
size_t len);

/* Streaming tokenization interface.
*
Expand All @@ -255,13 +255,13 @@ char libinjection_sqli_lookup_word(struct libinjection_sqli_state* sql_state,
* \returns 1, has a token, keep going, or 0 no tokens
*
*/
int libinjection_sqli_tokenize(struct libinjection_sqli_state * sql_state);
int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf);

/**
* parses and folds input, up to 5 tokens
*
*/
int libinjection_sqli_fold(struct libinjection_sqli_state * sql_state);
int libinjection_sqli_fold(struct libinjection_sqli_state *sf);

/** The built-in default function to match fingerprints
* and do false negative/positive analysis. This calls the following
Expand Down
20 changes: 19 additions & 1 deletion src/lib/third_party/src/libinjection_html5.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/* prototypes */

static int h5_skip_white(h5_state_t* hs);
static int h5_is_white(char c);
static int h5_is_white(char ch);
static int h5_state_eof(h5_state_t* hs);
static int h5_state_data(h5_state_t* hs);
static int h5_state_tag_open(h5_state_t* hs);
Expand Down Expand Up @@ -323,13 +323,29 @@ static int h5_state_before_attribute_name(h5_state_t* hs)
int ch;

TRACE();

/* for manual tail call optimization, see comment below */
tail_call:;

ch = h5_skip_white(hs);
switch (ch) {
case CHAR_EOF: {
return 0;
}
case CHAR_SLASH: {
hs->pos += 1;
/* Logically, We want to call h5_state_self_closing_start_tag(hs) here.
As this function may call us back and the compiler
might not implement automatic tail call optimization,
this might result in a deep recursion.
We detect this case here and start over with the current state.
*/

if (hs->pos < hs->len && hs->s[hs->pos] != CHAR_GT) {
goto tail_call;
}
return h5_state_self_closing_start_tag(hs);
}
case CHAR_GT: {
Expand Down Expand Up @@ -574,6 +590,8 @@ static int h5_state_after_attribute_value_quoted_state(h5_state_t* hs)

/**
* 12.2.4.43
*
* WARNING: This function is partially inlined into h5_state_before_attribute_name()
*/
static int h5_state_self_closing_start_tag(h5_state_t* hs)
{
Expand Down
37 changes: 23 additions & 14 deletions src/lib/third_party/src/libinjection_sqli.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "libinjection_sqli.h"
#include "libinjection_sqli_data.h"

#define LIBINJECTION_VERSION "3.9.2"
#define LIBINJECTION_VERSION "3.9.2.60-8e70-dirty"

#define LIBINJECTION_SQLI_TOKEN_SIZE sizeof(((stoken_t*)(0))->val)
#define LIBINJECTION_SQLI_MAX_TOKENS 5
Expand Down Expand Up @@ -503,12 +503,7 @@ static size_t parse_slash(struct libinjection_sqli_state * sf)
* skip over initial '/x'
*/
ptr = memchr2(cur + 2, slen - (pos + 2), '*', '/');

/*
* (ptr == NULL) causes false positive in cppcheck 1.61
* casting to type seems to fix it
*/
if (ptr == (const char*) NULL) {
if (ptr == NULL) {
/* till end of line */
clen = slen - pos;
} else {
Expand All @@ -525,7 +520,10 @@ static size_t parse_slash(struct libinjection_sqli_state * sf)
* are an automatic black ban!
*/

if(ptr && (memchr2(cur + 2, (size_t)(ptr - (cur + 1)), '/', '*') != NULL)) {
if (
ptr != NULL &&
memchr2(cur + 2, (size_t)(ptr - (cur + 1)), '/', '*') != NULL
) {
ctype = TYPE_EVIL;
} else if (is_mysql_comment(cs, slen, pos)) {
ctype = TYPE_EVIL;
Expand Down Expand Up @@ -599,6 +597,16 @@ static size_t parse_operator2(struct libinjection_sqli_state * sf)
}
}

#ifndef __clang_analyzer__
/* Code not to be analyzed by clang.
*
* Why we do this? Because there is a false positive here:
* libinjection_sqli.c:608:13: warning: Out of bound memory access (access exceeds upper limit of memory block) [alpha.security.ArrayBoundV2]
* if (*ptr != '\\') {
* ^~~~
* Specifically, this function deals with non-null terminated char arrays. This can be added
* as prerequisite, and is not written clearly. But the math in the for below holds.
*/
/*
* Ok! " \" " one backslash = escaped!
* " \\" " two backslash = not escaped!
Expand All @@ -616,6 +624,7 @@ static int is_backslash_escaped(const char* end, const char* start)

return (end - ptr) & 1;
}
#endif

static size_t is_double_delim_escaped(const char* cur, const char* end)
{
Expand Down Expand Up @@ -1066,9 +1075,9 @@ static size_t parse_money(struct libinjection_sqli_state *sf)
}

/* we have $foobar$ ... find it again */
strend = my_memmem(cs+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2);
strend = my_memmem(cs+pos+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2);

if (strend == NULL || ((size_t)(strend - cs) < (pos+xlen+2))) {
if (strend == NULL) {
/* fell off edge */
st_assign(sf->current, TYPE_STRING, pos+xlen+2, slen - pos - xlen - 2, cs+pos+xlen+2);
sf->current->str_open = '$';
Expand Down Expand Up @@ -1197,12 +1206,12 @@ static size_t parse_number(struct libinjection_sqli_state * sf)
* without having to regenerated the SWIG (or other binding) in minor
* releases.
*/
const char* libinjection_version()
const char* libinjection_version(void)
{
return LIBINJECTION_VERSION;
}

int libinjection_sqli_tokenize(struct libinjection_sqli_state * sf)
int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf)
{
pt2Function fnptr;
size_t *pos = &sf->pos;
Expand Down Expand Up @@ -2309,12 +2318,12 @@ int libinjection_is_sqli(struct libinjection_sqli_state * sql_state)
return FALSE;
}

int libinjection_sqli(const char* input, size_t slen, char fingerprint[])
int libinjection_sqli(const char* s, size_t slen, char fingerprint[])
{
int issqli;
struct libinjection_sqli_state state;

libinjection_sqli_init(&state, input, slen, 0);
libinjection_sqli_init(&state, s, slen, 0);
issqli = libinjection_is_sqli(&state);
if (issqli) {
strcpy(fingerprint, state.fingerprint);
Expand Down
23 changes: 16 additions & 7 deletions src/lib/third_party/src/libinjection_xss.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static int is_black_tag(const char* s, size_t len);
static int is_black_url(const char* s, size_t len);
static int cstrcasecmp_with_null(const char *a, const char *b, size_t n);
static int html_decode_char_at(const char* src, size_t len, size_t* consumed);
static int htmlencode_startswith(const char* prefix, const char *src, size_t n);
static int htmlencode_startswith(const char *a/* prefix */, const char *b /* src */, size_t n);


typedef struct stringtype {
Expand Down Expand Up @@ -509,22 +509,31 @@ int libinjection_is_xss(const char* s, size_t len, int flags)

/*
* wrapper
*
*
* const char* s: is expected to be a null terminated string.
* size_t len: should represent the length of the string
* without the null terminator - strlen(s).
*
* Further info:
* - https://github.com/client9/libinjection/issues/150
*
*/
int libinjection_xss(const char* s, size_t len)
int libinjection_xss(const char* s, size_t slen)
{
if (libinjection_is_xss(s, len, DATA_STATE)) {
if (libinjection_is_xss(s, slen, DATA_STATE)) {
return 1;
}
if (libinjection_is_xss(s, len, VALUE_NO_QUOTE)) {
if (libinjection_is_xss(s, slen, VALUE_NO_QUOTE)) {
return 1;
}
if (libinjection_is_xss(s, len, VALUE_SINGLE_QUOTE)) {
if (libinjection_is_xss(s, slen, VALUE_SINGLE_QUOTE)) {
return 1;
}
if (libinjection_is_xss(s, len, VALUE_DOUBLE_QUOTE)) {
if (libinjection_is_xss(s, slen, VALUE_DOUBLE_QUOTE)) {
return 1;
}
if (libinjection_is_xss(s, len, VALUE_BACK_QUOTE)) {
if (libinjection_is_xss(s, slen, VALUE_BACK_QUOTE)) {
return 1;
}

Expand Down

0 comments on commit 0c1d0e9

Please sign in to comment.