Merge 2.5.x (2.5.12) changes into trunk.

This commit is contained in:
b1v1r
2010-02-05 19:05:20 +00:00
parent ed11e27e0f
commit 08edc0c26f
54 changed files with 3170 additions and 330 deletions

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -33,7 +33,8 @@
/**
* Creates a fresh directory configuration.
*/
void *create_directory_config(apr_pool_t *mp, char *path) {
void *create_directory_config(apr_pool_t *mp, char *path)
{
directory_config *dcfg = (directory_config *)apr_pcalloc(mp, sizeof(directory_config));
if (dcfg == NULL) return NULL;
@@ -87,6 +88,7 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
dcfg->upload_keep_files = NOT_SET;
dcfg->upload_validates_files = NOT_SET;
dcfg->upload_filemode = NOT_SET;
dcfg->upload_file_limit = NOT_SET;
/* These are only used during the configuration process. */
dcfg->tmp_chain_starter = NULL;
@@ -121,8 +123,10 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
* Copies rules between one phase of two configuration contexts,
* taking exceptions into account.
*/
static void copy_rules_phase(apr_pool_t *mp, apr_array_header_t *parent_phase_arr,
apr_array_header_t *child_phase_arr, apr_array_header_t *exceptions_arr)
static void copy_rules_phase(apr_pool_t *mp,
apr_array_header_t *parent_phase_arr,
apr_array_header_t *child_phase_arr,
apr_array_header_t *exceptions_arr)
{
rule_exception **exceptions;
msre_rule **rules;
@@ -190,8 +194,9 @@ static void copy_rules_phase(apr_pool_t *mp, apr_array_header_t *parent_phase_ar
* Copies rules between two configuration contexts,
* taking exceptions into account.
*/
static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset, msre_ruleset *child_ruleset,
apr_array_header_t *exceptions_arr)
static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
msre_ruleset *child_ruleset,
apr_array_header_t *exceptions_arr)
{
copy_rules_phase(mp, parent_ruleset->phase_request_headers,
child_ruleset->phase_request_headers, exceptions_arr);
@@ -210,7 +215,8 @@ static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset, msre_ruleset
/**
* Merges two directory configurations.
*/
void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
{
directory_config *parent = (directory_config *)_parent;
directory_config *child = (directory_config *)_child;
directory_config *merged = create_directory_config(mp, NULL);
@@ -418,6 +424,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
? parent->upload_validates_files : child->upload_validates_files);
merged->upload_filemode = (child->upload_filemode == NOT_SET
? parent->upload_filemode : child->upload_filemode);
merged->upload_file_limit = (child->upload_file_limit == NOT_SET
? parent->upload_file_limit : child->upload_file_limit);
/* Misc */
merged->data_dir = (child->data_dir == NOT_SET_P
@@ -461,7 +469,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
* the configuration phase. It can only be called on copies of those
* (created fresh for every transaction).
*/
void init_directory_config(directory_config *dcfg) {
void init_directory_config(directory_config *dcfg)
{
if (dcfg == NULL) return;
if (dcfg->is_enabled == NOT_SET) dcfg->is_enabled = 0;
@@ -511,7 +520,8 @@ void init_directory_config(directory_config *dcfg) {
if (dcfg->upload_dir == NOT_SET_P) dcfg->upload_dir = NULL;
if (dcfg->upload_keep_files == NOT_SET) dcfg->upload_keep_files = KEEP_FILES_OFF;
if (dcfg->upload_validates_files == NOT_SET) dcfg->upload_validates_files = 0;
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = mode2fileperms(0600);
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = 0600;
if (dcfg->upload_file_limit == NOT_SET) dcfg->upload_file_limit = 100;
/* Misc */
if (dcfg->data_dir == NOT_SET_P) dcfg->data_dir = NULL;
@@ -531,13 +541,14 @@ void init_directory_config(directory_config *dcfg) {
if (dcfg->cache_trans_maxitems == (apr_size_t)NOT_SET) dcfg->cache_trans_maxitems = 512;
if (dcfg->request_encoding == NOT_SET_P) dcfg->request_encoding = NULL;
}
/**
*
*/
static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
const char *p1, const char *p2, const char *p3)
const char *p1, const char *p2, const char *p3)
{
char *my_error_msg = NULL;
msre_rule *rule = NULL;
@@ -724,8 +735,8 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
/**
*
*/
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char *p1,
const char *p2, const char *p3)
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
const char *p1, const char *p2, const char *p3)
{
char *my_error_msg = NULL;
msre_rule *rule = NULL;
@@ -777,7 +788,7 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char
*
*/
static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
const char *p1, const char *p2)
const char *p1, const char *p2)
{
char *my_error_msg = NULL;
msre_rule *rule = NULL;
@@ -862,17 +873,21 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
/* -- Configuration directives -- */
static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1)
{
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_ACTION, SECACTION_TARGETS, SECACTION_ARGS, p1);
}
static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
const char *action = apr_pstrcat(dcfg->mp, SECMARKER_BASE_ACTIONS, p1, NULL);
return add_marker(cmd, (directory_config *)_dcfg, SECMARKER_TARGETS, SECMARKER_ARGS, action);
}
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (strlen(p1) != 1) {
@@ -884,7 +899,8 @@ static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg, const cha
return NULL;
}
static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = _dcfg;
if (strcasecmp(p1, "On") == 0) dcfg->auditlog_flag = AUDITLOG_ON;
@@ -899,7 +915,8 @@ static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
return NULL;
}
static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = _dcfg;
dcfg->auditlog_name = (char *)p1;
@@ -932,7 +949,8 @@ static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = _dcfg;
if (dcfg->auditlog_name == NOT_SET_P) {
@@ -969,7 +987,9 @@ static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = _dcfg;
if (is_valid_parts_specification((char *)p1) != 1) {
@@ -980,7 +1000,9 @@ static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg, const char *
return NULL;
}
static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = _dcfg;
dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE_DOTALL, NULL, NULL);
@@ -991,7 +1013,9 @@ static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg, co
return NULL;
}
static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = _dcfg;
if (strcasecmp(p1, "Serial") == 0) dcfg->auditlog_type = AUDITLOG_SERIAL;
@@ -1004,7 +1028,9 @@ static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg, const char *p
return NULL;
}
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1024,7 +1050,9 @@ static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg, const char
return NULL;
}
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1044,7 +1072,9 @@ static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg, const cha
return NULL;
}
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = _dcfg;
dcfg->auditlog_storage_dir = ap_server_root_relative(cmd->pool, p1);
@@ -1052,7 +1082,9 @@ static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg, const
return NULL;
}
static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (strcmp(p1, "0") == 0) dcfg->cookie_format = COOKIES_V0;
@@ -1065,7 +1097,8 @@ static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg, const char *p1
return NULL;
}
static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
char cwd[1025] = "";
if (cmd->server->is_virtual) {
@@ -1094,7 +1127,9 @@ static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
/**
* Adds component signature to the list of signatures kept in configuration.
*/
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
/* ENH Enforce "Name/VersionX.Y.Z (comment)" format. */
@@ -1103,14 +1138,16 @@ static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg, const ch
return NULL;
}
static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag) {
static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
dcfg->content_injection_enabled = flag;
return NULL;
}
static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (cmd->server->is_virtual) {
@@ -1122,7 +1159,8 @@ static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
apr_status_t rc;
@@ -1140,7 +1178,9 @@ static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
dcfg->debuglog_level = atoi(p1);
@@ -1149,7 +1189,9 @@ static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg, const char *
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecDebugLogLevel: %s", p1);
}
static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
extern msc_engine *modsecurity;
char *my_error_msg = NULL;
@@ -1213,7 +1255,9 @@ static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg, const char *p
return NULL;
}
static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg, const char *p1, const char *p2) {
static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
extern char *guardianlog_name;
extern apr_file_t *guardianlog_fd;
extern char *guardianlog_condition;
@@ -1262,7 +1306,9 @@ static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg, const char *p1,
return NULL;
}
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
@@ -1278,7 +1324,9 @@ static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
return NULL;
}
static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
@@ -1294,7 +1342,9 @@ static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg, const cha
return NULL;
}
static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
@@ -1310,7 +1360,9 @@ static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
return NULL;
}
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1323,7 +1375,9 @@ static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg, const ch
return NULL;
}
static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1334,7 +1388,9 @@ static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg, const char
return NULL;
}
static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1347,7 +1403,9 @@ static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg, const c
return NULL;
}
static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
@@ -1365,7 +1423,9 @@ static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg, const ch
return NULL;
}
static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1378,7 +1438,9 @@ static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg, c
return NULL;
}
static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg, const char *_p1) {
static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg,
const char *_p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
char *p1 = apr_pstrdup(cmd->pool, _p1);
@@ -1394,7 +1456,9 @@ static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg, cons
return NULL;
}
static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd, void *_dcfg) {
static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd,
void *_dcfg)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1407,13 +1471,14 @@ static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd, void *_dcf
return NULL;
}
static const char *cmd_rule(cmd_parms *cmd, void *_dcfg, const char *p1,
const char *p2, const char *p3)
static const char *cmd_rule(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2, const char *p3)
{
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_NORMAL, p1, p2, p3);
}
static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1428,43 +1493,16 @@ static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
return NULL;
}
/*
static const char *cmd_rule_import_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
if (dcfg == NULL) return NULL;
re->type = RULE_EXCEPTION_IMPORT_ID;
// TODO verify p1
re->param = p1;
*(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
return NULL;
}
static const char *cmd_rule_import_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
if (dcfg == NULL) return NULL;
re->type = RULE_EXCEPTION_IMPORT_MSG;
// TODO verify p1
re->param = p1;
*(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
return NULL;
}
*/
static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag) {
static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
dcfg->rule_inheritance = flag;
return NULL;
}
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg, const char *p1,
const char *p2)
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
#if defined(WITH_LUA)
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
@@ -1475,7 +1513,9 @@ static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg, const char *p1,
#endif
}
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
if (dcfg == NULL) return NULL;
@@ -1490,7 +1530,9 @@ static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg, const char
return NULL;
}
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
if (dcfg == NULL) return NULL;
@@ -1514,12 +1556,14 @@ static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg, const cha
}
static const char *cmd_rule_update_action_by_id(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
const char *p1, const char *p2)
{
return update_rule_action(cmd, (directory_config *)_dcfg, p1, p2);
}
static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
if (cmd->server->is_virtual) {
return "ModSecurity: SecServerSignature not allowed in VirtualHost";
}
@@ -1527,7 +1571,8 @@ static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg, const char
return NULL;
}
static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1538,7 +1583,8 @@ static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1549,7 +1595,26 @@ static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_upload_file_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
if (strcasecmp(p1, "default") == 0) {
dcfg->upload_file_limit = NOT_SET;
}
else {
dcfg->upload_file_limit = atoi(p1);
}
return NULL;
}
static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1569,7 +1634,9 @@ static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg, const char *
return NULL;
}
static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1589,7 +1656,8 @@ static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg, const char
return NULL;
}
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
/* ENH enforce format (letters, digits, ., _, -) */
@@ -1598,10 +1666,51 @@ static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
return NULL;
}
/* PCRE Limits */
static const char *cmd_pcre_match_limit(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
long val;
if (cmd->server->is_virtual) {
return "ModSecurity: SecPcreMatchLimit not allowed in VirtualHost";
}
val = atol(p1);
if (val <= 0) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
"SecPcreMatchLimit: %s", p1);
}
msc_pcre_match_limit = (unsigned long int)val;
return NULL;
}
static const char *cmd_pcre_match_limit_recursion(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
long val;
if (cmd->server->is_virtual) {
return "ModSecurity: SecPcreMatchLimitRecursion not allowed in VirtualHost";
}
val = atol(p1);
if (val <= 0) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
"SecPcreMatchLimitRecursion: %s", p1);
}
msc_pcre_match_limit_recursion = (unsigned long int)val;
return NULL;
}
/* -- Geo Lookup configuration -- */
static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
const char *p1)
const char *p1)
{
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
char *error_msg;
@@ -1618,7 +1727,9 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
/* -- Cache -- */
static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg, const char *p1, const char *p2) {
static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
@@ -1911,6 +2022,22 @@ const command_rec module_directives[] = {
"marker for a skipAfter target"
),
AP_INIT_TAKE1 (
"SecPcreMatchLimit",
cmd_pcre_match_limit,
NULL,
CMD_SCOPE_MAIN,
"PCRE match limit"
),
AP_INIT_TAKE1 (
"SecPcreMatchLimitRecursion",
cmd_pcre_match_limit_recursion,
NULL,
CMD_SCOPE_MAIN,
"PCRE match limit recursion"
),
AP_INIT_TAKE1 (
"SecRequestBodyAccess",
cmd_request_body_access,
@@ -2071,6 +2198,14 @@ const command_rec module_directives[] = {
"path to the file upload area"
),
AP_INIT_TAKE1 (
"SecUploadFileLimit",
cmd_upload_file_limit,
NULL,
CMD_SCOPE_ANY,
"limit the number of uploaded files processed"
),
AP_INIT_TAKE1 (
"SecUploadFileMode",
cmd_upload_filemode,

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

69
apache2/configure vendored
View File

@@ -694,6 +694,9 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_pcre_study
enable_pcre_match_limit
enable_pcre_match_limit_recursion
enable_errors
enable_verbose_output
enable_strict_compile
@@ -1328,6 +1331,12 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-pcre-study Enable PCRE regex studying during configure.
--enable-pcre-match-limit
Enable PCRE regex match limit during configure.
--enable-pcre-match-limit-recursion
Enable PCRE regex match limit recursion during
configure.
--disable-errors Disable errors during configure.
--enable-verbose-output Enable more verbose configure output.
--enable-strict-compile Enable strict compilation (warnings are errors).
@@ -4186,7 +4195,7 @@ test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
esac
for ac_func in atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol
for ac_func in atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol fchmod
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4221,6 +4230,62 @@ MSC_REGRESSION_DOCROOT_DIR="$MSC_REGRESSION_SERVERROOT_DIR/htdocs"
### Configure Options
# Add PCRE Studying
# Check whether --enable-pcre-study was given.
if test "${enable_pcre_study+set}" = set; then :
enableval=$enable_pcre_study;
if test "$enableval" != "no"; then
pcre_study='-DWITH_PCRE_STUDY'
else
pcre_study=''
fi
else
pcre_study='-DWITH_PCRE_STUDY'
fi
# Limit PCRE matching
# Check whether --enable-pcre-match-limit was given.
if test "${enable_pcre_match_limit+set}" = set; then :
enableval=$enable_pcre_match_limit;
if test "$enableval" = "yes"; then
as_fn_error "PCRE match limits require a numeric value" "$LINENO" 5
elif test "$enableval" = "no"; then
pcre_match_limit=''
else
pcre_match_limit="-DMODSEC_PCRE_MATCH_LIMIT=$enableval"
fi
else
pcre_match_limit='-DMODSEC_PCRE_MATCH_LIMIT=1500'
fi
# Limit PCRE matching recursion
# Check whether --enable-pcre-match-limit-recursion was given.
if test "${enable_pcre_match_limit_recursion+set}" = set; then :
enableval=$enable_pcre_match_limit_recursion;
if test "$enableval" = "yes"; then
as_fn_error "PCRE match limits require a numeric value" "$LINENO" 5
elif test "$enableval" = "no"; then
pcre_match_limit_recursion=''
else
pcre_match_limit_recursion="-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=$enableval"
fi
else
pcre_match_limit_recursion='-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=1500'
fi
# Ignore configure errors
# Check whether --enable-errors was given.
if test "${enable_errors+set}" = set; then :
@@ -4575,7 +4640,7 @@ else
EXTRA_CFLAGS="-O2 -g -Wall $strict_compile"
fi
fi
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
APXS_WRAPPER=build/apxs-wrapper
APXS_EXTRA_CFLAGS=""

View File

@@ -40,7 +40,7 @@ AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_CHECK_FUNCS([atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol])
AC_CHECK_FUNCS([atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol fchmod])
# Some directories
MSC_BASE_DIR=`pwd`
@@ -63,6 +63,56 @@ AC_SUBST(MSC_REGRESSION_DOCROOT_DIR)
### Configure Options
# Add PCRE Studying
AC_ARG_ENABLE(pcre-study,
AS_HELP_STRING([--enable-pcre-study],
[Enable PCRE regex studying during configure.]),
[
if test "$enableval" != "no"; then
pcre_study='-DWITH_PCRE_STUDY'
else
pcre_study=''
fi
],
[
pcre_study='-DWITH_PCRE_STUDY'
])
# Limit PCRE matching
AC_ARG_ENABLE(pcre-match-limit,
AS_HELP_STRING([--enable-pcre-match-limit],
[Enable PCRE regex match limit during configure.]),
[
if test "$enableval" = "yes"; then
AC_MSG_ERROR([PCRE match limits require a numeric value])
elif test "$enableval" = "no"; then
pcre_match_limit=''
else
pcre_match_limit="-DMODSEC_PCRE_MATCH_LIMIT=$enableval"
fi
],
[
pcre_match_limit='-DMODSEC_PCRE_MATCH_LIMIT=1500'
])
# Limit PCRE matching recursion
AC_ARG_ENABLE(pcre-match-limit-recursion,
AS_HELP_STRING([--enable-pcre-match-limit-recursion],
[Enable PCRE regex match limit recursion during configure.]),
[
if test "$enableval" = "yes"; then
AC_MSG_ERROR([PCRE match limits require a numeric value])
elif test "$enableval" = "no"; then
pcre_match_limit_recursion=''
else
pcre_match_limit_recursion="-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=$enableval"
fi
],
[
pcre_match_limit_recursion='-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=1500'
])
# Ignore configure errors
AC_ARG_ENABLE(errors,
AS_HELP_STRING([--disable-errors],
@@ -325,7 +375,7 @@ else
EXTRA_CFLAGS="-O2 -g -Wall $strict_compile"
fi
fi
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
APXS_WRAPPER=build/apxs-wrapper
APXS_EXTRA_CFLAGS=""

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -52,6 +52,9 @@ apr_file_t DSOLOCAL *guardianlog_fd = NULL;
char DSOLOCAL *guardianlog_condition = NULL;
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
/* -- Miscellaneous functions -- */
@@ -227,9 +230,24 @@ int perform_interception(modsec_rec *msr) {
break;
}
/* If the level is not high enough to add an alert message, but "auditlog"
* is enabled, then still add the message. */
if ((log_level > 3) && (actionset->auditlog != 0)) {
*(const char **)apr_array_push(msr->alerts) = msc_alert_message(msr, actionset, NULL, message);
}
/* Log the message now. */
msc_alert(msr, log_level, actionset, message, msr->intercept_message);
/* However, this will mark the txn relevant again if it is <= 3,
* which will mess up noauditlog. We need to compensate for this
* so that we do not increment twice when auditlog is enabled and
* prevent incrementing when auditlog is disabled.
*/
if ((actionset->auditlog == 0) && (log_level <= 3)) {
msr->is_relevant--;
}
return status;
}

View File

@@ -3,6 +3,9 @@
/* Define to 1 if you have the `atexit' function. */
#undef HAVE_ATEXIT
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -127,6 +127,10 @@ extern module AP_MODULE_DECLARE_DATA security2_module;
extern DSOLOCAL const command_rec module_directives[];
extern DSOLOCAL unsigned long int msc_pcre_match_limit;
extern DSOLOCAL unsigned long int msc_pcre_match_limit_recursion;
#define RESBODY_STATUS_NOT_READ 0 /* we were not configured to read the body */
#define RESBODY_STATUS_ERROR 1 /* error occured while we were reading the body */
#define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
@@ -335,6 +339,7 @@ struct modsec_rec {
/* upload */
int upload_extract_files;
int upload_remove_files;
int upload_files_count;
/* other */
apr_table_t *collections_original;
@@ -441,6 +446,7 @@ struct directory_config {
int upload_keep_files;
int upload_validates_files;
int upload_filemode; /* int only so NOT_SET works */
int upload_file_limit;
/* Used only in the configuration phase. */
msre_rule *tmp_chain_starter;

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -279,12 +279,20 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
} else {
/* Header line. */
if ((msr->mpd->buf[0] == '\t') || (msr->mpd->buf[0] == ' ')) {
if (isspace(msr->mpd->buf[0])) {
char *header_value, *new_value, *data;
/* header folding, add data to the header we are building */
msr->mpd->flag_header_folding = 1;
/* RFC-2557 states header folding is SP / HTAB, but PHP and
* perhaps others will take any whitespace. So, we accept,
* but with a flag set.
*/
if ((msr->mpd->buf[0] != '\t') && (msr->mpd->buf[0] != ' ')) {
msr->mpd->flag_invalid_header_folding = 1;
}
if (msr->mpd->mpp->last_header_name == NULL) {
/* we are not building a header at this moment */
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid part header (folding error).");
@@ -293,7 +301,15 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
/* locate the beginning of data */
data = msr->mpd->buf;
while((*data == '\t') || (*data == ' ')) data++;
while(isspace(*data)) {
/* Flag invalid header folding if an invalid RFC-2557 character is used anywhere
* in the folding prefix.
*/
if ((*data != '\t') && (*data != ' ')) {
msr->mpd->flag_invalid_header_folding = 1;
}
data++;
}
new_value = apr_pstrdup(msr->mp, data);
remove_lf_crlf_inplace(new_value);
@@ -397,16 +413,32 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
/* add data to the part we are building */
if (msr->mpd->mpp->type == MULTIPART_FILE) {
int extract = msr->upload_extract_files;
/* remember where we started */
if (msr->mpd->mpp->length == 0) {
msr->mpd->mpp->offset = msr->mpd->buf_offset;
}
/* check if the file limit has been reached */
if (extract && (msr->mpd->nfiles >= msr->txcfg->upload_file_limit)) {
if (msr->mpd->flag_file_limit_exceeded == 0) {
*error_msg = apr_psprintf(msr->mp,
"Multipart: Upload file limit exceeded "
"SecUploadFileLimit %d.",
msr->txcfg->upload_file_limit);
msr_log(msr, 3, "%s", *error_msg);
msr->mpd->flag_file_limit_exceeded = 1;
}
extract = 0;
}
/* only store individual files on disk if we are going
* to keep them or if we need to have them approved later
*/
if (msr->upload_extract_files) {
if (extract) {
/* first create a temporary file if we don't have it already */
if (msr->mpd->mpp->tmp_file_fd == 0) {
/* construct temporary file name */
@@ -421,8 +453,14 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
return -1;
}
/* keep track of the files count */
msr->mpd->nfiles++;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Multipart: Created temporary file: %s",
msr_log(msr, 4,
"Multipart: Created temporary file %d (mode %04o): %s",
msr->mpd->nfiles,
(unsigned int)msr->txcfg->upload_filemode,
log_escape_nq(msr->mp, msr->mpd->mpp->tmp_file_name));
}
}
@@ -879,6 +917,14 @@ int multipart_complete(modsec_rec *msr, char **error_msg) {
if (msr->mpd->flag_missing_semicolon) {
msr_log(msr, 4, "Multipart: Warning: missing semicolon in C-T header.");
}
if (msr->mpd->flag_invalid_quoting) {
msr_log(msr, 4, "Multipart: Warning: invalid quoting used.");
}
if (msr->mpd->flag_invalid_header_folding) {
msr_log(msr, 4, "Multipart: Warning: invalid header folding used.");
}
}
if ((msr->mpd->seen_data != 0) && (msr->mpd->is_complete == 0)) {

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -68,6 +68,9 @@ struct multipart_data {
/* this array keeps parts */
apr_array_header_t *parts;
/* Number of parts that are files */
int nfiles;
/* mime boundary used to detect when
* parts end and begin
*/
@@ -118,6 +121,8 @@ struct multipart_data {
int flag_boundary_whitespace;
int flag_missing_semicolon;
int flag_invalid_quoting;
int flag_invalid_header_folding;
int flag_file_limit_exceeded;
};

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -22,7 +22,9 @@
/**
*
*/
int parse_cookies_v0(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies) {
int parse_cookies_v0(modsec_rec *msr, char *_cookie_header,
apr_table_t *cookies)
{
char *attr_name = NULL, *attr_value = NULL;
char *cookie_header;
char *saveptr = NULL;
@@ -85,13 +87,21 @@ int parse_cookies_v0(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies
/**
*
*/
int parse_cookies_v1(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies) {
int parse_cookies_v1(modsec_rec *msr, char *_cookie_header,
apr_table_t *cookies)
{
char *attr_name = NULL, *attr_value = NULL, *p = NULL;
char *prev_attr_name = NULL;
char *cookie_header = NULL;
int cookie_count = 0;
if (_cookie_header == NULL) return -1;
// XXX Should it not match _v0 parser?
//if (_cookie_header == NULL) {
// msr_log(msr, 1, "Cookie parser: Received null for argument.");
// return -1;
//}
cookie_header = strdup(_cookie_header);
if (cookie_header == NULL) return -1;
@@ -213,6 +223,7 @@ int parse_cookies_v1(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies
while( (*p != 0)&&( (*p == ',')||(*p == ';')||(isspace(*p)) ) ) p++;
}
free(cookie_header);
return cookie_count;
}
@@ -322,7 +333,8 @@ int parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength,
/**
*
*/
void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg) {
void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg)
{
if (msr->txcfg->debuglog_level >= 5) {
msr_log(msr, 5, "Adding request argument (%s): name \"%s\", value \"%s\"",
arg->origin, log_escape_ex(msr->mp, arg->name, arg->name_len),

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -38,17 +38,21 @@ apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
}
/**
* Compiles the provided regular expression pattern. The last two
* Compiles the provided regular expression pattern. The _err*
* parameters are optional, but if they are provided and an error
* occurs they will contain the error message and the offset in
* the pattern where the offending part of the pattern begins.
* the pattern where the offending part of the pattern begins. The
* match_limit* parameters are optional and if >0, then will set
* match limits.
*/
void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset)
void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset,
int match_limit, int match_limit_recursion)
{
const char *errptr = NULL;
int erroffset;
msc_regex_t *regex;
pcre_extra *pe = NULL;
regex = apr_pcalloc(pool, sizeof(msc_regex_t));
if (regex == NULL) return NULL;
@@ -62,15 +66,74 @@ void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
if (regex->re == NULL) return NULL;
#ifdef WITH_PCRE_STUDY
regex->pe = pcre_study(regex->re, 0, &errptr);
pe = pcre_study(regex->re, 0, &errptr);
#endif
/* Setup the pcre_extra record if pcre_study did not already do it */
if (pe == NULL) {
pe = malloc(sizeof(pcre_extra));
if (pe == NULL) {
return NULL;
}
memset(pe, 0, sizeof(pcre_extra));
}
#ifdef PCRE_EXTRA_MATCH_LIMIT
/* If match limit is available, then use it */
/* Use ModSecurity runtime defaults */
if (match_limit > 0) {
pe->match_limit = match_limit;
pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
}
#ifdef MODSEC_PCRE_MATCH_LIMIT
/* Default to ModSecurity compiled defaults */
else {
pe->match_limit = MODSEC_PCRE_MATCH_LIMIT;
pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
}
#endif /* MODSEC_PCRE_MATCH_LIMIT */
#else
#warning This PCRE version does not support match limits! Upgrade to at least PCRE v6.5.
#endif /* PCRE_EXTRA_MATCH_LIMIT */
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
/* If match limit recursion is available, then use it */
/* Use ModSecurity runtime defaults */
if (match_limit_recursion > 0) {
pe->match_limit_recursion = match_limit_recursion;
pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
}
#ifdef MODSEC_PCRE_MATCH_LIMIT_RECURSION
/* Default to ModSecurity compiled defaults */
else {
pe->match_limit_recursion = MODSEC_PCRE_MATCH_LIMIT_RECURSION;
pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
}
#endif /* MODSEC_PCRE_MATCH_LIMIT_RECURSION */
#else
#warning This PCRE version does not support match recursion limits! Upgrade to at least PCRE v6.5.
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
regex->pe = pe;
apr_pool_cleanup_register(pool, (void *)regex,
(apr_status_t (*)(void *))msc_pcre_cleanup, apr_pool_cleanup_null);
return regex;
}
/**
* Compiles the provided regular expression pattern. Calls msc_pregcomp_ex()
* with default limits.
*/
void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset)
{
return msc_pregcomp_ex(pool, pattern, options, _errptr, _erroffset, 0, 0);
}
/**
* Executes regular expression with extended options.
* Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1
@@ -119,3 +182,4 @@ int msc_fullinfo(msc_regex_t *regex, int what, void *where)
{
return pcre_fullinfo(regex->re, regex->pe, what, where);
}

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -22,6 +22,17 @@
typedef struct msc_regex_t msc_regex_t;
#include "pcre.h"
#ifndef PCRE_ERROR_MATCHLIMIT
/* Define for compile, but not valid in this version of PCRE. */
#define PCRE_ERROR_MATCHLIMIT (-8)
#endif /* PCRE_ERROR_MATCHLIMIT */
#ifndef PCRE_ERROR_RECURSIONLIMIT
/* Define for compile, but not valid in this version of PCRE. */
#define PCRE_ERROR_RECURSIONLIMIT (-21)
#endif /* PCRE_ERROR_RECURSIONLIMIT */
#include "apr_general.h"
#include "modsecurity.h"
@@ -33,17 +44,23 @@ struct msc_regex_t {
apr_status_t DSOLOCAL msc_pcre_cleanup(msc_regex_t *regex);
void DSOLOCAL *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset);
void DSOLOCAL *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset,
int match_limit, int match_limit_recursion);
int DSOLOCAL msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen,
int startoffset, int options, int *ovector, int ovecsize, char **error_msg);
void DSOLOCAL *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset);
int DSOLOCAL msc_regexec_ex(msc_regex_t *regex, const char *s,
unsigned int slen, int startoffset, int options,
int *ovector, int ovecsize, char **error_msg);
int DSOLOCAL msc_regexec_capture(msc_regex_t *regex, const char *s,
unsigned int slen, int *ovector, int ovecsize, char **error_msg);
unsigned int slen, int *ovector,
int ovecsize, char **error_msg);
int DSOLOCAL msc_regexec(msc_regex_t *regex, const char *s, unsigned int slen,
char **error_msg);
int DSOLOCAL msc_regexec(msc_regex_t *regex, const char *s,
unsigned int slen, char **error_msg);
int DSOLOCAL msc_fullinfo(msc_regex_t *regex, int what, void *where);

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -79,7 +79,8 @@ static apr_pool_t *g_mp = NULL;
static modsec_rec *g_msr = NULL;
static unsigned char buf[BUFLEN];
msc_engine *modsecurity = NULL;
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
/* Stubs */
char *format_error_log_message(apr_pool_t *mp, error_message *em) {
@@ -765,7 +766,7 @@ int main(int argc, const char * const argv[])
result = RESULT_WRONGRET;
}
else if (param_len != out_len) {
fprintf(stderr, "Lenth %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
fprintf(stderr, "Length %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
result = RESULT_WRONGSIZE;
}
else {

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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,15 +16,16 @@
* directly using the email address support@breach.com.
*
*/
#include "msc_release.h"
#include "msc_util.h"
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "mod_security2_config.h"
#include "msc_release.h"
#include "msc_util.h"
#include <apr_lib.h>
/**
@@ -435,14 +436,25 @@ char *current_filetime(apr_pool_t *mp) {
*
*/
int msc_mkstemp_ex(char *template, int mode) {
int fd = -1;
/* ENH Use apr_file_mktemp instead. */
#if !(defined(WIN32)||defined(NETWARE))
return mkstemp(template);
#else
#if !(defined(WIN32)||defined(NETWARE))
fd = mkstemp(template);
#ifdef HAVE_FCHMOD
if ((fd != -1) && (mode != 0)) {
if (fchmod(fd, mode) == -1) {
return -1;
}
}
#endif /* HAVE_FCHMOD */
#else
if (mktemp(template) == NULL) return -1;
return open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode);
#endif
fd = open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode);
#endif /* !(defined(WIN32)||defined(NETWARE)) */
return fd;
}
/**
@@ -1149,68 +1161,175 @@ int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len) {
* IMP1 Assumes NUL-terminated
*/
int normalize_path_inplace(unsigned char *input, int input_len, int win, int *changed) {
unsigned char *d = input;
int i, count;
unsigned char *src;
unsigned char *dst;
unsigned char *end;
int ldst = 0;
int hitroot = 0;
int done = 0;
int relative;
int trailing;
*changed = 0;
i = count = 0;
while ((i < input_len)&&(count < input_len)) {
char c = input[i];
/* Need at least one byte to normalize */
if (input_len <= 0) return 0;
/*
* ENH: Deal with UNC and drive letters?
*/
src = dst = input;
end = input + (input_len - 1);
ldst = 1;
relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1;
trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0;
while (!done && (src <= end) && (dst <= end)) {
/* Convert backslash to forward slash on Windows only. */
if ((win)&&(c == '\\')) {
c = '/';
*changed = 1;
}
if (c == '/') {
/* Is there a directory back-reference? Yes, we
* require at least 5 prior bytes here. That's on
* purpose.
*/
if ((count >= 5)&&(*(d - 1) == '.')&&(*(d - 2) == '.')&&(*(d - 3) == '/')) {
unsigned char *cd = d - 4;
int ccount = count - 4;
if (win) {
if (*src == '\\') {
*src = '/';
*changed = 1;
/* Go back until we reach the beginning or a forward slash. */
while ((ccount > 0)&&(*cd != '/')) {
ccount--;
cd--;
}
if (*cd == '/') {
d = cd;
count = ccount;
}
} else
/* Is there a directory self-reference? */
if ((count >= 2)&&(*(d - 1) == '.')&&(*(d - 2) == '/')) {
/* Ignore the last two bytes. */
d -= 2;
count -= 2;
*changed = 1;
} else
/* Or are there just multiple occurences of forward slash? */
if ((count >= 1)&&(*(d - 1) == '/')) {
/* Ignore the last one byte. */
d--;
count--;
}
if ((src < end) && (*(src + 1) == '\\')) {
*(src + 1) = '/';
*changed = 1;
}
}
/* Copy the byte over. */
*d++ = c;
count++;
i++;
/* Always normalize at the end of the input. */
if (src == end) {
done = 1;
}
/* Skip normalization if this is NOT the end of the path segment. */
else if (*(src + 1) != '/') {
goto copy; /* Skip normalization. */
}
/*** Normalize the path segment. ***/
/* Could it be an empty path segment? */
if ((src != end) && *src == '/') {
/* Ignore */
*changed = 1;
goto copy; /* Copy will take care of this. */
}
/* Could it be a back or self reference? */
else if (*src == '.') {
/* Back-reference? */
if ((dst > input) && (*(dst - 1) == '.')) {
/* If a relative path and either our normalization has
* already hit the rootdir, or this is a backref with no
* previous path segment, then mark that the rootdir was hit
* and just copy the backref as no normilization is possible.
*/
if (relative && (hitroot || ((dst - 2) <= input))) {
hitroot = 1;
goto copy; /* Skip normalization. */
}
/* Remove backreference and the previous path segment. */
dst -= 3;
while ((dst > input) && (*dst != '/')) {
dst--;
}
/* But do not allow going above rootdir. */
if (dst <= input) {
hitroot = 1;
dst = input;
/* Need to leave the root slash if this
* is not a relative path and the end was reached
* on a backreference.
*/
if (!relative && (src == end)) {
dst++;
}
}
if (done) goto length; /* Skip the copy. */
src++;
*changed = 1;
}
/* Relative Self-reference? */
else if (dst == input) {
*changed = 1;
/* Ignore. */
if (done) goto length; /* Skip the copy. */
src++;
}
/* Self-reference? */
else if (*(dst - 1) == '/') {
*changed = 1;
/* Ignore. */
if (done) goto length; /* Skip the copy. */
dst--;
src++;
}
}
/* Found a regular path segment. */
else if (dst > input) {
hitroot = 0;
}
copy:
/*** Copy the byte if required. ***/
/* Skip to the last forward slash when multiple are used. */
if (*src == '/') {
unsigned char *oldsrc = src;
while ( (src < end)
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) )
{
src++;
}
if (oldsrc != src) *changed = 1;
/* Do not copy the forward slash to the root
* if it is not a relative path. Instead
* move over the slash to the next segment.
*/
if (relative && (dst == input)) {
src++;
goto length; /* Skip the copy */
}
}
*(dst++) = *(src++);
length:
ldst = (dst - input);
}
*d = '\0';
/* Make sure that there is not a trailing slash in the
* normalized form if there was not one in the original form.
*/
if (!trailing && (dst > input) && *(dst - 1) == '/') {
ldst--;
dst--;
}
return count;
/* Always NUL terminate */
*dst = '\0';
return ldst;
}
char *modsec_build(apr_pool_t *mp) {

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -22,6 +22,13 @@
#include <sys/types.h>
#include <apr_file_info.h>
#ifndef APR_WSTICKY
/* Add extra flags added to APR in 0.9.5 */
#define APR_USETID 0x8000 /**< Set user id */
#define APR_GSETID 0x4000 /**< Set group id */
#define APR_WSTICKY 0x2000 /**< Sticky bit */
#endif
#include "modsecurity.h"
int DSOLOCAL normalize_path_inplace(unsigned char *input, int len, int win, int *changed);

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -1050,8 +1050,7 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
}
}
}
else
if (rc == RULE_MATCH) {
else if (rc == RULE_MATCH) {
if (msr->rule_was_intercepted) {
/* If the transaction was intercepted by this rule we will
* go back. Do note that we are relying on the

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -84,7 +84,7 @@ static int msre_op_rx_param_init(msre_rule *rule, char **error_msg) {
*error_msg = NULL;
/* Compile pattern */
regex = msc_pregcomp(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
if (regex == NULL) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
erroffset, errptr);
@@ -143,8 +143,29 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
* and no memory has to be allocated for any backreferences.
*/
rc = msc_regexec_capture(regex, target, target_length, ovector, 30, &my_error_msg);
if (rc < -1) {
*error_msg = apr_psprintf(msr->mp, "Regex execution failed: %s", my_error_msg);
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
if (s == NULL) return -1;
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
s->name_len = strlen(s->name);
s->value = apr_pstrdup(msr->mp, "1");
s->value_len = 1;
if ((s->name == NULL)||(s->value == NULL)) return -1;
apr_table_setn(msr->tx_vars, s->name, (void *)s);
*error_msg = apr_psprintf(msr->mp,
"Rule execution error - "
"PCRE limits exceeded (%d): %s",
rc, my_error_msg);
msr_log(msr, 3, "%s.", *error_msg);
return 0; /* No match. */
}
else if (rc < -1) {
*error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
rc, my_error_msg);
return -1;
}
@@ -170,6 +191,7 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
if (s == NULL) return -1;
s->name = apr_psprintf(msr->mp, "%d", i);
s->name_len = strlen(s->name);
s->value = apr_pstrmemdup(msr->mp,
target + ovector[2 * i], ovector[2 * i + 1] - ovector[2 * i]);
s->value_len = (ovector[2 * i + 1] - ovector[2 * i]);
@@ -243,7 +265,8 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
char buf[HUGE_STRING_LEN + 1];
char *fn;
char *next;
char *ptr;
char *start;
char *end;
const char *rulefile_path;
apr_status_t rc;
apr_file_t *fd;
@@ -289,7 +312,7 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
}
/* Open file and read */
rc = apr_file_open(&fd, fn, APR_READ | APR_FILE_NOCLEANUP, 0, rule->ruleset->mp);
rc = apr_file_open(&fd, fn, APR_READ | APR_BUFFERED | APR_FILE_NOCLEANUP, 0, rule->ruleset->mp);
if (rc != APR_SUCCESS) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Could not open phrase file \"%s\": %s", fn, apr_strerror(rc, errstr, 1024));
return 0;
@@ -309,21 +332,24 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
return 0;
}
/* Remove newline */
ptr = buf;
while(*ptr != '\0') ptr++;
if ((ptr > buf) && (*(ptr - 1) == '\n')) *(ptr - 1) = '\0';
/* Trim Whitespace */
start = buf;
while ((apr_isspace(*start) != 0) && (*start != '\0')) start++;
end = buf + strlen(buf);
if (end > start) end--;
while ((end > start) && (apr_isspace(*end) != 0)) end--;
if (end > start) {
*(++end) = '\0';
}
/* Ignore empty lines and comments */
ptr = buf;
while((*ptr != '\0') && apr_isspace(*ptr)) ptr++;
if ((*ptr == '\0') || (*ptr == '#')) continue;
if ((start == end) || (*start == '#')) continue;
#ifdef DEBUG_CONF
fprintf(stderr, "Adding phrase file pattern: \"%s\"\n", buf);
#endif
acmp_add_pattern(p, buf, NULL, NULL, strlen(buf));
acmp_add_pattern(p, start, NULL, NULL, (end - start));
}
fn = next;
}
@@ -369,6 +395,7 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
if (s == NULL) return -1;
s->name = "0";
s->name_len = strlen(s->name);
s->value = apr_pstrdup(msr->mp, match);
if (s->value == NULL) return -1;
s->value_len = strlen(s->value);
@@ -1067,7 +1094,7 @@ static int msre_op_verifyCC_init(msre_rule *rule, char **error_msg) {
*error_msg = NULL;
/* Compile rule->op_param */
regex = msc_pregcomp(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset);
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
if (regex == NULL) {
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
erroffset, errptr);
@@ -1159,6 +1186,7 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var *
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
if (s == NULL) return -1;
s->name = apr_psprintf(msr->mp, "%d", i);
s->name_len = strlen(s->name);
s->value = apr_pstrmemdup(msr->mp, match, length);
s->value_len = length;
if ((s->name == NULL)||(s->value == NULL)) return -1;
@@ -1796,18 +1824,27 @@ static int msre_op_validateUtf8Encoding_execute(modsec_rec *msr, msre_rule *rule
static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
msc_string str;
int left, right;
char *target = NULL;
if (error_msg == NULL) return -1;
*error_msg = NULL;
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
str.value = (char *)rule->op_param;
str.value_len = strlen(str.value);
expand_macros(msr, &str, rule, msr->mp);
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
right = atoi(rule->op_param);
right = atoi(str.value);
if (left != right) {
/* No match. */
@@ -1825,6 +1862,7 @@ static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
msc_string str;
int left, right;
char *target = NULL;
@@ -1833,10 +1871,23 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
if (error_msg == NULL) return -1;
*error_msg = NULL;
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
str.value = (char *)rule->op_param;
str.value_len = strlen(str.value);
expand_macros(msr, &str, rule, msr->mp);
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
right = atoi(rule->op_param);
right = atoi(str.value);
if (left <= right) {
/* No match. */
@@ -1854,6 +1905,7 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
msc_string str;
int left, right;
char *target = NULL;
@@ -1862,10 +1914,23 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
if (error_msg == NULL) return -1;
*error_msg = NULL;
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
str.value = (char *)rule->op_param;
str.value_len = strlen(str.value);
expand_macros(msr, &str, rule, msr->mp);
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
right = atoi(rule->op_param);
right = atoi(str.value);
if (left >= right) {
/* No match. */
@@ -1883,6 +1948,7 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
msc_string str;
int left, right;
char *target = NULL;
@@ -1891,10 +1957,23 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
if (error_msg == NULL) return -1;
*error_msg = NULL;
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
str.value = (char *)rule->op_param;
str.value_len = strlen(str.value);
expand_macros(msr, &str, rule, msr->mp);
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
right = atoi(rule->op_param);
right = atoi(str.value);
if (left < right) {
/* No match. */
@@ -1912,6 +1991,7 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
msc_string str;
int left, right;
char *target = NULL;
@@ -1920,10 +2000,23 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
if (error_msg == NULL) return -1;
*error_msg = NULL;
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
str.value = (char *)rule->op_param;
str.value_len = strlen(str.value);
expand_macros(msr, &str, rule, msr->mp);
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
right = atoi(rule->op_param);
right = atoi(str.value);
if (left > right) {
/* No match. */
@@ -1936,7 +2029,7 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
}
}
/* ------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
*

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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
@@ -1379,6 +1379,30 @@ static int var_multipart_invalid_quoting_generate(modsec_rec *msr, msre_var *var
}
}
/* MULTIPART_INVALID_HEADER_FOLDING */
static int var_multipart_invalid_header_folding_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
apr_table_t *vartab, apr_pool_t *mptmp)
{
if ((msr->mpd != NULL)&&(msr->mpd->flag_invalid_header_folding != 0)) {
return var_simple_generate(var, vartab, mptmp, "1");
} else {
return var_simple_generate(var, vartab, mptmp, "0");
}
}
/* MULTIPART_FILE_LIMIT_EXCEEDED */
static int var_multipart_file_limit_exceeded_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
apr_table_t *vartab, apr_pool_t *mptmp)
{
if ((msr->mpd != NULL)&&(msr->mpd->flag_file_limit_exceeded != 0)) {
return var_simple_generate(var, vartab, mptmp, "1");
} else {
return var_simple_generate(var, vartab, mptmp, "0");
}
}
/* MULTIPART_STRICT_ERROR */
static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
@@ -1395,6 +1419,8 @@ static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, m
||(msr->mpd->flag_lf_line != 0)
||(msr->mpd->flag_missing_semicolon != 0)
||(msr->mpd->flag_invalid_quoting != 0)
||(msr->mpd->flag_invalid_header_folding != 0)
||(msr->mpd->flag_file_limit_exceeded != 0)
) {
return var_simple_generate(var, vartab, mptmp, "1");
}
@@ -2643,6 +2669,28 @@ void msre_engine_register_default_variables(msre_engine *engine) {
PHASE_REQUEST_BODY
);
/* MULTIPART_INVALID_HEADER_FOLDING */
msre_engine_variable_register(engine,
"MULTIPART_INVALID_HEADER_FOLDING",
VAR_SIMPLE,
0, 0,
NULL,
var_multipart_invalid_header_folding_generate,
VAR_DONT_CACHE, /* flag */
PHASE_REQUEST_BODY
);
/* MULTIPART_FILE_LIMIT_EXCEEDED */
msre_engine_variable_register(engine,
"MULTIPART_FILE_LIMIT_EXCEEDED",
VAR_SIMPLE,
0, 0,
NULL,
var_multipart_file_limit_exceeded_generate,
VAR_DONT_CACHE, /* flag */
PHASE_REQUEST_BODY
);
/* MULTIPART_STRICT_ERROR */
msre_engine_variable_register(engine,
"MULTIPART_STRICT_ERROR",

View File

@@ -1,17 +1,21 @@
### Logging tests
# log/nolog
# log/nolog (pass)
{
type => "action",
comment => "log",
comment => "log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -22,9 +26,12 @@
},
{
type => "action",
comment => "nolog",
comment => "nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog"
@@ -41,19 +48,70 @@
),
},
# auditlog/noauditlog
# log/nolog (deny)
{
type => "action",
comment => "auditlog",
comment => "log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
# auditlog/noauditlog (pass)
{
type => "action",
comment => "auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -64,15 +122,18 @@
},
{
type => "action",
comment => "noauditlog",
comment => "noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -83,19 +144,70 @@
),
},
# All log/nolog auditlog/noauditlog combos
# auditlog/noauditlog (deny)
{
type => "action",
comment => "log,auditlog",
comment => "auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
# All log/nolog auditlog/noauditlog combos (pass)
{
type => "action",
comment => "log,auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -106,15 +218,18 @@
},
{
type => "action",
comment => "log,noauditlog",
comment => "log,noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -126,9 +241,12 @@
},
{
type => "action",
comment => "nolog,auditlog",
comment => "nolog,auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog,auditlog"
@@ -145,9 +263,12 @@
},
{
type => "action",
comment => "nolog,noauditlog",
comment => "nolog,noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog,noauditlog"
@@ -165,16 +286,19 @@
},
{
type => "action",
comment => "auditlog,log",
comment => "auditlog,log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -185,9 +309,12 @@
},
{
type => "action",
comment => "auditlog,nolog",
comment => "auditlog,nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog,nolog"
@@ -205,15 +332,18 @@
},
{
type => "action",
comment => "noauditlog,log",
comment => "noauditlog,log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -225,9 +355,12 @@
},
{
type => "action",
comment => "noauditlog,nolog",
comment => "noauditlog,nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog,nolog"
@@ -244,3 +377,188 @@
),
},
# All log/nolog auditlog/noauditlog combos (deny)
{
type => "action",
comment => "log,auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "log,noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog,auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog,auditlog"
),
match_log => {
audit => [ qr/-H--\s+Message: .*Stopwatch: /s, 1 ],
},
match_response => {
-error => [ qr/ModSecurity: /, 1 ],
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog,noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog,noauditlog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "auditlog,log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "auditlog,nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog,log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog,nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},

View File

@@ -96,7 +96,7 @@
return 1;
},
match_log => {
debug => [ qr/Created temporary file: $ENV{TEMP_DIR}/, 1 ],
debug => [ qr/Created temporary file.*$ENV{TEMP_DIR}/, 1 ],
-debug => [ qr/Failed to /, 1 ],
},
match_response => {

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -27,64 +27,190 @@
{
type => "tfn",
name => "normalisePath",
input => "/foo/bar//baz",
output => "/foo/bar/baz",
input => "x",
output => "x",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => ".",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "./",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "./foo/bar baz/././././boo//eek/././../whoa",
output => "./foo/bar baz/boo/whoa",
input => "./..",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "./../",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "//foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "..",
output => "..",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../",
output => "../",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../.",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "//foo/bar baz/././././boo//eek/././../whoa/./",
output => "/foo/bar baz/boo/whoa/",
input => ".././",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./foo/bar baz/././././boo//eek/././../whoa//",
output => "/foo/bar baz/boo/whoa/",
input => "../..",
output => "../..",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../../",
output => "../../",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "/dir/foo//bar",
output => "/dir/foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./../../../../../../../../etc/passwd",
output => "/etc/passwd",
input => "dir/foo//bar/",
output => "dir/foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./.././../../../../../../../etc/../etc/./passwd",
output => "/etc/passwd",
input => "dir/../foo",
output => "foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/../../foo",
output => "../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/.",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/./",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/..",
output => "../../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/../",
output => "../../foo/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir//.//..//.//..//..//foo//bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir//.//..//.//..//..//foo//bar//",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/subdir/subsubdir/subsubsubdir/../../..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./subdir/./subsubdir/./subsubsubdir/../../..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./subdir/../subsubdir/../subsubsubdir/..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/dir/./subdir/../subsubdir/../subsubsubdir/../",
output => "/dir/",
ret => 1,
},

View File

@@ -27,64 +27,190 @@
{
type => "tfn",
name => "normalisePathWin",
input => "\\foo\\bar\\\\baz",
output => "/foo/bar/baz",
input => "x",
output => "x",
ret => 0,
},
{
type => "tfn",
name => "normalisePathWin",
input => ".",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => ".\\",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => ".\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "./foo/bar baz/boo/whoa",
input => ".\\..",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => ".\\..\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => "..",
output => "..",
ret => 0,
},
{
type => "tfn",
name => "normalisePathWin",
input => "..\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\.\\",
output => "/foo/bar baz/boo/whoa/",
input => "..\\.",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\\\",
output => "/foo/bar baz/boo/whoa/",
input => "..\\.\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\..\\..\\..\\..\\..\\..\\..\\..\\etc\\passwd",
output => "/etc/passwd",
input => "..\\..",
output => "../..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\..\\.\\..\\..\\..\\..\\..\\..\\..\\etc\\..\\etc\\.\\passwd",
output => "/etc/passwd",
input => "..\\..\\",
output => "../../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\dir\\foo\\\\bar",
output => "/dir/foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\foo\\\\bar\\",
output => "dir/foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\..\\foo",
output => "foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\..\\..\\foo",
output => "../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..",
output => "../../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..\\",
output => "../../foo/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar\\\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\subdir\\subsubdir\\subsubsubdir\\..\\..\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\subdir\\.\\subsubdir\\.\\subsubsubdir\\..\\..\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..\\",
output => "/dir/",
ret => 1,
},

View File

@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.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