Merge 2.5.x (2.5.12) changes into trunk.

This commit is contained in:
b1v1r 2010-02-05 19:05:20 +00:00
Родитель ed11e27e0f
Коммит 08edc0c26f
54 изменённых файлов: 3170 добавлений и 330 удалений

48
CHANGES
Просмотреть файл

@ -1,5 +1,4 @@
2 Feb 2010 - trunk
04 Feb 2010 - trunk
-------------------
* Add REQUEST_BODY_LENGTH, which contains the number of request body
@ -27,6 +26,51 @@
pave support for allowing access to all ModSecurity variables from
mog_log_config. [Ivan Ristic]
04 Feb 2010 - 2.5.12
--------------------
* Fixed SecUploadFileMode to set the correct mode.
* Fixed nolog,auditlog/noauditlog/nolog controls for disruptive actions.
* Added additional file info definitions introduced in APR 0.9.5 so that
build will work with older APRs (IBM HTTP Server v6).
* Added SecUploadFileLimit to limit the number of uploaded file parts that
will be processed in a multipart POST. The default is 100.
* Fixed path normalization to better handle backreferences that extend
above root directories. Reported by Sogeti/ESEC R&D.
* Trim whitespace around phrases used with @pmFromFile and allow
for both LF and CRLF terminated lines.
* Allow for more robust parsing for multipart header folding. Reported
by Sogeti/ESEC R&D.
* Fixed failure to match internally set TX variables with regex
(TX:/.../) syntax.
* Fixed failure to log full internal TX variable names and populate
MATCHED_VAR* vars.
* Enabled PCRE "studying" by default. This is now a configure-time option.
* Added PCRE match limits (SecPcreMatchLimit/SecPcreMatchLimitRecursion) to
aide in REDoS type attacks. A rule that goes over the limits will set
TX:MSC_PCRE_LIMITS_EXCEEDED. It is intended that the next major release
of ModSecurity (2.6.x) will move these flags to a dedicated collection.
* Reduced default PCRE match limits reducing impact of REDoS on poorly
written regex rules. Reported by Sogeti/ESEC R&D.
* Fixed memory leak in v1 cookie parser. Reported by Sogeti/ESEC R&D.
* Now support macro expansion in numeric operators (@eq, @ge, @lt, etc.)
* Update copyright to 2010.
* Reserved 700,000-799,999 IDs for Ivan Ristic.
* Fixed SecAction not working when CONNECT request method is used

Просмотреть файл

@ -1,5 +1,5 @@
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/)
ModSecurity for Apache is an open source product, released under terms of
the General Public Licence, Version 2 (GPLv2). Please refer to the

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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,

Просмотреть файл

@ -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

Просмотреть файл

@ -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 поставляемый
Просмотреть файл

@ -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=""

Просмотреть файл

@ -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=""

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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)) {

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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),

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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,
}
}
/* ------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
*

Просмотреть файл

@ -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

Просмотреть файл

@ -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",

Просмотреть файл

@ -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",
),
},

Просмотреть файл

@ -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 => {

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -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,
},

Просмотреть файл

@ -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,
},

Просмотреть файл

@ -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

Просмотреть файл

@ -13,7 +13,7 @@
</xsl:template>
<xsl:template name="user.footer.navigation">
<div class="copyright" align="center">Copyright (C) 2004-2009 <a href="http://www.breach.com">Breach Security</a></div>
<div class="copyright" align="center">Copyright (C) 2004-2010 <a href="http://www.breach.com">Breach Security</a></div>
</xsl:template>
<xsl:template name="article.titlepage.separator">

Просмотреть файл

@ -9,7 +9,7 @@
</xsl:template>
<xsl:template name="user.footer.navigation">
<div class="copyright" align="center">Copyright (C) 2004-2009 <a href="http://www.breach.com">Breach Security</a></div>
<div class="copyright" align="center">Copyright (C) 2004-2010 <a href="http://www.breach.com">Breach Security</a></div>
</xsl:template>
<xsl:template name="article.titlepage.separator">

Просмотреть файл

@ -6,7 +6,7 @@
<releaseinfo>Version 1.0 / (April 10, 2007)</releaseinfo>
<copyright>
<year>2004-2009</year>
<year>2004-2010</year>
<holder>Breach Security, Inc. (<ulink
url="http://www.breach.com">http://www.breach.com</ulink>)</holder>

Просмотреть файл

@ -4,9 +4,9 @@
<article>
<title><trademark class="registered">ModSecurity</trademark> Reference Manual</title>
<articleinfo>
<releaseinfo>Version 2.6.0-trunk (Nov 12, 2009)</releaseinfo>
<releaseinfo>Version 2.6.0-trunk (Feb 3, 2009)</releaseinfo>
<copyright>
<year>2004-2009</year>
<year>2004-2010</year>
<holder>Breach Security, Inc. (<ulink url="http://www.breach.com"
>http://www.breach.com</ulink>)</holder>
</copyright>
@ -218,10 +218,11 @@
central repository, then you will also need the curl library.</para>
<para><ulink type="" url="http://curl.haxx.se/libcurl/"
>http://curl.haxx.se/libcurl/</ulink></para>
<note>
<para>Many have had issues with libcurl linked with the GnuTLS library for SSL/TLS
support. It is recommended that the openssl library be used for SSL/TLS support in
libcurl.</para>
<para>Many have had issues with libcurl linked with the GnuTLS
library for SSL/TLS support. It is recommended that the openssl
library be used for SSL/TLS support in libcurl.</para>
</note>
</listitem>
</orderedlist>
@ -999,6 +1000,61 @@ SecRule &amp;REQUEST_HEADERS:Accept "@eq 0" \
SecMarker 99</emphasis></programlisting>
</para>
</section>
<section>
<title><literal>SecPcreMatchLimit</literal></title>
<para><emphasis>Description:</emphasis>Sets the the match limit in the
PCRE library. See the pcre_extra field in the pcreapi man page.</para>
<para><emphasis>Syntax:</emphasis> <literal
moreinfo="none">SecPcreMatchLimit value</literal></para>
<para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecPcreMatchLimit 1500</literal></para>
<para><emphasis>Processing Phase:</emphasis> N/A</para>
<para><emphasis>Scope:</emphasis> Global</para>
<para><emphasis>Version:</emphasis> 2.5.12</para>
<para><emphasis>Dependencies/Notes:</emphasis> Default is set at compile
(1500 by default)</para>
<para>The <literal>--enable-pcre-match-limit=val</literal> configure
option will set a custom default and the
<literal>--disable-pcre-match-limit</literal> option will resort to the
compiled PCRE library default.</para>
</section>
<section>
<title><literal>SecPcreMatchLimitRecursion</literal></title>
<para><emphasis>Description:</emphasis>Sets the the match limit
recursion in the PCRE library. See the pcre_extra field in the pcreapi
man page.</para>
<para><emphasis>Syntax:</emphasis> <literal
moreinfo="none">SecPcreMatchLimitRecursion value</literal></para>
<para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecPcreMatchLimitRecursion 1500</literal></para>
<para><emphasis>Processing Phase:</emphasis> N/A</para>
<para><emphasis>Scope:</emphasis> Global</para>
<para><emphasis>Version:</emphasis> 2.5.12</para>
<para><emphasis>Dependencies/Notes:</emphasis> Default is set at compile
(1500 by default)</para>
<para>The <literal>--enable-pcre-match-limit-recursion=val</literal>
configure option will set a custom default and the
<literal>--disable-pcre-match-limit-recursion</literal> option will
resort to the compiled PCRE library default.</para>
</section>
<section>
<title><literal>SecPdfProtect</literal></title>
<para><emphasis>Description:</emphasis> Enables the PDF XSS protection functionality. Once
@ -1670,6 +1726,42 @@ SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new m
as the temporary directory defined with <literal moreinfo="none">SecTmpDir</literal>. This
directive is used with <literal>SecUploadKeepFiles</literal>.</para>
</section>
<section>
<title><literal>SecUploadFileLimit</literal></title>
<para><emphasis>Description:</emphasis> Configures the maximum number of
file uploads processed in a multipart POST.</para>
<para><emphasis>Syntax:</emphasis> <literal
moreinfo="none">SecUploadFileLimit number</literal></para>
<para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecUploadFileLimit 10</literal></para>
<para><emphasis>Processing Phase:</emphasis> N/A</para>
<para><emphasis>Scope:</emphasis> Any</para>
<para><emphasis>Version:</emphasis> 2.5.12</para>
<para><emphasis>Dependencies/Notes:</emphasis> The default is set to 100
files, but you are encouraged to reduce this value. Any file over the
limit will not be extracted and the <literal
moreinfo="none">MULTIPART_FILE_LIMIT_EXCEEDED</literal> and <literal
moreinfo="none">MULTIPART_STRICT_ERROR</literal> flags will be set. To
prevent bypassing any file checks, you must check for one of these
flags.</para>
<note>
<para>If the limit is exceeded, the part name and file name will still
be recorded in <literal moreinfo="none">FILES_NAME</literal> and
<literal moreinfo="none">FILES</literal>, the file size will be
recorded in <literal moreinfo="none">FILES_SIZES</literal>, but there
will be no record in <literal moreinfo="none">FILES_TMPNAMES</literal>
as a temporary file was not created.</para>
</note>
</section>
<section>
<title><literal>SecUploadFileMode</literal></title>
<para><emphasis>Description:</emphasis> Configures the mode (permissions) of any uploaded
@ -2111,19 +2203,30 @@ SecRule ARGS "@pm some key words" id:12345,deny,status:500</programlisting>
</section>
<section>
<title><literal>MULTIPART_STRICT_ERROR</literal></title>
<para><literal>MULTIPART_STRICT_ERROR</literal> will be set to <literal>1</literal> when any
of the following variables is also set to <literal>1</literal>: <literal
>REQBODY_PROCESSOR_ERROR</literal>, <literal>MULTIPART_BOUNDARY_QUOTED</literal>, <literal
>MULTIPART_BOUNDARY_WHITESPACE</literal>, <literal>MULTIPART_DATA_BEFORE</literal>,
<literal>MULTIPART_DATA_AFTER</literal>, <literal>MULTIPART_HEADER_FOLDING</literal>,
<literal>MULTIPART_LF_LINE</literal>, <literal>MULTIPART_SEMICOLON_MISSING</literal>
<literal>MULTIPART_INVALID_QUOTING</literal>. Each of these variables covers one unusual
(although sometimes legal) aspect of the request body in <literal>multipart/form-data
format</literal>. Your policies should <emphasis>always</emphasis> contain a rule to check
either this variable (easier) or one or more individual variables (if you know exactly what
you want to accomplish). Depending on the rate of false positives and your default policy
you should decide whether to block or just warn when the rule is triggered.</para>
<para>The best way to use this variable is as in the example below:</para>
<para><literal>MULTIPART_STRICT_ERROR</literal> will be set to
<literal>1</literal> when any of the following variables is also set to
<literal>1</literal>: <literal>REQBODY_PROCESSOR_ERROR</literal>,
<literal>MULTIPART_BOUNDARY_QUOTED</literal>,
<literal>MULTIPART_BOUNDARY_WHITESPACE</literal>,
<literal>MULTIPART_DATA_BEFORE</literal>,
<literal>MULTIPART_DATA_AFTER</literal>,
<literal>MULTIPART_HEADER_FOLDING</literal>,
<literal>MULTIPART_LF_LINE</literal>,
<literal>MULTIPART_SEMICOLON_MISSING</literal>
<literal>MULTIPART_INVALID_QUOTING</literal>
<literal>MULTIPART_INVALID_HEADER_FOLDING</literal>
<literal>MULTIPART_FILE_LIMIT_EXCEEDED</literal>. Each of these
variables covers one unusual (although sometimes legal) aspect of the
request body in <literal>multipart/form-data format</literal>. Your
policies should <emphasis>always</emphasis> contain a rule to check
either this variable (easier) or one or more individual variables (if
you know exactly what you want to accomplish). Depending on the rate of
false positives and your default policy you should decide whether to
block or just warn when the rule is triggered.</para>
<para>The best way to use this variable is as in the example
below:</para>
<programlisting>SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \
failed strict validation: \
@ -2135,7 +2238,9 @@ DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}'"</programlisting>
IQ %{MULTIPART_INVALID_QUOTING}, \
IQ %{MULTIPART_INVALID_HEADER_FOLDING}, \
FE %{MULTIPART_FILE_LIMIT_EXCEEDED}'"</programlisting>
<para>The <literal>multipart/form-data</literal> parser was upgraded in ModSecurity v2.1.3 to
actively look for signs of evasion. Many variables (as listed above) were added to expose
various facts discovered during the parsing process. The <literal
@ -2570,6 +2675,21 @@ SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}</programlisting>
using the <literal moreinfo="none">@rx</literal> operator with capturing parens and the
<literal moreinfo="none">capture</literal> action.</para>
</listitem>
<listitem>
<para><literal moreinfo="none">TX:MSC_.*</literal> - ModSecurity
processing flags.</para>
<itemizedlist>
<listitem>
<para><literal
moreinfo="none">MSC_PCRE_LIMITS_EXCEEDED</literal> - Set
non-zero if PCRE match limits are exceeded. See <literal
moreinfo="none">SecPcreMatchLimit</literal> and <literal
moreinfo="none">SecPcreMatchLimitRecursion</literal>.</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<programlisting format="linespecific">SecRule WEBSERVER_ERROR_LOG "does not exist" "phase:5,pass,<emphasis>setvar:tx.score=+5</emphasis>"
SecRule<emphasis> TX:SCORE</emphasis> "@gt 20" deny,log</programlisting>
@ -3256,7 +3376,7 @@ setvar:session.suspicious=1,<emphasis>expirevar:session.suspicious=3600</emphasi
<para>430,000-699,999; unused (available for reservation).</para>
</listitem>
<listitem>
<para>700,000-799,999; reserved for Ivan Ristic.</para>
<para>700,000-799,999; reserved for Ivan Ristic.</para>
</listitem>
<listitem>
@ -3731,6 +3851,9 @@ SecRule ARGS:route "!<emphasis>@endsWith %{REQUEST_ADDR}</emphasis>" t:none,deny
"equal to."</para>
<para>Example:</para>
<programlisting format="linespecific">SecRule &amp;REQUEST_HEADERS_NAMES "<emphasis>@eq</emphasis> 15"</programlisting>
<para>Macro expansion is performed so you may use variable names such as
<literal>%{TX.1}</literal>, etc.</para>
</section>
<section>
<title><literal>ge</literal></title>
@ -3738,6 +3861,9 @@ SecRule ARGS:route "!<emphasis>@endsWith %{REQUEST_ADDR}</emphasis>" t:none,deny
"greater than or equal to."</para>
<para>Example:</para>
<programlisting format="linespecific">SecRule &amp;REQUEST_HEADERS_NAMES "<emphasis>@ge</emphasis> 15"</programlisting>
<para>Macro expansion is performed so you may use variable names such as
<literal>%{TX.1}</literal>, etc.</para>
</section>
<section>
<title><literal>geoLookup</literal></title>
@ -3766,6 +3892,9 @@ SecRule &amp;GEO "@eq 0" "deny,status:403,msg:'Failed to lookup IP'"</programlis
"greater than."</para>
<para>Example:</para>
<programlisting format="linespecific">SecRule &amp;REQUEST_HEADERS_NAMES "<emphasis>@gt</emphasis> 15"</programlisting>
<para>Macro expansion is performed so you may use variable names such as
<literal>%{TX.1}</literal>, etc.</para>
</section>
<section>
<title><literal>inspectFile</literal></title>
@ -3800,6 +3929,9 @@ end</programlisting>
"less than or equal to."</para>
<para>Example:</para>
<programlisting format="linespecific">SecRule &amp;REQUEST_HEADERS_NAMES "<emphasis>@le</emphasis> 15"</programlisting>
<para>Macro expansion is performed so you may use variable names such as
<literal>%{TX.1}</literal>, etc.</para>
</section>
<section>
<title><literal>lt</literal></title>
@ -3807,6 +3939,9 @@ end</programlisting>
"less than."</para>
<para>Example:</para>
<programlisting format="linespecific">SecRule &amp;REQUEST_HEADERS_NAMES "<emphasis>@lt</emphasis> 15"</programlisting>
<para>Macro expansion is performed so you may use variable names such as
<literal>%{TX.1}</literal>, etc.</para>
</section>
<section>
<title><literal>pm</literal></title>
@ -3827,15 +3962,34 @@ end</programlisting>
<para>Notes:</para>
<orderedlist continuation="restarts" inheritnum="ignore">
<listitem>
<para>The contents of the files should be one phrase per line. End of line markers will be
stripped from the phrases, however, whitespace will not be trimmed from phrases in the
file. Empty lines and comment lines (beginning with a '#') are ignored.</para>
<para>The contents of the files should be one phrase per line. End
of line markers will be stripped from the phrases (LF and CRLF), and
whitespace is trimmed from both sides of the phrases. Empty lines
and comment lines (beginning with a '#') are ignored.</para>
</listitem>
<listitem>
<para>To allow easier inclusion of phrase files with rulesets, relative paths may be used
to the phrase files. In this case, the path of the file containing the rule is prepended
to the phrase file path.</para>
</listitem>
<listitem>
<para>To allow easier matching of whole IP addresses, you can add
boundary characters to the phrases. For example, use "/1.2.3.4/"
instead of "1.2.3.4". You can then insert these characters into the
target prior to a match:</para>
<programlisting format="linespecific">SecAction "phase:1,pass,nolog,setvar:tx.remote_addr=/%{REMOTE_ADDR}/"
SecRule TX:REMOTE_ADDR "<emphasis>@pmFromFile ip-blacklist.txt</emphasis>" "deny,status:403
# ip-blacklist.txt contents:
# NOTE: All IPs must be prefixed/suffixed with "/" as the rules
# will add in this character as a boundary to ensure
# the entire IP is matched.
# SecAction "phase:1,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'"
/1.2.3.4/
/5.6.7.8/</programlisting>
</listitem>
</orderedlist>
<para>Example:</para>
<programlisting format="linespecific">SecRule REQUEST_HEADERS:User-Agent "<emphasis>@pm</emphasis> /path/to/blacklist1 blacklist2" "deny,status:403</programlisting>

Просмотреть файл

@ -6,7 +6,7 @@
<articleinfo>
<releaseinfo>2.6.0-trunk (April 22, 2009)</releaseinfo>
<copyright>
<year>2004-2009</year>
<year>2004-2010</year>
<holder>Breach Security, Inc. (<ulink url="http://www.breach.com"
>http://www.breach.com</ulink>)</holder>
</copyright>

Просмотреть файл

@ -4,10 +4,15 @@ SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
# PCRE Tuning
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
# Handling of file uploads
# TODO Choose a folder private to Apache.
# SecUploadDir /opt/apache-frontend/tmp/
SecUploadKeepFiles Off
SecUploadFileLimit 10
# Debug log
SecDebugLog logs/modsec_debug.log
@ -53,8 +58,19 @@ DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}'"
IQ %{MULTIPART_INVALID_QUOTING}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
IH %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
# Did we see anything that might be a boundary?
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with "MSC_". The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
"phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"