Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions apache2/apache2_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ void *create_directory_config(apr_pool_t *mp, char *path)
/* xml external entity */
dcfg->xml_external_entity = NOT_SET;

/* remote addr define */
dcfg->remote_define = NOT_SET_P;

return dcfg;
}

Expand Down Expand Up @@ -598,6 +601,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
merged->xml_external_entity = (child->xml_external_entity == NOT_SET
? parent->xml_external_entity : child->xml_external_entity);

/* remote add define */
merged->remote_define = (child->remote_define == NOT_SET_P
? parent->remote_define : child->remote_define);

return merged;
}

Expand Down Expand Up @@ -721,6 +728,9 @@ void init_directory_config(directory_config *dcfg)
/* xml external entity */
if (dcfg->xml_external_entity == NOT_SET) dcfg->xml_external_entity = 0;

/* remote addr define */
if (dcfg->remote_define == NOT_SET_P) dcfg->remote_define = "default";

}

/**
Expand Down Expand Up @@ -2286,6 +2296,15 @@ static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
return NULL;
}

static const char *cmd_remote_addr_define(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;

dcfg->remote_define = p1;

return NULL;
}

static const char *cmd_sensor_id(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
Expand Down Expand Up @@ -3475,6 +3494,14 @@ const command_rec module_directives[] = {
"id"
),

AP_INIT_TAKE1 (
"SecRemoteAddrDefine",
cmd_remote_addr_define,
NULL,
CMD_SCOPE_MAIN,
"Define a request header field to define remote addr"
),

AP_INIT_TAKE1 (
"SecSensorId",
cmd_sensor_id,
Expand Down
25 changes: 22 additions & 3 deletions apache2/apache2_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
apr_size_t nbytes, nbytes_written;
apr_file_t *debuglog_fd = NULL;
int filter_debug_level = 0;
char *remote = NULL;
char *parse_remote = NULL;
char *saved = NULL;
char *str = NULL;
char str1[1024] = "";
char str2[1256] = "";

Expand Down Expand Up @@ -268,9 +272,24 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->useragent_ip ? r->useragent_ip : r->connection->client_ip, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
#else
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->connection->remote_ip, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
if(strcasecmp(msr->txcfg->remote_define, "default") == 0) {
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->connection->remote_ip, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
} else {
remote = (char *)apr_table_get(msr->r->headers_in, msr->txcfg->remote_define);
if(remote == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->connection->remote_ip, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
} else {
parse_remote = apr_pstrdup(msr->mp, remote);
str = apr_strtok(parse_remote, ",", &saved);
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", str, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
}
}
#endif

/* Add this message to the list. */
Expand Down
89 changes: 54 additions & 35 deletions apache2/libinjection/sqlparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,12 @@ void st_assign_char(stoken_t * st, const char stype, const char value)
void st_assign(stoken_t * st, const char stype, const char *value,
size_t len)
{
size_t last = len < (ST_MAX_SIZE - 1) ? len : (ST_MAX_SIZE - 1);
size_t last = len < ST_MAX_SIZE ? len : (ST_MAX_SIZE - 1);
st->type = stype;
strncpy(st->val, value, last);
memcpy(st->val, value, last);
st->val[last] = CHAR_NULL;
}

void st_assign_cstr(stoken_t * st, const char stype, const char *value)
{
st->type = stype;
strncpy(st->val, value, ST_MAX_SIZE - 1);
st->val[ST_MAX_SIZE - 1] = CHAR_NULL;
}

void st_copy(stoken_t * dest, const stoken_t * src)
{
memcpy(dest, src, sizeof(stoken_t));
Expand Down Expand Up @@ -313,7 +306,7 @@ size_t parse_eol_comment(sfilter * sf)
const char *endpos =
(const char *) memchr((const void *) (cs + pos), '\n', slen - pos);
if (endpos == NULL) {
st_assign_cstr(current, 'c', cs + pos);
st_assign(current, 'c', cs + pos, slen - pos);
return slen;
} else {
st_assign(current, 'c', cs + pos, endpos - cs - pos);
Expand Down Expand Up @@ -404,7 +397,7 @@ size_t parse_slash(sfilter * sf)
/*
* unterminated comment
*/
st_assign_cstr(current, 'c', cs + pos);
st_assign(current, 'c', cs + pos, slen - pos);
return slen;
} else {
/*
Expand Down Expand Up @@ -441,7 +434,7 @@ size_t parse_backslash(sfilter * sf)
size_t pos = sf->pos;

if (pos + 1 < slen && cs[pos + 1] == 'N') {
st_assign_cstr(current, '1', "NULL");
st_assign(current, '1', "NULL", 4);
return pos + 2;
} else {
return parse_other(sf);
Expand Down Expand Up @@ -479,16 +472,16 @@ size_t parse_operator2(sfilter * sf)
/*
* special 3-char operator
*/
st_assign_cstr(current, 'o', "<=>");
st_assign(current, 'o', "<=>", 3);
return pos + 3;
} else if (is_operator2(op2)) {
if (streq(op2, "&&") || streq(op2, "||")) {
st_assign_cstr(current, '&', op2);
st_assign(current, '&', op2, 2);
} else {
/*
* normal 2 char operator
*/
st_assign_cstr(current, 'o', op2);
st_assign(current, 'o', op2, 2);
}
return pos + 2;
} else {
Expand Down Expand Up @@ -530,7 +523,7 @@ size_t parse_string_core(const char *cs, const size_t len, size_t pos,
* string ended with no trailing quote
* assign what we have
*/
st_assign_cstr(st, 's', cs + pos + offset);
st_assign(st, 's', cs + pos + offset, len - pos - offset);
st->str_close = CHAR_NULL;
return len;
} else if (*(qpos - 1) != '\\') {
Expand Down Expand Up @@ -639,6 +632,30 @@ size_t parse_var(sfilter * sf)
}
}

size_t parse_money(sfilter *sf)
{
stoken_t *current = &sf->syntax_current;
const char *cs = sf->s;
const size_t slen = sf->slen;
size_t pos = sf->pos;
size_t xlen;

/*
* $1,000.00 or $1.000,00 ok!
* This also parses $....,,,111 but that's ok
*/
xlen = strlenspn(cs + pos + 1, slen - pos - 1, "0123456789.,");
if (xlen == 0) {
/*
* just ignore '$'
*/
return pos + 1;
} else {
st_assign(current, '1', cs + pos, 1 + xlen);
return pos + 1 + xlen;
}
}

size_t parse_number(sfilter * sf)
{
stoken_t *current = &sf->syntax_current;
Expand All @@ -655,7 +672,7 @@ size_t parse_number(sfilter * sf)
xlen =
strlenspn(cs + pos + 2, slen - pos - 2, "0123456789ABCDEFabcdef");
if (xlen == 0) {
st_assign_cstr(current, 'n', "0X");
st_assign(current, 'n', "0X", 2);
return pos + 2;
} else {
st_assign(current, '1', cs + pos, 2 + xlen);
Expand All @@ -664,10 +681,10 @@ size_t parse_number(sfilter * sf)
}

start = pos;
while (isdigit(cs[pos])) {
while (pos < slen && isdigit(cs[pos])) {
pos += 1;
}
if (cs[pos] == '.') {
if (pos < slen && cs[pos] == '.') {
pos += 1;
while (pos < slen && isdigit(cs[pos])) {
pos += 1;
Expand All @@ -678,23 +695,25 @@ size_t parse_number(sfilter * sf)
}
}

if (cs[pos] == 'E' || cs[pos] == 'e') {
pos += 1;
if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) {
pos += 1;
}
while (isdigit(cs[pos])) {
if (pos < slen) {
if (cs[pos] == 'E' || cs[pos] == 'e') {
pos += 1;
if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) {
pos += 1;
}
while (pos < slen && isdigit(cs[pos])) {
pos += 1;
}
} else if (isalpha(cs[pos])) {
/*
* oh no, we have something like '6FOO'
* use microsoft style parsing and take just
* the number part and leave the rest to be
* parsed later
*/
st_assign(current, '1', cs + start, pos - start);
return pos;
}
} else if (isalpha(cs[pos])) {
/*
* oh no, we have something like '6FOO'
* use microsoft style parsing and take just
* the number part and leave the rest to be
* parsed later
*/
st_assign(current, '1', cs + start, pos - start);
return pos;
}

st_assign(current, '1', cs + start, pos - start);
Expand Down Expand Up @@ -895,7 +914,7 @@ int sqli_tokenize(sfilter * sf, stoken_t * sout)
*/
if (last->type == 'n' && !cstrcasecmp(last->val, "IN")) {
st_copy(last, current);
st_assign_cstr(sout, 'f', "IN");
st_assign(sout, 'f', "IN", 2);
return TRUE;
} else {
/*
Expand Down
2 changes: 1 addition & 1 deletion apache2/libinjection/sqlparse_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ static const pt2Function char_parse_map[] = {
&parse_operator2, /* 33 */
&parse_string, /* 34 */
&parse_eol_comment, /* 35 */
&parse_white, /* 36 */
&parse_money, /* 36 */
&parse_operator1, /* 37 */
&parse_operator2, /* 38 */
&parse_string, /* 39 */
Expand Down
1 change: 1 addition & 0 deletions apache2/libinjection/sqlparse_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ int is_operator2(const char *key);
int is_sqli_pattern(const char *key);

size_t parse_none(sfilter * sf);
size_t parse_money(sfilter * sf);
size_t parse_other(sfilter * sf);
size_t parse_white(sfilter * sf);
size_t parse_operator1(sfilter *sf);
Expand Down
5 changes: 4 additions & 1 deletion apache2/modsecurity.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ struct directory_config {

/* Hash */
apr_array_header_t *hash_method;
const char *crypto_key;
const char *crypto_key;
int crypto_key_len;
const char *crypto_param_name;
int hash_is_enabled;
Expand All @@ -598,6 +598,9 @@ struct directory_config {

/* xml */
int xml_external_entity;

/* remote addr */
const char *remote_define;
};

struct error_message_t {
Expand Down
32 changes: 30 additions & 2 deletions apache2/re_variables.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,13 +700,41 @@ static int var_useragent_ip_generate(modsec_rec *msr, msre_var *var, msre_rule *
static int var_remote_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
apr_table_t *vartab, apr_pool_t *mptmp)
{
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
char *remote = NULL;
char *parse_remote = NULL;
char *saved = NULL;
char *str = NULL;

if(strcasecmp(msr->txcfg->remote_define, "default") == 0) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "Set variable \"%s\" to \"%s\".", var->name, msr->remote_addr);
}
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
} else {
remote = (char *)apr_table_get(msr->r->headers_in, msr->txcfg->remote_define);
if(remote == NULL) {
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "Request header \"%s\" not present setting variable \"%s\" to \"%s\".", msr->txcfg->remote_define,
var->name, msr->remote_addr);
}
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
} else {
parse_remote = apr_pstrdup(msr->mp, remote);
str = apr_strtok(parse_remote, ",", &saved);
msr->remote_addr = apr_pstrdup(msr->mp, str);
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "Request header \"%s\" is present setting variable \"%s\" to \"%s\".", msr->txcfg->remote_define,
var->name, msr->remote_addr);
}
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
}
}
}

/* REMOTE_HOST */

static int var_remote_host_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
apr_table_t *vartab, apr_pool_t *mptmp)
apr_table_t *vartab, apr_pool_t *mptmp)
{
const char *value1 = ap_get_remote_host(msr->r->connection, msr->r->per_dir_config,
REMOTE_NAME, NULL);
Expand Down