mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Improvements, fixes and new features
This commit is contained in:
parent
4f1ab2f713
commit
49732256f6
@ -42,9 +42,9 @@
|
||||
* Data structures for acmp parser
|
||||
*/
|
||||
|
||||
/**
|
||||
* One node in trie
|
||||
*/
|
||||
/**
|
||||
* One node in trie
|
||||
*/
|
||||
typedef struct acmp_node_t acmp_node_t;
|
||||
typedef struct acmp_btree_node_t acmp_btree_node_t;
|
||||
struct acmp_node_t {
|
||||
@ -79,9 +79,9 @@ struct acmp_btree_node_t {
|
||||
* Data related to parser, not to individual nodes
|
||||
*/
|
||||
struct ACMP {
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
int is_utf8;
|
||||
#endif
|
||||
#endif
|
||||
int is_case_sensitive;
|
||||
apr_pool_t *parent_pool;
|
||||
apr_pool_t *pool;
|
||||
@ -188,11 +188,11 @@ static long utf8_lcase(acmp_utf8_char_t ucs_code) {
|
||||
* Returns length of given string for parser's encoding
|
||||
*/
|
||||
static size_t acmp_strlen(ACMP *parser, const char *str) {
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
return (parser->is_utf8 == 0) ? strlen(str) : utf8_strlen(str);
|
||||
#else
|
||||
#else
|
||||
return strlen(str);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,14 +205,14 @@ static void acmp_strtoucs(ACMP *parser, const char *str, acmp_utf8_char_t *ucs_c
|
||||
int i;
|
||||
const char *c = str;
|
||||
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
if (parser->is_utf8) {
|
||||
for (i = 0; i < len; i++) {
|
||||
*(ucs_chars++) = utf8_decodechar(c);
|
||||
c += utf8_seq_len(c);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
for (i = 0; i < len; i++) {
|
||||
*(ucs_chars++) = *(c++);
|
||||
@ -341,7 +341,7 @@ static void acmp_connect_other_matches(ACMP *parser, acmp_node_t *node) {
|
||||
* Adds leaves to binary tree, working from sorted array of keyword tree nodes
|
||||
*/
|
||||
static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
|
||||
int pos, int lb, int rb, apr_pool_t *pool) {
|
||||
int pos, int lb, int rb, apr_pool_t *pool) {
|
||||
|
||||
int left = 0, right = 0;
|
||||
if ((pos - lb) > 1) {
|
||||
@ -350,9 +350,9 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
|
||||
/* ENH: Check alloc succeded */
|
||||
node->left->node = nodes[left];
|
||||
node->left->letter = nodes[left]->letter;
|
||||
#ifdef DEBUG_ACMP
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "%lc ->left %lc\n", (wint_t)node->node->letter, (wint_t)node->left->node->letter);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if ((rb - pos) > 1) {
|
||||
right = pos + (rb - pos) / 2;
|
||||
@ -360,9 +360,9 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
|
||||
/* ENH: Check alloc succeded */
|
||||
node->right->node = nodes[right];
|
||||
node->right->letter = nodes[right]->letter;
|
||||
#ifdef DEBUG_ACMP
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "%lc ->right %lc\n", (wint_t)node->node->letter, (wint_t)node->right->node->letter);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (node->right != NULL) {
|
||||
acmp_add_btree_leaves(node->right, nodes, right, pos, rb, pool);
|
||||
@ -436,9 +436,9 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
||||
for (child = parser->root_node->child; child != NULL; child = child->sibling) {
|
||||
child->fail = parser->root_node;
|
||||
*(acmp_node_t **)apr_array_push(arr) = child;
|
||||
#ifdef DEBUG_ACMP
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "fail direction: *%s* => *%s*\n", child->text, child->fail->text);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@ -449,9 +449,9 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
||||
goto_node = acmp_child_for_code(node->parent->fail, node->letter);
|
||||
node->fail = (goto_node != NULL) ? goto_node : parser->root_node;
|
||||
}
|
||||
#ifdef DEBUG_ACMP
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "fail direction: *%s* => *%s*\n", node->text, node->fail->text);
|
||||
#endif
|
||||
#endif
|
||||
child = node->child;
|
||||
while (child != NULL) {
|
||||
*(acmp_node_t **)apr_array_push(arr2) = child;
|
||||
@ -486,8 +486,8 @@ static void acmp_clear_hit_count_recursive(acmp_node_t *node) {
|
||||
static void acmp_found(ACMP *parser, acmp_node_t *node) {
|
||||
if (node->callback) {
|
||||
node->callback(parser, node->callback_data,
|
||||
parser->bp_buffer[(parser->char_pos - node->depth - 1) % parser->bp_buff_len],
|
||||
parser->char_pos - node->depth - 1);
|
||||
parser->bp_buffer[(parser->char_pos - node->depth - 1) % parser->bp_buff_len],
|
||||
parser->char_pos - node->depth - 1);
|
||||
}
|
||||
node->hit_count++;
|
||||
parser->hit_count++;
|
||||
@ -516,9 +516,9 @@ ACMP *acmp_create(int flags, apr_pool_t *pool) {
|
||||
/* ENH: Check alloc succeded */
|
||||
parser->pool = p;
|
||||
parser->parent_pool = pool;
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
parser->is_utf8 = (flags & ACMP_FLAG_UTF8) == 0 ? 0 : 1;
|
||||
#endif
|
||||
#endif
|
||||
parser->is_case_sensitive = (flags & ACMP_FLAG_CASE_SENSITIVE) == 0 ? 0 : 1;
|
||||
parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
|
||||
/* ENH: Check alloc succeded */
|
||||
@ -554,9 +554,9 @@ ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool) {
|
||||
/* ENH: Check alloc succeded */
|
||||
new_parser->pool = p;
|
||||
new_parser->parent_pool = pool;
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
new_parser->is_utf8 = parser->is_utf8;
|
||||
#endif
|
||||
#endif
|
||||
new_parser->is_case_sensitive = parser->is_case_sensitive;
|
||||
new_parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
|
||||
/* ENH: Check alloc succeded */
|
||||
@ -596,7 +596,7 @@ apr_status_t acmp_prepare(ACMP *parser) {
|
||||
* len - Length of pattern in characters, if zero string length is used.
|
||||
*/
|
||||
apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
|
||||
acmp_callback_t callback, void *data, apr_size_t len)
|
||||
acmp_callback_t callback, void *data, apr_size_t len)
|
||||
{
|
||||
size_t length, i, j;
|
||||
acmp_utf8_char_t *ucs_chars;
|
||||
@ -654,9 +654,9 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
|
||||
*/
|
||||
apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
|
||||
acmp_node_t *node, *go_to;
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
apr_size_t seq_length;
|
||||
#endif
|
||||
#endif
|
||||
const char *end;
|
||||
|
||||
if (parser->is_failtree_done == 0) acmp_prepare(parser);
|
||||
@ -668,7 +668,7 @@ apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
|
||||
acmp_utf8_char_t letter;
|
||||
|
||||
parser->bp_buffer[parser->char_pos % parser->bp_buff_len] = parser->byte_pos;
|
||||
#ifdef ACMP_USE_UTF8
|
||||
#ifdef ACMP_USE_UTF8
|
||||
if (parser->is_utf8) {
|
||||
if (parser->u8buff_len > 0) {
|
||||
/* Resuming partial utf-8 sequence */
|
||||
@ -697,7 +697,7 @@ apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
letter = *data++;
|
||||
parser->byte_pos++;
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ACMP_H_
|
||||
#define ACMP_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _APACHE2_H_
|
||||
#define _APACHE2_H_
|
||||
|
||||
|
@ -12,10 +12,11 @@
|
||||
* distribution.
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Breach Security, Inc.
|
||||
* directly using the email address support@breach.com.
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "modsecurity.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <util_filter.h>
|
||||
|
||||
#include "modsecurity.h"
|
||||
@ -518,14 +519,14 @@ static int flatten_response_body(modsec_rec *msr) {
|
||||
msr->resbody_data = apr_palloc(msr->mp, msr->resbody_length + 1);
|
||||
if (msr->resbody_data == NULL) {
|
||||
msr_log(msr, 1, "Output filter: Response body data memory allocation failed. Asked for: %" APR_SIZE_T_FMT,
|
||||
msr->resbody_length + 1);
|
||||
msr->resbody_length + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = apr_brigade_flatten(msr->of_brigade, msr->resbody_data, &msr->resbody_length);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", rc,
|
||||
get_apr_error(msr->mp, rc));
|
||||
get_apr_error(msr->mp, rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -533,16 +534,16 @@ static int flatten_response_body(modsec_rec *msr) {
|
||||
msr->resbody_status = RESBODY_STATUS_READ;
|
||||
|
||||
if (msr->txcfg->stream_outbody_inspection) {
|
||||
msr->stream_output_data = (char *)malloc(msr->resbody_length+1);
|
||||
msr->stream_output_length = msr->resbody_length+1;
|
||||
msr->stream_output_data = (char *)calloc(sizeof(char),msr->resbody_length+1);
|
||||
msr->stream_output_length = msr->resbody_length+1;
|
||||
|
||||
if (msr->stream_output_data == NULL) {
|
||||
msr_log(msr, 1, "Output filter: Stream Response body data memory allocation failed. Asked for: %" APR_SIZE_T_FMT,
|
||||
msr->stream_output_length + 1);
|
||||
return -1;
|
||||
}
|
||||
if (msr->stream_output_data == NULL) {
|
||||
msr_log(msr, 1, "Output filter: Stream Response body data memory allocation failed. Asked for: %" APR_SIZE_T_FMT,
|
||||
msr->stream_output_length + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
apr_cpystrn(msr->stream_output_data,msr->resbody_data,msr->stream_output_length);
|
||||
apr_cpystrn(msr->stream_output_data,msr->resbody_data,msr->stream_output_length);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include "apache2.h"
|
||||
#include "http_core.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "http_core.h"
|
||||
@ -24,6 +25,7 @@
|
||||
#include "modsecurity.h"
|
||||
#include "apache2.h"
|
||||
#include "http_main.h"
|
||||
#include "http_connection.h"
|
||||
|
||||
#include "apr_optional.h"
|
||||
#include "mod_log_config.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "apr_global_mutex.h"
|
||||
@ -371,6 +372,11 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
|
||||
msr->request_cookies = apr_table_make(msr->mp, 16);
|
||||
if (msr->request_cookies == NULL) return -1;
|
||||
|
||||
/* Initialize matched vars */
|
||||
msr->matched_vars = apr_table_make(msr->mp, 8);
|
||||
if (msr->matched_vars == NULL) return -1;
|
||||
apr_table_clear(msr->matched_vars);
|
||||
|
||||
/* Locate the cookie headers and parse them */
|
||||
arr = apr_table_elts(msr->request_headers);
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
@ -473,6 +479,7 @@ static apr_status_t modsecurity_process_phase_request_headers(modsec_rec *msr) {
|
||||
static apr_status_t modsecurity_process_phase_request_body(modsec_rec *msr) {
|
||||
apr_time_t time_before;
|
||||
apr_status_t rc = 0;
|
||||
|
||||
|
||||
if ((msr->allow_scope == ACTION_ALLOW_REQUEST)||(msr->allow_scope == ACTION_ALLOW)) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MODSECURITY_H_
|
||||
#define _MODSECURITY_H_
|
||||
|
||||
@ -386,6 +387,9 @@ struct modsec_rec {
|
||||
*/
|
||||
unsigned int allow_scope;
|
||||
|
||||
/* matched vars */
|
||||
apr_table_t *matched_vars;
|
||||
|
||||
/* Generic request body processor context to be used by custom parsers. */
|
||||
void *reqbody_processor_ctx;
|
||||
};
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "msc_geo.h"
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_GEO_H_
|
||||
#define _MSC_GEO_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_GSB_H_
|
||||
#define _MSC_GSB_H_
|
||||
|
||||
@ -32,6 +33,4 @@ struct gsb_db {
|
||||
|
||||
int DSOLOCAL gsb_mal_init(directory_config *dcfg, const char *dbfn, char **error_msg);
|
||||
|
||||
//int DSOLOCAL gsb_mal_lookup(modsec_rec *msr, const char *target, char **error_msg);
|
||||
|
||||
#endif
|
||||
|
@ -17,8 +17,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "modsecurity_config.h"
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "re.h"
|
||||
@ -1125,8 +1124,27 @@ void sec_audit_logger(modsec_rec *msr) {
|
||||
}
|
||||
|
||||
/* AUDITLOG_PART_UPLOADS */
|
||||
/* ENH: Implement */
|
||||
if ((strchr(msr->txcfg->auditlog_parts, AUDITLOG_PART_UPLOADS) != NULL) && (msr->mpd != NULL)) {
|
||||
text = apr_psprintf(msr->mp, "\n--%s-%c--\n", msr->new_auditlog_boundary, AUDITLOG_PART_UPLOADS);
|
||||
sec_auditlog_write(msr, text, strlen(text));
|
||||
|
||||
multipart_part **parts = NULL;
|
||||
unsigned int total_size = 0;
|
||||
int cfiles = 0;
|
||||
|
||||
parts = (multipart_part **)msr->mpd->parts->elts;
|
||||
for(cfiles = 0; cfiles < msr->mpd->parts->nelts; cfiles++) {
|
||||
if (parts[cfiles]->type == MULTIPART_FILE) {
|
||||
if(parts[cfiles]->filename != NULL) {
|
||||
text = apr_psprintf(msr->mp, "#%d Filename: %s - Size: %u - ContentType: %s\n", cfiles, log_escape_nq(msr->mp, parts[cfiles]->filename), parts[cfiles]->tmp_file_size, log_escape_nq(msr->mp, parts[cfiles]->content_type ? parts[cfiles]->content_type : "<Unknown ContentType>"));
|
||||
sec_auditlog_write(msr, text, strlen(text));
|
||||
total_size += parts[cfiles]->tmp_file_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
text = apr_psprintf(msr->mp, "Total upload size: %u\n", total_size);
|
||||
sec_auditlog_write(msr, text, strlen(text));
|
||||
}
|
||||
|
||||
/* AUDITLOG_PART_MATCHEDRULES */
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_LOGGING_H_
|
||||
#define _MSC_LOGGING_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
|
||||
#include "msc_lua.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
|
||||
#ifndef _MSC_LUA_H_
|
||||
|
@ -16,8 +16,8 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity_config.h"
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_MULTIPART_H_
|
||||
#define _MSC_MULTIPART_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "msc_parsers.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_PARSERS_H_
|
||||
#define _MSC_PARSERS_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "msc_pcre.h"
|
||||
#include "apr_strings.h"
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_PCRE_H_
|
||||
#define _MSC_PCRE_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_RELEASE_H_
|
||||
#define _MSC_RELEASE_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include "re.h"
|
||||
#include "msc_parsers.h"
|
||||
@ -400,7 +401,7 @@ static apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, char **e
|
||||
|
||||
msr->stream_input_length = msr->msc_reqbody_length;
|
||||
|
||||
msr->stream_input_data = malloc(msr->stream_input_length + 1);
|
||||
msr->stream_input_data = (char *)calloc(sizeof(char), msr->stream_input_length + 1);
|
||||
if (msr->stream_input_data== NULL) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Unable to allocate memory to hold request body on stream. Asked for %u bytes.",
|
||||
msr->stream_input_length + 1);
|
||||
|
@ -16,8 +16,8 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity_config.h"
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "msc_xml.h"
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSC_XML_H_
|
||||
#define _MSC_XML_H_
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "persist_dbm.h"
|
||||
#include "apr_sdbm.h"
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PERSIST_DBM_H_
|
||||
#define _PERSIST_DBM_H_
|
||||
|
||||
|
42
apache2/re.c
42
apache2/re.c
@ -12,10 +12,11 @@
|
||||
* distribution.
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Breach Security, Inc.
|
||||
* directly using the email address support@breach.com.
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "re.h"
|
||||
@ -918,6 +919,8 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
msr_log(msr, 9, "This phase consists of %d rule(s).", arr->nelts);
|
||||
}
|
||||
|
||||
apr_table_clear(msr->matched_vars);
|
||||
|
||||
/* Loop through the rules in the selected set. */
|
||||
skip = 0;
|
||||
skipped = 0;
|
||||
@ -1116,6 +1119,7 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
}
|
||||
}
|
||||
|
||||
apr_table_clear(msr->matched_vars);
|
||||
skipped = 0;
|
||||
saw_starter = 0;
|
||||
}
|
||||
@ -1152,6 +1156,7 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
|
||||
}
|
||||
|
||||
apr_table_clear(msr->matched_vars);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1205,7 +1210,9 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
else if (rc < 0) {
|
||||
msr_log(msr, 1, "Rule processing failed.");
|
||||
|
||||
|
||||
if (msr->txcfg->reqintercept_oe == 1) {
|
||||
apr_table_clear(msr->matched_vars);
|
||||
return -1;
|
||||
} else {
|
||||
if (rule->actionset->is_chained) {
|
||||
@ -1226,18 +1233,20 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
}
|
||||
}
|
||||
|
||||
apr_table_clear(msr->matched_vars);
|
||||
skipped = 0;
|
||||
saw_starter = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
msr_log(msr, 1, "Rule processing failed with unknown return code: %d.", rc);
|
||||
apr_table_clear(msr->matched_vars);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ENH warn if chained rules are missing. */
|
||||
|
||||
apr_table_clear(msr->matched_vars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1831,6 +1840,7 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
|
||||
apr_time_t time_before_op = 0;
|
||||
char *my_error_msg = NULL;
|
||||
const char *full_varname = NULL;
|
||||
char *parm = NULL;
|
||||
int rc;
|
||||
|
||||
/* determine the full var name if not already resolved
|
||||
@ -1920,6 +1930,32 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
|
||||
msr->matched_var->value = apr_pmemdup(msr->mp, var->value, var->value_len);
|
||||
msr->matched_var->value_len = var->value_len;
|
||||
|
||||
parm = strchr(msr->matched_var->name,':');
|
||||
|
||||
if(parm) {
|
||||
parm++;
|
||||
|
||||
msc_string *mvar = apr_palloc(msr->mp, sizeof(msc_string));
|
||||
mvar->name = apr_pstrdup(msr->mp, parm);
|
||||
mvar->name_len = strlen(mvar->name);
|
||||
mvar->value = apr_pmemdup(msr->mp, var->value, var->value_len);
|
||||
mvar->value_len = var->value_len;
|
||||
|
||||
apr_table_unset(msr->matched_vars, parm);
|
||||
apr_table_setn(msr->matched_vars, parm, (void *)mvar);
|
||||
|
||||
} else {
|
||||
|
||||
msc_string *mvar = apr_palloc(msr->mp, sizeof(msc_string));
|
||||
mvar->name = apr_pstrdup(msr->mp, var->name);
|
||||
mvar->name_len = strlen(mvar->name);
|
||||
mvar->value = apr_pmemdup(msr->mp, var->value, var->value_len);
|
||||
mvar->value_len = var->value_len;
|
||||
|
||||
apr_table_unset(msr->matched_vars, mvar->name);
|
||||
apr_table_setn(msr->matched_vars, mvar->name, (void *)mvar);
|
||||
}
|
||||
|
||||
/* Keep track of the highest severity matched so far */
|
||||
if ((acting_actionset->severity > 0) && (acting_actionset->severity < msr->highest_severity))
|
||||
{
|
||||
|
@ -190,6 +190,8 @@ struct msre_rule {
|
||||
|
||||
ap_regex_t *sub_regex;
|
||||
char *sub_str;
|
||||
char *re_str;
|
||||
int re_precomp;
|
||||
|
||||
msre_ipmatch *ip_op;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2008 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2010 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "re.h"
|
||||
#include <ctype.h>
|
||||
#include "apr_lib.h"
|
||||
@ -572,6 +573,34 @@ static apr_status_t msre_action_redirect_execute(modsec_rec *msr, apr_pool_t *mp
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* tag */
|
||||
|
||||
/*
|
||||
* \brief Execution function to tag action
|
||||
*
|
||||
* \param msr Pointer internal modsec request structure
|
||||
* \param mptmp Pointer to memory pool
|
||||
* \param rule Pointer to the rule
|
||||
* \param action Pointer to action structure
|
||||
*
|
||||
* \retval 1 On Success
|
||||
*/
|
||||
static apr_status_t msre_action_tag_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
msre_rule *rule, msre_action *action)
|
||||
{
|
||||
msc_string *var = NULL;
|
||||
|
||||
var = apr_pcalloc(mptmp, sizeof(msc_string));
|
||||
if (var == NULL) return -1;
|
||||
var->value = (char *)action->param;
|
||||
var->value_len = strlen(var->value);
|
||||
expand_macros(msr, var, rule, mptmp);
|
||||
|
||||
action->param = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* proxy */
|
||||
|
||||
static char *msre_action_proxy_validate(msre_engine *engine, msre_action *action) {
|
||||
@ -2355,6 +2384,19 @@ void msre_engine_register_default_actions(msre_engine *engine) {
|
||||
);
|
||||
|
||||
/* sanitiseMatchedBytes */
|
||||
msre_engine_action_register(engine,
|
||||
"sanitiseMatchedBytes",
|
||||
ACTION_NON_DISRUPTIVE,
|
||||
0, 1,
|
||||
NO_PLUS_MINUS,
|
||||
ACTION_CARDINALITY_MANY,
|
||||
ACTION_CGROUP_NONE,
|
||||
NULL,
|
||||
msre_action_sanitizeMatchedBytes_init,
|
||||
msre_action_sanitizeMatched_execute
|
||||
);
|
||||
|
||||
/* sanitizeMatchedBytes */
|
||||
msre_engine_action_register(engine,
|
||||
"sanitizeMatchedBytes",
|
||||
ACTION_NON_DISRUPTIVE,
|
||||
@ -2586,7 +2628,7 @@ void msre_engine_register_default_actions(msre_engine *engine) {
|
||||
ACTION_CGROUP_NONE,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
msre_action_tag_execute
|
||||
);
|
||||
|
||||
/* prepend */
|
||||
|
@ -16,13 +16,19 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "re.h"
|
||||
#include "msc_pcre.h"
|
||||
#include "msc_geo.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_strmatch.h"
|
||||
#include "acmp.h"
|
||||
#if defined(WIN32) || defined(WINNT)
|
||||
#include "pcre.h"
|
||||
#else
|
||||
#include <regex.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define PARSE_REGEX_IP "([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(?:(\\/[0-9]+))?|([0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+\\:[0-9a-f]+)(?:(\\/[0-9]+))?"
|
||||
#define MAX_SUBSTRINGS 30
|
||||
@ -79,6 +85,15 @@ static int msre_op_nomatch_execute(modsec_rec *msr, msre_rule *rule,
|
||||
/* ipmatch */
|
||||
|
||||
#if !defined(WIN32) || !defined(WINNT)
|
||||
/*
|
||||
* \brief Init function to ipmatch operator
|
||||
*
|
||||
* \param rule Pointer to the rule
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval 1 On Success
|
||||
* \retval 0 On Fail
|
||||
*/
|
||||
static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
@ -103,6 +118,9 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
||||
unsigned long ipmask = 0, network = 0, hostmask = 0, broadcast = 0;
|
||||
int maskbits = 0;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
parse_regex = pcre_compile(PARSE_REGEX_IP, opts, &eb, &eo, NULL);
|
||||
|
||||
if(parse_regex == NULL) {
|
||||
@ -394,6 +412,18 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Execution function to ipmatch operator
|
||||
*
|
||||
* \param msr Pointer internal modsec request structure
|
||||
* \param rule Pointer to the rule
|
||||
* \param var Pointer to variable structure
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval -1 On Failure
|
||||
* \retval 1 On Match
|
||||
* \retval 0 On No Match
|
||||
*/
|
||||
static int msre_op_ipmatch_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
@ -403,13 +433,16 @@ static int msre_op_ipmatch_execute(modsec_rec *msr, msre_rule *rule, msre_var *v
|
||||
int i;
|
||||
msre_ipmatch *ipdata = rule->ip_op;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if(var == NULL || (strcmp(var->name,"REMOTE_ADDR") != 0 ) || (strcmp(var->name,"SERVER_ADDR") != 0 )) {
|
||||
msr_log(msr,9,"Operator ipmatch only works with REMOTE_ADDR and SERVER_ADDR variable");
|
||||
return -1;
|
||||
*error_msg = "Internal Error: Operator ipmatch only works with REMOTE_ADDR and SERVER_ADDR variable.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(ipdata == NULL) {
|
||||
msr_log(msr,9,"Ipmatch operator struct is NULL");
|
||||
*error_msg = "Internal Error: ipmatch is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -469,6 +502,36 @@ static int msre_op_ipmatch_execute(modsec_rec *msr, msre_rule *rule, msre_var *v
|
||||
|
||||
/* rsub */
|
||||
|
||||
static char *remove_escape(msre_rule *rule, char *str, int len) {
|
||||
char *parm = apr_palloc(rule->ruleset->mp, len);;
|
||||
char *ret = parm;
|
||||
|
||||
for(;*str!='\0';str++) {
|
||||
if(*str != '\\') {
|
||||
*parm++ = *str;
|
||||
} else {
|
||||
str++;
|
||||
if(*str != '/') {
|
||||
str--;
|
||||
*parm++ = *str;
|
||||
} else {
|
||||
*parm++ = *str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Init function to rsub operator
|
||||
*
|
||||
* \param rule Pointer to the rule
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval 1 On Success
|
||||
* \retval 0 On Fail
|
||||
*/
|
||||
static int msre_op_rsub_param_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
@ -477,15 +540,20 @@ static int msre_op_rsub_param_init(msre_rule *rule, char **error_msg) {
|
||||
const char *line = NULL;
|
||||
char *reg_pattern = NULL;
|
||||
char *replace = NULL;
|
||||
char *e_pattern = NULL;
|
||||
char *e_replace = NULL;
|
||||
char *flags = NULL;
|
||||
char *data;
|
||||
char *data = NULL;
|
||||
char delim;
|
||||
int ignore_case = 0;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
line = rule->op_param;
|
||||
|
||||
if (apr_tolower(*line) != 's') {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error rsub operator format, must be s/// pattern",
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error rsub operator format, must be s/ pattern",
|
||||
erroffset, errptr);
|
||||
return 0;
|
||||
}
|
||||
@ -495,30 +563,59 @@ static int msre_op_rsub_param_init(msre_rule *rule, char **error_msg) {
|
||||
if (delim)
|
||||
reg_pattern = ++data;
|
||||
if (reg_pattern) {
|
||||
|
||||
if (*data != delim) {
|
||||
while (*++data && *data != delim);
|
||||
for(;*data != '\0' ;data++) {
|
||||
if(*data == delim) {
|
||||
data--;
|
||||
if(*data == '\\') {
|
||||
data++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*data) {
|
||||
*data = '\0';
|
||||
replace = ++data;
|
||||
}
|
||||
}
|
||||
if (replace) {
|
||||
if (*data != delim) {
|
||||
while (*++data && *data != delim);
|
||||
}
|
||||
if (*data) {
|
||||
*data = '\0';
|
||||
flags = ++data;
|
||||
*++data = '\0';
|
||||
++data;
|
||||
replace = data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!delim || !reg_pattern || !*reg_pattern || !replace) {
|
||||
if (replace) {
|
||||
|
||||
if (*data != delim) {
|
||||
for(;*data != '\0' ;data++) {
|
||||
if(*data == delim) {
|
||||
data--;
|
||||
if(*data == '\\') {
|
||||
data++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*data) {
|
||||
*++data = '\0';
|
||||
flags = ++data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!delim || !reg_pattern || !replace) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error rsub operator format - must be s/regex/str/[flags]",
|
||||
erroffset, errptr);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
e_pattern = remove_escape(rule, reg_pattern, strlen(reg_pattern));
|
||||
e_replace = remove_escape(rule, replace, strlen(replace));
|
||||
|
||||
if (flags) {
|
||||
while (*flags) {
|
||||
delim = apr_tolower(*flags);
|
||||
@ -531,21 +628,37 @@ static int msre_op_rsub_param_init(msre_rule *rule, char **error_msg) {
|
||||
}
|
||||
}
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
pattern = apr_pstrdup(rule->ruleset->mp, e_pattern);
|
||||
rule->sub_str = apr_pstrdup(rule->ruleset->mp, e_replace);
|
||||
|
||||
pattern = apr_pstrdup(rule->ruleset->mp, reg_pattern);
|
||||
rule->sub_str = apr_pstrdup(rule->ruleset->mp, replace);
|
||||
if(strstr(pattern,"%{") == NULL) {
|
||||
regex = ap_pregcomp(rule->ruleset->mp, pattern, AP_REG_EXTENDED |
|
||||
(ignore_case ? AP_REG_ICASE : 0));
|
||||
rule->sub_regex = regex;
|
||||
} else {
|
||||
rule->re_precomp = 1;
|
||||
rule->re_str = apr_pstrdup(rule->ruleset->mp, reg_pattern);
|
||||
rule->sub_regex = NULL;
|
||||
}
|
||||
|
||||
regex = ap_pregcomp(rule->ruleset->mp, pattern, AP_REG_EXTENDED |
|
||||
(ignore_case ? AP_REG_ICASE : 0));
|
||||
|
||||
rule->sub_regex = regex;
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Execution function to rsub operator
|
||||
*
|
||||
* \param msr Pointer internal modsec request structure
|
||||
* \param rule Pointer to the rule
|
||||
* \param var Pointer to variable structure
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval -1 On Failure
|
||||
* \retval 1 On Match
|
||||
* \retval 0 On No Match
|
||||
*/
|
||||
static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
ap_regex_t *regex = rule->sub_regex;
|
||||
msc_string *str = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
msc_string *re_pattern = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
char *offset = NULL;
|
||||
int sub = 0, so = 0, p_len = 0;
|
||||
char *replace = NULL;
|
||||
@ -554,6 +667,8 @@ static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
int output_body = 0, input_body = 0, count = 0;
|
||||
ap_regmatch_t pmatch[AP_MAX_REG_MATCH];
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if(strcmp(var->name,"STREAM_OUTPUT_BODY") == 0 ) {
|
||||
output_body = 1;
|
||||
@ -564,11 +679,37 @@ static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return -1;
|
||||
}
|
||||
|
||||
replace = apr_pstrdup(rule->ruleset->mp, rule->sub_str);;
|
||||
if(rule->re_precomp == 1) {
|
||||
re_pattern->value = (char *)rule->re_str;
|
||||
re_pattern->value_len = strlen(re_pattern->value);
|
||||
|
||||
expand_macros(msr, re_pattern, rule, msr->mp);
|
||||
|
||||
if(strlen(re_pattern->value) > 0)
|
||||
rule->sub_regex = ap_pregcomp(rule->ruleset->mp, re_pattern->value, AP_REG_EXTENDED);
|
||||
else
|
||||
rule->sub_regex = NULL;
|
||||
|
||||
rule->re_precomp = 0;
|
||||
}
|
||||
|
||||
if(rule->sub_regex == NULL) {
|
||||
*error_msg = "Internal Error: regex data is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
str->value = (char *)rule->sub_str;
|
||||
str->value_len = strlen(str->value);
|
||||
|
||||
expand_macros(msr, str, rule, msr->mp);
|
||||
|
||||
replace = apr_pstrdup(rule->ruleset->mp, str->value);
|
||||
data = apr_pcalloc(msr->mp, var->value_len+(AP_MAX_REG_MATCH*strlen(replace))+1);
|
||||
|
||||
if(replace == NULL || data == NULL)
|
||||
return 0;
|
||||
if(replace == NULL || data == NULL) {
|
||||
*error_msg = "Internal Error: cannot allocate memory";
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(data,var->value,var->value_len);
|
||||
size += (AP_MAX_REG_MATCH*strlen(replace)+2);
|
||||
@ -585,7 +726,7 @@ static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
offset = offset + p_len - 2;
|
||||
}
|
||||
|
||||
sub = pmatch [1].rm_so;
|
||||
sub = -1;
|
||||
|
||||
for (offset = data; !ap_regexec(rule->sub_regex, offset, 1, pmatch, 0); ) {
|
||||
p_len = pmatch [0].rm_eo - pmatch [0].rm_so;
|
||||
@ -595,6 +736,7 @@ static int msre_op_rsub_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
memmove (offset + strlen (replace), offset + p_len, strlen (offset) - p_len + 1);
|
||||
memmove (offset, replace, strlen (replace));
|
||||
offset += strlen (replace);
|
||||
if (sub >= 0) break;
|
||||
}
|
||||
|
||||
size -= ((AP_MAX_REG_MATCH - count)*(strlen(replace)) + ((strlen(replace) - p_len)*(count+AP_MAX_REG_MATCH) - (AP_MAX_REG_MATCH+4)));
|
||||
@ -791,7 +933,7 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
/* We no longer escape the pattern here as it is done when logging */
|
||||
char *pattern = apr_pstrdup(msr->mp, regex->pattern);
|
||||
char *pattern = apr_pstrdup(msr->mp, log_escape(msr->mp, regex->pattern ? regex->pattern : "<Unknown Match>"));
|
||||
|
||||
/* This message will be logged. */
|
||||
if (strlen(pattern) > 252) {
|
||||
@ -1004,6 +1146,17 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
|
||||
/* gsbLookup */
|
||||
|
||||
/*
|
||||
* \brief Verify function to gsbLookup operator
|
||||
*
|
||||
* \param rule Pointer to the rule
|
||||
* \param match Pointer to input data
|
||||
* \param match_length Input size
|
||||
*
|
||||
* \retval -1 On Failure
|
||||
* \retval 1 On Match
|
||||
* \retval 0 On No Match
|
||||
*/
|
||||
static int verify_gsb(gsb_db *gsb, msre_rule *rule, const char *match, unsigned int match_length) {
|
||||
apr_md5_ctx_t ctx;
|
||||
apr_status_t rc;
|
||||
@ -1032,6 +1185,15 @@ static int verify_gsb(gsb_db *gsb, msre_rule *rule, const char *match, unsigned
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Init function to gsbLookup operator
|
||||
*
|
||||
* \param rule Pointer to the rule
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval 1 On Success
|
||||
* \retval 0 On Fail
|
||||
*/
|
||||
static int msre_op_gsbLookup_param_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
@ -1054,6 +1216,18 @@ static int msre_op_gsbLookup_param_init(msre_rule *rule, char **error_msg) {
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Execution function to gsbLookup operator
|
||||
*
|
||||
* \param msr Pointer internal modsec request structure
|
||||
* \param rule Pointer to the rule
|
||||
* \param var Pointer to variable structure
|
||||
* \param error_msg Pointer to error msg
|
||||
*
|
||||
* \retval -1 On Failure
|
||||
* \retval 1 On Match
|
||||
* \retval 0 On No Match
|
||||
*/
|
||||
static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
msc_regex_t *regex = (msc_regex_t *)rule->op_param_data;
|
||||
char *my_error_msg = NULL;
|
||||
@ -1071,26 +1245,23 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
char *str = NULL, *entire = NULL;
|
||||
int capture;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if(regex == NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 8) {
|
||||
msr_log(msr, 8, "GSB: regex is null");
|
||||
}
|
||||
*error_msg = "Internal Error: regex data is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(gsb == NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 8) {
|
||||
msr_log(msr, 8, "GSB: gsb is null");
|
||||
}
|
||||
*error_msg = "Internal Error: gsb data is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = apr_pcalloc(msr->mp, var->value_len+1);
|
||||
|
||||
if(data == NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 8) {
|
||||
msr_log(msr, 8, "GSB: Fail to alloc memory for input data");
|
||||
}
|
||||
*error_msg = "Internal Error: cannot allocate memory for data.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1105,11 +1276,7 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
match = apr_psprintf(rule->ruleset->mp, "%.*s", ovector[2*i+1] - ovector[2*i], data + ovector[2*i]);
|
||||
|
||||
if (match == NULL) {
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 8) {
|
||||
msr_log(msr, 8, "GSB: Fail to alloc memory for match string");
|
||||
}
|
||||
|
||||
*error_msg = "Internal Error: cannot allocate memory for match.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1147,7 +1314,7 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
ret = verify_gsb(gsb, rule, canon, canon_length);
|
||||
|
||||
if(ret > 0) {
|
||||
set_match_to_tx(msr, capture, canon);
|
||||
set_match_to_tx(msr, capture, match);
|
||||
if (! *error_msg) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Gsb lookup for \"%s\" succeeded.",
|
||||
log_escape_nq(msr->mp, canon));
|
||||
@ -2018,7 +2185,7 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
static int cpf_verify(const char *cpfnumber, int len, msre_rule *rule) {
|
||||
|
||||
int factor, part_1, part_2, var_len = len;
|
||||
int sum = 0, i = 0, cpf_len = 11;
|
||||
int sum = 0, i = 0, cpf_len = 11, c;
|
||||
int cpf[11];
|
||||
char s_cpf[11];
|
||||
char bad_cpf[11][11] = { "00000000000",
|
||||
@ -2060,7 +2227,7 @@ static int cpf_verify(const char *cpfnumber, int len, msre_rule *rule) {
|
||||
part_1 = convert_to_int(s_cpf[cpf_len-2]);
|
||||
part_2 = convert_to_int(s_cpf[cpf_len-1]);
|
||||
|
||||
int c = cpf_len;
|
||||
c = cpf_len;
|
||||
|
||||
for(i = 0; i < 9; i++) {
|
||||
sum += (cpf[i] * --c);
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "apr_md5.h"
|
||||
@ -25,6 +26,57 @@
|
||||
#include "re.h"
|
||||
#include "msc_util.h"
|
||||
|
||||
/* cmdline */
|
||||
|
||||
static int msre_fn_cmdline_execute(apr_pool_t *mptmp, unsigned char *input,
|
||||
long int input_len, char **rval, long int *rval_len)
|
||||
{
|
||||
int space = 0;
|
||||
unsigned char *s = input;
|
||||
|
||||
if (rval == NULL) return -1;
|
||||
|
||||
*rval = (char *)input;
|
||||
/* Check characters */
|
||||
for ( ; *input; input++ ) {
|
||||
switch(*input) {
|
||||
/* remove some characters */
|
||||
case '"':
|
||||
case '\'':
|
||||
case '\\':
|
||||
case '^':
|
||||
continue;
|
||||
/* replace some characters to space (only one) */
|
||||
case ' ':
|
||||
case ',':
|
||||
case ';':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (!space) {
|
||||
*s++ = ' ';
|
||||
space++;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
case '(':
|
||||
/* remove space before / or ( */
|
||||
if (space) s--;
|
||||
space = 0;
|
||||
*s++ = *input;
|
||||
break;
|
||||
/* copy normal characters */
|
||||
default :
|
||||
*s++ = tolower(*input);
|
||||
space = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*s = 0;
|
||||
*rval_len = strlen(*rval);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* lowercase */
|
||||
|
||||
static int msre_fn_lowercase_execute(apr_pool_t *mptmp, unsigned char *input,
|
||||
@ -786,6 +838,11 @@ void msre_engine_register_default_tfns(msre_engine *engine) {
|
||||
msre_fn_trimLeft_execute
|
||||
);
|
||||
|
||||
msre_engine_tfn_register(engine,
|
||||
"cmdline",
|
||||
msre_fn_cmdline_execute
|
||||
);
|
||||
|
||||
/* trimRight */
|
||||
msre_engine_tfn_register(engine,
|
||||
"trimRight",
|
||||
|
@ -16,6 +16,7 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "http_core.h"
|
||||
|
||||
#include "modsecurity.h"
|
||||
@ -456,6 +457,18 @@ static int var_request_uri_raw_generate(modsec_rec *msr, msre_var *var, msre_rul
|
||||
return var_simple_generate(var, vartab, mptmp, msr->r->unparsed_uri);
|
||||
}
|
||||
|
||||
/* UNIQUE_ID */
|
||||
|
||||
static int var_uniqueid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
char *value = get_env_var(msr->r, "UNIQUE_ID");
|
||||
if (value != NULL) {
|
||||
return var_simple_generate(var, vartab, mptmp, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* REQUEST_URI */
|
||||
|
||||
static int var_request_uri_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
@ -1833,6 +1846,107 @@ static int var_request_body_length_generate(modsec_rec *msr, msre_var *var, msre
|
||||
return var_simple_generate(var, vartab, mptmp, value);
|
||||
}
|
||||
|
||||
/* MATCHED_VARS_NAMES */
|
||||
|
||||
static int var_matched_vars_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
const apr_array_header_t *arr = NULL;
|
||||
const apr_table_entry_t *te = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
arr = apr_table_elts(msr->matched_vars);
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
int match = 0;
|
||||
msc_string *str = (msc_string *)te[i].val;
|
||||
|
||||
/* Figure out if we want to include this variable. */
|
||||
if (var->param == NULL) match = 1;
|
||||
else {
|
||||
if (var->param_data != NULL) { /* Regex. */
|
||||
char *my_error_msg = NULL;
|
||||
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
||||
strlen(str->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
||||
} else { /* Simple comparison. */
|
||||
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we had a match add this argument to the collection. */
|
||||
if (match && (strncmp(str->name,"MATCHED_VARS:",13) != 0) && (strncmp(str->name,"MATCHED_VARS_NAMES:",19))) {
|
||||
|
||||
msre_var *rvar = apr_palloc(mptmp, sizeof(msre_var));
|
||||
|
||||
rvar->value = apr_pstrndup(mptmp, str->name, strlen(str->name));
|
||||
rvar->value_len = strlen(rvar->value);
|
||||
rvar->name = apr_psprintf(mptmp, "MATCHED_VARS_NAMES:%s",
|
||||
log_escape_nq(mptmp, str->name));
|
||||
|
||||
apr_table_setn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Set variable \"%s\" value \"%s\" size %d to collection.", rvar->name, rvar->value, rvar->value_len);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* MATCHED_VARS */
|
||||
|
||||
static int var_matched_vars_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
const apr_array_header_t *arr = NULL;
|
||||
const apr_table_entry_t *te = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
arr = apr_table_elts(msr->matched_vars);
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
int match = 0;
|
||||
msc_string *str = (msc_string *)te[i].val;
|
||||
|
||||
/* Figure out if we want to include this variable. */
|
||||
if (var->param == NULL) match = 1;
|
||||
else {
|
||||
if (var->param_data != NULL) { /* Regex. */
|
||||
char *my_error_msg = NULL;
|
||||
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
||||
strlen(str->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
||||
} else { /* Simple comparison. */
|
||||
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we had a match add this argument to the collection. */
|
||||
if (match && (strncmp(str->name,"MATCHED_VARS:",13) != 0) && (strncmp(str->name,"MATCHED_VARS_NAMES:",19))) {
|
||||
|
||||
//msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
||||
msre_var *rvar = apr_palloc(mptmp, sizeof(msre_var));
|
||||
|
||||
rvar->value = apr_pstrndup(mptmp, str->value, str->value_len);
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "MATCHED_VARS:%s",
|
||||
log_escape_nq(mptmp, str->name));
|
||||
|
||||
apr_table_setn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Set variable \"%s\" value \"%s\" size %d to collection.", rvar->name, rvar->value, rvar->value_len);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* REQUEST_COOKIES */
|
||||
|
||||
static int var_request_cookies_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
@ -1863,7 +1977,7 @@ static int var_request_cookies_generate(modsec_rec *msr, msre_var *var, msre_rul
|
||||
if (match) {
|
||||
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
||||
|
||||
rvar->value = te[i].val;
|
||||
rvar->value = te[i].key;
|
||||
rvar->value_len = strlen(rvar->value);
|
||||
rvar->name = apr_psprintf(mptmp, "REQUEST_COOKIES:%s",
|
||||
log_escape_nq(mptmp, te[i].key));
|
||||
@ -2928,6 +3042,28 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MATCHED_VARS_NAMES */
|
||||
msre_engine_variable_register(engine,
|
||||
"MATCHED_VARS_NAMES",
|
||||
VAR_LIST,
|
||||
0, 1,
|
||||
var_generic_list_validate,
|
||||
var_matched_vars_names_generate,
|
||||
VAR_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
/* MATCHED_VARS */
|
||||
msre_engine_variable_register(engine,
|
||||
"MATCHED_VARS",
|
||||
VAR_LIST,
|
||||
0, 1,
|
||||
var_generic_list_validate,
|
||||
var_matched_vars_generate,
|
||||
VAR_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
/* REQUEST_COOKIES */
|
||||
msre_engine_variable_register(engine,
|
||||
"REQUEST_COOKIES",
|
||||
@ -3038,6 +3174,18 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
/* UNIQUE_ID */
|
||||
msre_engine_variable_register(engine,
|
||||
"UNIQUE_ID",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_uniqueid_generate,
|
||||
VAR_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
|
||||
/* STREAM_OUTPUT_BODY */
|
||||
msre_engine_variable_register(engine,
|
||||
"STREAM_OUTPUT_BODY",
|
||||
|
@ -16,6 +16,8 @@
|
||||
* directly using the email address support@trustwave.com.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8TABLES_H_
|
||||
#define UTF8TABLES_H_
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user