mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2026-01-09 17:54:37 +03:00
Merge in trunk changes for 2.5.0-dev2.
This commit is contained in:
154
CHANGES
154
CHANGES
@@ -1,3 +1,133 @@
|
||||
21 June 2007 - 2.5.0-dev2
|
||||
-------------------------
|
||||
|
||||
* Reversioned from 2.2.0 base version to 2.5.0 because of the large changeset.
|
||||
|
||||
* Added @within string comparison operator with support for macro expansion.
|
||||
|
||||
* Removed experimental variable RESPONSE_CONTENT_ENCODING which was not
|
||||
working as intended.
|
||||
|
||||
* Update included core rules to latest version.
|
||||
|
||||
* Do not trigger "pause" action for internal requests.
|
||||
|
||||
* Added matching rule filename and line number to audit log.
|
||||
|
||||
* Added new phrase matching operators, @pm and @pmFromFile. These use
|
||||
an alternate set based matching engine (Aho-Corasick) to perform faster
|
||||
phrase type matches such as black/white lists, spam keywords, etc.
|
||||
|
||||
* Cache transformations per-request/phase so they are not repeated.
|
||||
|
||||
* Fixed issue with requests that use internal requests. These had the
|
||||
potential to be intercepted incorrectly when other Apache httpd modules
|
||||
that used internal requests were used with mod_security.
|
||||
|
||||
* Added Solaris to the list of platforms not supporting the hidden
|
||||
visibility attribute.
|
||||
|
||||
* Removed excessive debug log entries about "capture" action.
|
||||
|
||||
* Fixed decoding full-width unicode in t:urlDecodeUni.
|
||||
|
||||
* Lessen some overhead of debugging messages and calculations
|
||||
|
||||
* Removed strnlen() calls for non-GNU platforms.
|
||||
|
||||
|
||||
14 June 2007 - 2.1.2-rc1
|
||||
------------------------
|
||||
|
||||
* Update included core rules to latest version.
|
||||
|
||||
* Do not trigger "pause" action for internal requests.
|
||||
|
||||
* Fixed issue with requests that use internal requests. These had the
|
||||
potential to be intercepted incorrectly when other Apache httpd modules
|
||||
that used internal requests were used with mod_security.
|
||||
|
||||
* Added Solaris to the list of platforms not supporting the hidden
|
||||
visibility attribute.
|
||||
|
||||
* Fixed decoding full-width unicode in t:urlDecodeUni.
|
||||
|
||||
* Lessen some overhead of debugging messages and calculations.
|
||||
|
||||
* Do not try to intercept a request after a failed rule. This fixes the
|
||||
issue associated with an "Internal Error: Asked to intercept request
|
||||
but was_intercepted is zero" error message.
|
||||
|
||||
* Added SecAuditLog2 directive to allow redundent concurrent audit log
|
||||
index files. This will allow sending audit data to two consoles, etc.
|
||||
|
||||
* Small performance improvement in memory management for rule execution.
|
||||
|
||||
|
||||
11 May 2007 - 2.2.0-dev1
|
||||
------------------------
|
||||
|
||||
* Added @within string comparison operator with support for macro expansion.
|
||||
|
||||
* Removed experimental variable RESPONSE_CONTENT_ENCODING which was not
|
||||
working as intended.
|
||||
|
||||
* Update included core rules to latest version.
|
||||
|
||||
* Do not trigger "pause" action for internal requests.
|
||||
|
||||
* Added matching rule filename and line number to audit log.
|
||||
|
||||
* Added new phrase matching operators, @pm and @pmFromFile. These use
|
||||
an alternate set based matching engine (Aho-Corasick) to perform faster
|
||||
phrase type matches such as black/white lists, spam keywords, etc.
|
||||
|
||||
* Cache transformations per-request/phase so they are not repeated.
|
||||
|
||||
* Fixed issue with requests that use internal requests. These had the
|
||||
potential to be intercepted incorrectly when other Apache httpd modules
|
||||
that used internal requests were used with mod_security.
|
||||
|
||||
* Added Solaris to the list of platforms not supporting the hidden
|
||||
visibility attribute.
|
||||
|
||||
* Removed excessive debug log entries about "capture" action.
|
||||
|
||||
* Fixed decoding full-width unicode in t:urlDecodeUni.
|
||||
|
||||
* Lessen some overhead of debugging messages and calculations
|
||||
TODO: more to come
|
||||
|
||||
* Removed strnlen() calls for non-GNU platforms.
|
||||
|
||||
|
||||
14 June 2007 - 2.1.2-rc1
|
||||
------------------------
|
||||
|
||||
* Update included core rules to latest version.
|
||||
|
||||
* Do not trigger "pause" action for internal requests.
|
||||
|
||||
* Fixed issue with requests that use internal requests. These had the
|
||||
potential to be intercepted incorrectly when other Apache httpd modules
|
||||
that used internal requests were used with mod_security.
|
||||
|
||||
* Added Solaris to the list of platforms not supporting the hidden
|
||||
visibility attribute.
|
||||
|
||||
* Fixed decoding full-width unicode in t:urlDecodeUni.
|
||||
|
||||
* Lessen some overhead of debugging messages and calculations.
|
||||
|
||||
* Do not try to intercept a request after a failed rule. This fixes the
|
||||
issue associated with an "Internal Error: Asked to intercept request
|
||||
but was_intercepted is zero" error message.
|
||||
|
||||
* Added SecAuditLog2 directive to allow redundent concurrent audit log
|
||||
index files. This will allow sending audit data to two consoles, etc.
|
||||
|
||||
* Small performance improvement in memory management for rule execution.
|
||||
|
||||
|
||||
11 May 2007 - 2.2.0-dev1
|
||||
-------------------------
|
||||
@@ -20,8 +150,8 @@
|
||||
|
||||
* Added experimental support for content injection. Directive
|
||||
SecContentInjection (On|Off) controls whether injection is taking place.
|
||||
Actions "prepend" and "append" inject content when executed. Do note that
|
||||
it is your responsibility to make sure the response is of the appropriate
|
||||
Actions "prepend" and "append" inject content when executed. Do note that
|
||||
it is your responsibility to make sure the response is of the appropriate
|
||||
content type (e.g. HTML, plain text, etc).
|
||||
|
||||
* Added string comparison operators with support for macro expansion:
|
||||
@@ -32,7 +162,7 @@
|
||||
|
||||
* Removed support for %0 - %9 capture macros as they were incorrectly
|
||||
expanding url encoded values. Use %{TX.0} - %{TX.9} instead.
|
||||
|
||||
|
||||
* Added t:length to transform a value to its character length.
|
||||
|
||||
* Added t:trimLeft, t:trimRight, t:trim to remove whitespace
|
||||
@@ -58,25 +188,21 @@
|
||||
and/or counting operator in the debug log.
|
||||
|
||||
|
||||
05 Apr 2007 - 2.1.1-rc2
|
||||
-----------------------
|
||||
11 Apr 2007 - 2.1.1
|
||||
-------------------
|
||||
|
||||
* Add the PCRE_DOLLAR_ENDONLY option when compiling regular expression
|
||||
for the @rx operator and variables.
|
||||
|
||||
|
||||
* Really set PCRE_DOTALL option when compiling the regular expression
|
||||
for the @rx operator as the docs state.
|
||||
|
||||
|
||||
11 Mar 2007 - 2.1.1-rc1
|
||||
-----------------------
|
||||
|
||||
|
||||
* Fixed potential memory corruption when expanding macros.
|
||||
|
||||
* Fixed error when a collection var was fetched in the same second as creation
|
||||
by setting the rate to zero.
|
||||
* Fixed error when a collection was retrieved from storage in the same second
|
||||
as creation by setting the rate to zero.
|
||||
|
||||
* Fixed ASCIIZ (NUL) parsing for application/x-www-form-urlencoded forms
|
||||
* Fixed ASCIIZ (NUL) parsing for application/x-www-form-urlencoded forms.
|
||||
|
||||
* Fixed the faulty REQUEST_FILENAME variable, which used to change
|
||||
the internal Apache structures by mistake.
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
|
||||
ModSecurity for Apache (http://www.modsecurity.org)
|
||||
Copyright (C) 2004-2006 Breach Security, Inc. (http://www.breach.com)
|
||||
You should have received a copy of the licence along with this
|
||||
program (stored in the file "LICENSE"). If the file is missing,
|
||||
or if you have any other questions related to the licence, please
|
||||
write to Breach Security, Inc. at support@breach.com.
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ APACHECTL = apachectl
|
||||
|
||||
INCLUDES = -I /usr/include/libxml2
|
||||
DEFS = -DWITH_LIBXML2
|
||||
#DEFS = -DWITH_LIBXML2 -DDEBUG_CONF
|
||||
#DEFS = -DWITH_LIBXML2 -DCACHE_DEBUG
|
||||
#LIBS = -Lmy/lib/dir -lmylib
|
||||
|
||||
CFLAGS = -O2 -g -Wuninitialized -Wall -Wmissing-prototypes -Wshadow -Wunused-variable -Wunused-value -Wchar-subscripts -Wsign-compare
|
||||
|
||||
@@ -24,7 +24,7 @@ OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \
|
||||
re.obj re_operators.obj re_actions.obj re_tfns.obj re_variables.obj \
|
||||
msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj msc_parsers.obj \
|
||||
msc_util.obj msc_pcre.obj persist_dbm.obj msc_reqbody.obj pdf_protect.obj \
|
||||
msc_geo.obj
|
||||
msc_geo.obj acmp.obj
|
||||
|
||||
all: $(DLL)
|
||||
|
||||
|
||||
711
apache2/acmp.c
Normal file
711
apache2/acmp.c
Normal file
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "acmp.h"
|
||||
#include "utf8tables.h"
|
||||
#include <apr_tables.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
* Data structures for acmp parser
|
||||
*/
|
||||
|
||||
/**
|
||||
* One node in trie
|
||||
*/
|
||||
typedef struct acmp_node_t acmp_node_t;
|
||||
typedef struct acmp_btree_node_t acmp_btree_node_t;
|
||||
struct acmp_node_t {
|
||||
acmp_utf8_char_t letter;
|
||||
int is_last;
|
||||
acmp_callback_t callback;
|
||||
void *callback_data;
|
||||
int depth;
|
||||
|
||||
acmp_node_t *child;
|
||||
acmp_node_t *sibling;
|
||||
acmp_node_t *fail;
|
||||
acmp_node_t *parent;
|
||||
acmp_node_t *o_match;
|
||||
|
||||
acmp_btree_node_t *btree;
|
||||
|
||||
apr_size_t hit_count;
|
||||
|
||||
char *text;
|
||||
char *pattern;
|
||||
};
|
||||
|
||||
struct acmp_btree_node_t {
|
||||
acmp_utf8_char_t letter;
|
||||
acmp_btree_node_t *left;
|
||||
acmp_btree_node_t *right;
|
||||
acmp_node_t *node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data related to parser, not to individual nodes
|
||||
*/
|
||||
struct ACMP {
|
||||
int is_utf8;
|
||||
int is_case_sensitive;
|
||||
apr_pool_t *parent_pool;
|
||||
apr_pool_t *pool;
|
||||
|
||||
int dict_count;
|
||||
apr_size_t longest_entry;
|
||||
|
||||
acmp_node_t *root_node;
|
||||
|
||||
const char *data_start;
|
||||
const char *data_end;
|
||||
const char *data_pos;
|
||||
apr_size_t data_len;
|
||||
|
||||
apr_size_t *bp_buffer;
|
||||
apr_size_t bp_buff_len;
|
||||
|
||||
acmp_node_t *active_node;
|
||||
char u8_buff[6];
|
||||
apr_size_t u8buff_len;
|
||||
apr_size_t hit_count;
|
||||
int is_failtree_done;
|
||||
int is_active;
|
||||
apr_size_t byte_pos;
|
||||
apr_size_t char_pos;
|
||||
};
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
* Functions for UTF-8 support
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns length of utf-8 sequence based on its first byte
|
||||
*/
|
||||
static int utf8_seq_len(const char *first_byte) {
|
||||
return utf8_seq_lengths[(unsigned int)(unsigned char)first_byte[0]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns length of utf8-encoded text
|
||||
*/
|
||||
static size_t utf8_strlen(const char *str) {
|
||||
int len = 0;
|
||||
const char *c = str;
|
||||
while (*c != 0) {
|
||||
c += utf8_seq_len(c);
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ucs code for given utf-8 sequence
|
||||
*/
|
||||
static acmp_utf8_char_t utf8_decodechar(const char *str) {
|
||||
int len = utf8_seq_len(str);
|
||||
acmp_utf8_char_t ch = 0;
|
||||
switch (len) {
|
||||
case 6: ch += (unsigned char)*str++; ch <<= 6;
|
||||
case 5: ch += (unsigned char)*str++; ch <<= 6;
|
||||
case 4: ch += (unsigned char)*str++; ch <<= 6;
|
||||
case 3: ch += (unsigned char)*str++; ch <<= 6;
|
||||
case 2: ch += (unsigned char)*str++; ch <<= 6;
|
||||
case 1: ch += (unsigned char)*str++;
|
||||
}
|
||||
ch -= utf8_offsets[len - 1];
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns lowercase for given unicode character. Searches through
|
||||
* utf8_lcase_map table, if it doesn't find the code assumes
|
||||
* it doesn't have a lowercase variant and returns code itself.
|
||||
*/
|
||||
static long utf8_lcase(acmp_utf8_char_t ucs_code) {
|
||||
long mid, left, right;
|
||||
left = 1;
|
||||
right = UTF8_LCASEMAP_LEN * 2 + 1;
|
||||
|
||||
while (left <= right) {
|
||||
mid = (left + right) >> 1;
|
||||
mid -= (mid % 2); mid++;
|
||||
if (ucs_code > utf8_lcase_map[mid])
|
||||
left = mid + 2;
|
||||
else if (ucs_code < utf8_lcase_map[mid])
|
||||
right = mid - 2;
|
||||
else if (ucs_code == utf8_lcase_map[mid])
|
||||
return utf8_lcase_map[mid - 1];
|
||||
}
|
||||
return ucs_code;
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
* Code for local / static utility functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns length of given string for parser's encoding
|
||||
*/
|
||||
static size_t acmp_strlen(ACMP *parser, const char *str) {
|
||||
return (parser->is_utf8 == 0) ? strlen(str) : utf8_strlen(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns string to array of ucs values, depending on parser's encoding
|
||||
* str - string to convert, doesn't have to be NULL-terminated
|
||||
* ucs_chars - where to write ucs values
|
||||
* len - length of input string
|
||||
*/
|
||||
static void acmp_strtoucs(ACMP *parser, const char *str, acmp_utf8_char_t *ucs_chars, int len) {
|
||||
int i;
|
||||
const char *c = str;
|
||||
|
||||
if (parser->is_utf8 == 0) {
|
||||
for (i = 0; i < len; i++) {
|
||||
*ucs_chars++ = *c++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
*ucs_chars++ = utf8_decodechar(c);
|
||||
c += utf8_seq_len(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node with given letter, or null if not found
|
||||
*/
|
||||
static acmp_node_t *acmp_child_for_code(acmp_node_t *parent_node, acmp_utf8_char_t ucs_code) {
|
||||
acmp_node_t *node = parent_node->child;
|
||||
if (node == NULL) return NULL;
|
||||
for (;;) {
|
||||
if (node->letter == ucs_code) return node;
|
||||
node = node->sibling;
|
||||
if (node == NULL) return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds node to parent node, if it is not already there
|
||||
*/
|
||||
static void acmp_add_node_to_parent(acmp_node_t *parent, acmp_node_t *child) {
|
||||
child->parent = parent;
|
||||
if (parent->child == NULL) {
|
||||
parent->child = child;
|
||||
return;
|
||||
}
|
||||
acmp_node_t *node = parent->child;
|
||||
for (;;) {
|
||||
if (node == child) return;
|
||||
if (node->sibling == NULL) {
|
||||
node->sibling = child;
|
||||
return;
|
||||
}
|
||||
node = node->sibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies values from one node to another, without child/sibling/fail pointers
|
||||
* and without state variables.
|
||||
*/
|
||||
static void acmp_clone_node_no_state(acmp_node_t *from, acmp_node_t *to) {
|
||||
memcpy(to, from, sizeof(acmp_node_t));
|
||||
to->child = NULL;
|
||||
to->sibling = NULL;
|
||||
to->fail = NULL;
|
||||
to->hit_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies sibling nodes and child node for from given "from" node to "to" node.
|
||||
* Both nodes must already exist.
|
||||
*/
|
||||
static void acmp_copy_nodes_recursive(acmp_node_t *from, acmp_node_t *to, apr_pool_t *pool) {
|
||||
acmp_node_t *old_node = from->child, *new_node, *nn2;
|
||||
if (old_node == NULL) return;
|
||||
nn2 = apr_pcalloc(pool, sizeof(acmp_node_t));
|
||||
acmp_clone_node_no_state(old_node, nn2);
|
||||
nn2->parent = to;
|
||||
to->child = nn2;
|
||||
acmp_copy_nodes_recursive(from->child, to->child, pool);
|
||||
|
||||
for (;;) {
|
||||
old_node = old_node->sibling;
|
||||
if (old_node == NULL) break;
|
||||
new_node = apr_pcalloc(pool, sizeof(acmp_node_t));
|
||||
acmp_clone_node_no_state(old_node, new_node);
|
||||
new_node->parent = to;
|
||||
nn2->sibling = new_node;
|
||||
nn2 = new_node;
|
||||
acmp_copy_nodes_recursive(old_node, new_node, pool);
|
||||
}
|
||||
}
|
||||
|
||||
static inline acmp_node_t *acmp_btree_find(acmp_node_t *node, acmp_utf8_char_t letter) {
|
||||
acmp_btree_node_t *bnode = node->btree;
|
||||
for (;;) {
|
||||
if (bnode == NULL) return NULL;
|
||||
if (bnode->letter == letter) return bnode->node;
|
||||
if (bnode->letter > letter) {
|
||||
bnode = bnode->left;
|
||||
} else {
|
||||
bnode = bnode->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static inline acmp_node_t *acmp_goto(acmp_node_t *node, acmp_utf8_char_t letter) {
|
||||
//return acmp_child_for_code(node, letter);
|
||||
return acmp_btree_find(node, letter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects each node with its first fail node that is end of a phrase.
|
||||
*/
|
||||
static void acmp_connect_other_matches(ACMP *parser, acmp_node_t *node) {
|
||||
acmp_node_t *child, *om;
|
||||
|
||||
for (child = node->child; child != NULL; child = child->sibling) {
|
||||
if (child->fail == NULL) continue;
|
||||
for (om = child->fail; om != parser->root_node; om = om->fail) {
|
||||
if (om->is_last) {
|
||||
child->o_match = om;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Go recursively through children of this node that have a child node */
|
||||
for(child = node->child; child != NULL; child = child->sibling) {
|
||||
if (child->child != NULL) acmp_connect_other_matches(parser, child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds leaves to binary tree, working from sorted array of keyword tree nodes
|
||||
*/
|
||||
static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
|
||||
int pos, int lb, int rb, apr_pool_t *pool) {
|
||||
|
||||
int left = 0, right = 0;
|
||||
if ((pos - lb) > 1) {
|
||||
left = lb + (pos - lb) / 2;
|
||||
node->left = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
|
||||
node->left->node = nodes[left];
|
||||
node->left->letter = nodes[left]->letter;
|
||||
/* printf("%c ->left %c \n", node->node->letter, node->left->node->letter); */
|
||||
}
|
||||
if ((rb - pos) > 1) {
|
||||
right = pos + (rb - pos) / 2;
|
||||
node->right = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
|
||||
node->right->node = nodes[right];
|
||||
node->right->letter = nodes[right]->letter;
|
||||
/* printf("%c ->right %c \n", node->node->letter, node->right->node->letter); */
|
||||
}
|
||||
if (node->right != NULL) {
|
||||
acmp_add_btree_leaves(node->right, nodes, right, pos, rb, pool);
|
||||
}
|
||||
if (node->left != NULL) {
|
||||
acmp_add_btree_leaves(node->left, nodes, left, lb, pos, pool);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds balanced binary tree from children nodes of given node.
|
||||
*/
|
||||
static void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) {
|
||||
apr_size_t count, i, j;
|
||||
acmp_node_t *child = node->child;
|
||||
|
||||
for (count = 0; child != NULL; child = child->sibling) count++;
|
||||
acmp_node_t *nodes[count];
|
||||
child = node->child;
|
||||
for (i = 0; i < count; i++) {
|
||||
nodes[i] = child;
|
||||
child = child->sibling;
|
||||
};
|
||||
/* We have array with all children of the node and number of those children
|
||||
*/
|
||||
for (i = 0; i < count - 1; i++)
|
||||
for (j = i + 1; j < count; j++) {
|
||||
if (nodes[i]->letter < nodes[j]->letter) continue;
|
||||
acmp_node_t *tmp = nodes[i];
|
||||
nodes[i] = nodes[j];
|
||||
nodes[j] = tmp;
|
||||
}
|
||||
node->btree = apr_pcalloc(parser->pool, sizeof(acmp_btree_node_t));
|
||||
apr_size_t pos = count / 2;
|
||||
node->btree->node = nodes[pos];
|
||||
node->btree->letter = nodes[pos]->letter;
|
||||
acmp_add_btree_leaves(node->btree, nodes, pos, -1, count, parser->pool);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (nodes[i]->child != NULL) acmp_build_binary_tree(parser, nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs fail paths on keyword trie
|
||||
*/
|
||||
static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
||||
/* Already connected ? */
|
||||
if (parser->is_failtree_done != 0) return APR_SUCCESS;
|
||||
acmp_node_t *child, *node, *goto_node;
|
||||
apr_array_header_t *arr, *arr2, *tmp;
|
||||
|
||||
parser->root_node->text = "";
|
||||
arr = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));
|
||||
arr2 = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));
|
||||
|
||||
parser->root_node->fail = parser->root_node;
|
||||
|
||||
/* All first-level children will fail back to root node */
|
||||
for (child = parser->root_node->child; child != NULL; child = child->sibling) {
|
||||
child->fail = parser->root_node;
|
||||
*(acmp_node_t **)apr_array_push(arr) = child;
|
||||
/* printf("fail direction: *%s* => *%s*\n", child->text, child->fail->text); */
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
while (apr_is_empty_array(arr) == 0) {
|
||||
node = *(acmp_node_t **)apr_array_pop(arr);
|
||||
node->fail = parser->root_node;
|
||||
if (node->parent != parser->root_node) {
|
||||
goto_node = acmp_child_for_code(node->parent->fail, node->letter);
|
||||
node->fail = (goto_node != NULL) ? goto_node : parser->root_node;
|
||||
}
|
||||
/* printf("fail direction: *%s* => *%s*\n", node->text, node->fail->text); */
|
||||
child = node->child;
|
||||
while (child != NULL) {
|
||||
*(acmp_node_t **)apr_array_push(arr2) = child;
|
||||
child = child->sibling;
|
||||
}
|
||||
}
|
||||
if (apr_is_empty_array(arr2) != 0) break;
|
||||
|
||||
tmp = arr;
|
||||
arr = arr2;
|
||||
arr2 = tmp;
|
||||
}
|
||||
acmp_connect_other_matches(parser, parser->root_node);
|
||||
if (parser->root_node->child != NULL) acmp_build_binary_tree(parser, parser->root_node);
|
||||
parser->is_failtree_done = 1;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears hit count of each node, called from acmp_reset()
|
||||
*/
|
||||
static void acmp_clear_hit_count_recursive(acmp_node_t *node) {
|
||||
for (; node != NULL; node = node->sibling) {
|
||||
node->hit_count = 0;
|
||||
if (node->child != NULL) acmp_clear_hit_count_recursive(node->child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a match is found
|
||||
*/
|
||||
static void acmp_found(ACMP *parser, acmp_node_t *node) {
|
||||
if (node->callback) {
|
||||
node->callback(parser, node->callback_data,
|
||||
parser->bp_buffer[(parser->char_pos - node->depth - 1) % parser->bp_buff_len],
|
||||
parser->char_pos - node->depth - 1);
|
||||
}
|
||||
/* printf("found: %s at position %d\n", node->pattern, parser->char_pos - node->depth - 1); */
|
||||
node->hit_count++;
|
||||
parser->hit_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
*******************************************************************************
|
||||
* Code for functions from header file
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* flags - OR-ed values of ACMP_FLAG constants
|
||||
* pool - apr_pool to use as parent pool, can be set to NULL
|
||||
*/
|
||||
ACMP *acmp_create(int flags, apr_pool_t *pool) {
|
||||
apr_status_t rc;
|
||||
apr_pool_t *p;
|
||||
rc = apr_pool_create(&p, pool);
|
||||
if (rc != APR_SUCCESS) return NULL;
|
||||
|
||||
ACMP *parser = apr_pcalloc(p, sizeof(ACMP));
|
||||
parser->pool = p;
|
||||
parser->parent_pool = pool;
|
||||
parser->is_utf8 = (flags & ACMP_FLAG_UTF8) == 0 ? 0 : 1;
|
||||
parser->is_case_sensitive = (flags & ACMP_FLAG_CASE_SENSITIVE) == 0 ? 0 : 1;
|
||||
parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys previously created parser
|
||||
*/
|
||||
void acmp_destroy(ACMP *parser) {
|
||||
/*
|
||||
* All data is kept in parser's pool (including parser struct itself), so
|
||||
* destroying the pool will destroy everything
|
||||
*/
|
||||
apr_pool_destroy(parser->pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates parser with same options and same patterns
|
||||
* parser - ACMP parser to duplicate
|
||||
* pool - parent pool to use, if left as NULL original parser's parent pool is used
|
||||
*/
|
||||
ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool) {
|
||||
apr_status_t rc;
|
||||
apr_pool_t *p;
|
||||
|
||||
if (pool == NULL) pool = parser->parent_pool;
|
||||
rc = apr_pool_create(&p, pool);
|
||||
if (rc != APR_SUCCESS) return NULL;
|
||||
|
||||
ACMP *new_parser = apr_pcalloc(p, sizeof(ACMP));
|
||||
new_parser->pool = p;
|
||||
new_parser->parent_pool = pool;
|
||||
new_parser->is_utf8 = parser->is_utf8;
|
||||
new_parser->is_case_sensitive = parser->is_case_sensitive;
|
||||
new_parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
|
||||
new_parser->dict_count = parser->dict_count;
|
||||
new_parser->longest_entry = parser->longest_entry;
|
||||
acmp_copy_nodes_recursive(parser->root_node, new_parser->root_node, new_parser->pool);
|
||||
acmp_prepare(new_parser);
|
||||
return new_parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates fail tree and initializes buffer
|
||||
*/
|
||||
apr_status_t acmp_prepare(ACMP *parser) {
|
||||
if (parser->bp_buff_len < parser->longest_entry) {
|
||||
parser->bp_buff_len = parser->longest_entry * 2;
|
||||
parser->bp_buffer = apr_pcalloc(parser->pool, sizeof(apr_size_t) * parser->bp_buff_len);
|
||||
}
|
||||
apr_status_t st = acmp_connect_fail_branches(parser);
|
||||
parser->active_node = parser->root_node;
|
||||
if (st != APR_SUCCESS) return st;
|
||||
parser->is_active = 1;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pattern to parser
|
||||
* parser - ACMP parser
|
||||
* pattern - string with pattern to match
|
||||
* callback - Optional, pointer to an acmp_callback_t function
|
||||
* data - pointer to data that will be passed to callback function, only used if callback
|
||||
* is supplied
|
||||
* len - Length of pattern in characters, if zero string length is used.
|
||||
*/
|
||||
apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
|
||||
acmp_callback_t callback, void *data, apr_size_t len)
|
||||
{
|
||||
if (parser->is_active != 0) return APR_EGENERAL;
|
||||
size_t length = (len == 0) ? acmp_strlen(parser, pattern) : len;
|
||||
size_t i, j;
|
||||
acmp_utf8_char_t ucs_chars[length];
|
||||
|
||||
acmp_node_t *parent = parser->root_node, *child;
|
||||
acmp_strtoucs(parser, pattern, ucs_chars, length);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
acmp_utf8_char_t letter = ucs_chars[i];
|
||||
if (parser->is_case_sensitive == 0) {
|
||||
letter = utf8_lcase(letter);
|
||||
}
|
||||
child = acmp_child_for_code(parent, letter);
|
||||
if (child == NULL) {
|
||||
child = apr_pcalloc(parser->pool, sizeof(acmp_node_t));
|
||||
child->pattern = "";
|
||||
child->letter = letter;
|
||||
child->depth = i;
|
||||
child->text = apr_pcalloc(parser->pool, strlen(pattern) + 2);
|
||||
for (j = 0; j <= i; j++) child->text[j] = pattern[j];
|
||||
}
|
||||
if (i == length - 1) {
|
||||
if (child->is_last == 0) {
|
||||
parser->dict_count++;
|
||||
child->is_last = 1;
|
||||
child->pattern = apr_pcalloc(parser->pool, strlen(pattern) + 2);
|
||||
strcpy(child->pattern, pattern);
|
||||
}
|
||||
child->callback = callback;
|
||||
child->callback_data = data;
|
||||
}
|
||||
acmp_add_node_to_parent(parent, child);
|
||||
parent = child;
|
||||
}
|
||||
if (length > parser->longest_entry) parser->longest_entry = length;
|
||||
parser->is_failtree_done = 0;
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to process incoming data stream
|
||||
* data - ptr to incoming data
|
||||
* len - size of data in bytes
|
||||
*/
|
||||
apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
|
||||
if (parser->is_failtree_done == 0) acmp_prepare(parser);
|
||||
acmp_node_t *node = parser->active_node, *go_to;
|
||||
apr_size_t seq_length;
|
||||
const char *end = (data + len);
|
||||
|
||||
while (data < end) {
|
||||
parser->bp_buffer[parser->char_pos % parser->bp_buff_len] = parser->byte_pos;
|
||||
acmp_utf8_char_t letter;
|
||||
if (parser->is_utf8) {
|
||||
if (parser->u8buff_len > 0) {
|
||||
/* Resuming partial utf-8 sequence */
|
||||
seq_length = utf8_seq_len(parser->u8_buff);
|
||||
for (;;) {
|
||||
parser->u8_buff[parser->u8buff_len++] = *data++;
|
||||
if (parser->u8buff_len == seq_length) {
|
||||
parser->u8buff_len = 0;
|
||||
letter = utf8_decodechar(parser->u8_buff);
|
||||
parser->byte_pos += seq_length;
|
||||
parser->char_pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* not resuming partial sequence, reading from the stream */
|
||||
seq_length = utf8_seq_len(data);
|
||||
if ((data + seq_length) > end) {
|
||||
while (data < end) parser->u8_buff[parser->u8buff_len++] = *data++;
|
||||
return APR_SUCCESS;
|
||||
} else {
|
||||
letter = utf8_decodechar(data);
|
||||
data += seq_length;
|
||||
parser->byte_pos += seq_length;
|
||||
parser->char_pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
letter = *data++;
|
||||
parser->byte_pos++;
|
||||
parser->char_pos++;
|
||||
}
|
||||
if (parser->is_case_sensitive == 0) letter = utf8_lcase(letter);
|
||||
|
||||
go_to = NULL;
|
||||
while (go_to == NULL) {
|
||||
acmp_node_t *n2 = acmp_goto(node, letter);
|
||||
go_to = acmp_child_for_code(node, letter);
|
||||
if (n2 != go_to) {
|
||||
n2 = acmp_goto(node, letter);
|
||||
};
|
||||
if (go_to != NULL) {
|
||||
if (go_to->is_last) {
|
||||
acmp_found(parser, go_to);
|
||||
}
|
||||
}
|
||||
if (node == parser->root_node) break;
|
||||
if (go_to == NULL) node = node->fail;
|
||||
}
|
||||
if (go_to != NULL) node = go_to;
|
||||
|
||||
/* We need to collect other nodes that are last letters of phrase. These
|
||||
* will be fail node of current node if it has is_last flag set, and
|
||||
* fail node of that node, recursively down to root node.
|
||||
*/
|
||||
go_to = node;
|
||||
if (go_to != parser->root_node) {
|
||||
for (go_to = go_to->o_match; go_to != NULL; go_to = go_to->o_match) {
|
||||
acmp_found(parser, go_to);
|
||||
}
|
||||
}
|
||||
}
|
||||
parser->active_node = node;
|
||||
return parser->hit_count > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of parser so you can start using it with new set of data.
|
||||
*
|
||||
* No need to clear buffer since it will be re-initialized at first run of
|
||||
* acmp_process
|
||||
*/
|
||||
void acmp_reset(ACMP *parser) {
|
||||
parser->is_active = 0;
|
||||
parser->byte_pos = 0;
|
||||
parser->char_pos = 0;
|
||||
parser->hit_count = 0;
|
||||
parser->u8buff_len = 0;
|
||||
acmp_clear_hit_count_recursive(parser->root_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ACMPT struct that will use parser's tree, without duplicating its data
|
||||
*/
|
||||
ACMPT *acmp_duplicate_quick(ACMP *parser, apr_pool_t *pool) {
|
||||
apr_pool_t *p = (pool != NULL) ? pool : parser->pool;
|
||||
ACMPT *dup = apr_pcalloc(p, sizeof(ACMPT));
|
||||
dup->parser = parser;
|
||||
return dup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree
|
||||
*/
|
||||
apr_status_t acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, apr_size_t len) {
|
||||
if (acmpt->parser->is_failtree_done == 0) {
|
||||
acmp_prepare(acmpt->parser);
|
||||
};
|
||||
ACMP *parser = acmpt->parser;
|
||||
if (acmpt->ptr == NULL) acmpt->ptr = parser->root_node;
|
||||
acmp_node_t *node = acmpt->ptr, *go_to;
|
||||
const char *end = (data + len);
|
||||
|
||||
while (data < end) {
|
||||
acmp_utf8_char_t letter = (unsigned char)*data++;
|
||||
go_to = NULL;
|
||||
while (go_to == NULL) {
|
||||
go_to = acmp_goto(node, letter);
|
||||
if (go_to != NULL) {
|
||||
if (go_to->is_last) {
|
||||
*match = go_to->text;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (node == parser->root_node) break;
|
||||
if (go_to == NULL) node = node->fail;
|
||||
}
|
||||
if (go_to != NULL) node = go_to;
|
||||
|
||||
/* If node has o_match, then we found a pattern */
|
||||
if (node->o_match != NULL) {
|
||||
*match = node->text;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
acmpt->ptr = node;
|
||||
return 0;
|
||||
}
|
||||
115
apache2/acmp.h
Normal file
115
apache2/acmp.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef ACMP_H_
|
||||
#define ACMP_H_
|
||||
|
||||
#include <apr.h>
|
||||
#include <apr_pools.h>
|
||||
|
||||
#define ACMP_FLAG_BYTE 0
|
||||
#define ACMP_FLAG_UTF8 0x100
|
||||
#define ACMP_FLAG_CASE_SENSITIVE 1
|
||||
#define ACMP_FLAG_CASE_INSENSITIVE 0
|
||||
|
||||
/**
|
||||
* Opaque struct with parser data
|
||||
*/
|
||||
typedef struct ACMP ACMP;
|
||||
|
||||
/**
|
||||
* Used to separate state from the trie for acmp_process_quick function
|
||||
*/
|
||||
typedef struct {
|
||||
ACMP *parser;
|
||||
void *ptr;
|
||||
} ACMPT;
|
||||
|
||||
/**
|
||||
* Callback function. Arguments are:
|
||||
* ACMP * - acmp parser that initiated callback
|
||||
* void * - custom data you supplied when adding callback
|
||||
* apr_size_t - position in bytes where pattern was found
|
||||
* apr_size_t - position in chars where pattern was found, for multibyte strings
|
||||
*/
|
||||
typedef void (*acmp_callback_t)(ACMP *, void *, apr_size_t, apr_size_t);
|
||||
|
||||
/**
|
||||
* flags - OR-ed values of ACMP_FLAG constants
|
||||
* pool - apr_pool to use as parent pool, can be set to NULL
|
||||
*/
|
||||
ACMP *acmp_create(int flags, apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Destroys previously created parser
|
||||
*/
|
||||
void acmp_destroy(ACMP *parser);
|
||||
|
||||
/**
|
||||
* Creates parser with same options and same patterns
|
||||
* parser - ACMP parser to duplicate
|
||||
* pool - parent pool to use, if left as NULL original parser's parent pool is used
|
||||
*/
|
||||
ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Adds pattern to parser. Cannot be done after starting the search.
|
||||
* parser - ACMP parser
|
||||
* pattern - string with pattern to match
|
||||
* callback - Optional, pointer to an acmp_callback_t function
|
||||
* data - pointer to data that will be passed to callback function, only used if callback
|
||||
* is supplied
|
||||
* len - Length of pattern in characters, if zero string length is used.
|
||||
*/
|
||||
apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
|
||||
acmp_callback_t callback, void *data, apr_size_t len);
|
||||
|
||||
/**
|
||||
* Called to process incoming data stream. You must call acmp_done after sending
|
||||
* last data packet
|
||||
*
|
||||
* data - ptr to incoming data
|
||||
* len - size of data in bytes
|
||||
*/
|
||||
apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len);
|
||||
|
||||
/**
|
||||
* Returns number of matches on all patterns combined
|
||||
*/
|
||||
apr_size_t acmp_match_count_total(ACMP *parser);
|
||||
|
||||
/**
|
||||
* Returns number of matches for given pattern
|
||||
*/
|
||||
apr_size_t acmp_match_count(ACMP *parser, const char *pattern);
|
||||
|
||||
/**
|
||||
* Resets the state of parser so you can start using it with new set of data,
|
||||
* or add new patterns.
|
||||
*/
|
||||
void acmp_reset(ACMP *parser);
|
||||
|
||||
/**
|
||||
* Creates an ACMPT struct that will use parser's tree, without duplicating its data
|
||||
*/
|
||||
ACMPT *acmp_duplicate_quick(ACMP *parser, apr_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree
|
||||
*/
|
||||
apr_status_t acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, apr_size_t len);
|
||||
|
||||
/**
|
||||
* Prepares parser for searching
|
||||
*/
|
||||
apr_status_t acmp_prepare(ACMP *parser);
|
||||
|
||||
|
||||
#endif /*ACMP_H_*/
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id$
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _APACHE2_H_
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: apache2_config.c,v 1.8 2006/12/28 10:39:13 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <limits.h>
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include "msc_logging.h"
|
||||
|
||||
#include "pdf_protect.h"
|
||||
#include "http_log.h"
|
||||
|
||||
/* #define DEBUG_CONF 1 */
|
||||
@@ -90,6 +88,7 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
|
||||
dcfg->pdfp_timeout = NOT_SET;
|
||||
dcfg->pdfp_token_name = NOT_SET_P;
|
||||
dcfg->pdfp_only_get = NOT_SET;
|
||||
dcfg->pdfp_method = NOT_SET;
|
||||
|
||||
/* Geo Lookups */
|
||||
dcfg->geo = NOT_SET_P;
|
||||
@@ -384,6 +383,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
||||
? parent->pdfp_token_name : child->pdfp_token_name);
|
||||
merged->pdfp_only_get = (child->pdfp_only_get == NOT_SET
|
||||
? parent->pdfp_only_get : child->pdfp_only_get);
|
||||
merged->pdfp_method = (child->pdfp_method == NOT_SET
|
||||
? parent->pdfp_method : child->pdfp_method);
|
||||
|
||||
/* Geo Lookup */
|
||||
merged->geo = (child->geo == NOT_SET_P
|
||||
@@ -456,7 +457,8 @@ void init_directory_config(directory_config *dcfg) {
|
||||
if (dcfg->pdfp_secret == NOT_SET_P) dcfg->pdfp_secret = NULL;
|
||||
if (dcfg->pdfp_timeout == NOT_SET) dcfg->pdfp_timeout = 10;
|
||||
if (dcfg->pdfp_token_name == NOT_SET_P) dcfg->pdfp_token_name = "PDFPTOKEN";
|
||||
if (dcfg->pdfp_only_get == NOT_SET) dcfg->pdfp_only_get = 0;
|
||||
if (dcfg->pdfp_only_get == NOT_SET) dcfg->pdfp_only_get = 1;
|
||||
if (dcfg->pdfp_method == NOT_SET) dcfg->pdfp_method = PDF_PROTECT_METHOD_TOKEN_REDIRECTION;
|
||||
|
||||
/* Geo Lookup */
|
||||
if (dcfg->geo == NOT_SET_P) dcfg->geo = NULL;
|
||||
@@ -1195,6 +1197,25 @@ static const char *cmd_pdf_protect_intercept_get_only(cmd_parms *cmd, void *_dcf
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_pdf_protect_method(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if (strcasecmp(p1, "TokenRedirection") == 0) {
|
||||
dcfg->pdfp_method = PDF_PROTECT_METHOD_TOKEN_REDIRECTION;
|
||||
} else
|
||||
if (strcasecmp(p1, "ForcedDownload") == 0) {
|
||||
dcfg->pdfp_method = PDF_PROTECT_METHOD_FORCED_DOWNLOAD;
|
||||
} else {
|
||||
return (const char *)apr_psprintf(cmd->pool,
|
||||
"ModSecurity: Unrecognised parameter value for SecPdfProtectMethod: %s", p1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* -- Geo Lookup configuration -- */
|
||||
|
||||
static const char *cmd_geo_lookups_db(cmd_parms *cmd, void *_dcfg,
|
||||
@@ -1547,7 +1568,15 @@ const command_rec module_directives[] = {
|
||||
cmd_pdf_protect_intercept_get_only,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
"whether or not to intercept only GET requess."
|
||||
"whether or not to intercept only GET and HEAD requess. Defaults to true."
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecPdfProtectMethod",
|
||||
cmd_pdf_protect_method,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
"protection method to use. Can be 'TokenRedirection' (default) or 'ForcedDownload'"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: apache2_io.c,v 1.6 2007/01/23 16:08:15 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: apache2_util.c,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity.h"
|
||||
@@ -255,6 +253,7 @@ void msr_log(modsec_rec *msr, int level, const char *text, ...) {
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an Apache error log message into one line of text.
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: mod_security2.c,v 1.11 2006/12/15 15:06:04 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <limits.h>
|
||||
@@ -55,14 +53,30 @@ int perform_interception(modsec_rec *msr) {
|
||||
msre_actionset *actionset = NULL;
|
||||
const char *message = NULL;
|
||||
const char *phase_text = "";
|
||||
const char *intreq_text = "";
|
||||
int is_initial_req = ap_is_initial_req(msr->r);
|
||||
int status = DECLINED;
|
||||
int log_level = 1;
|
||||
|
||||
/* Check for an initial request */
|
||||
|
||||
if (is_initial_req != 1) {
|
||||
if (msr->r->main != NULL) {
|
||||
intreq_text = "Sub-Request: ";
|
||||
}
|
||||
else if (msr->r->prev != NULL) {
|
||||
intreq_text = "Internal Redirect: ";
|
||||
}
|
||||
else {
|
||||
intreq_text = "Internal Request: ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sanity checks first. */
|
||||
|
||||
if (msr->was_intercepted == 0) {
|
||||
msr_log(msr, 1, "Internal Error: Asked to intercept request but was_intercepted is zero");
|
||||
msr->was_intercepted = 0;
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
@@ -78,12 +92,13 @@ int perform_interception(modsec_rec *msr) {
|
||||
phase_text = apr_psprintf(msr->mp, " (phase %i)", msr->phase);
|
||||
|
||||
/* By default we log at level 1 but we switch to 4
|
||||
* if a nolog action was used to hide the message.
|
||||
* if a nolog action was used or this is not the initial request
|
||||
* to hide the message.
|
||||
*/
|
||||
log_level = (actionset->log != 1) ? 4 : 1;
|
||||
log_level = ((actionset->log != 1) || (is_initial_req != 1)) ? 4 : 1;
|
||||
|
||||
/* Pause the request first (if configured to do so). */
|
||||
if (actionset->intercept_pause) {
|
||||
/* Pause the request first (if configured and the initial request). */
|
||||
if (actionset->intercept_pause && (is_initial_req == 1)) {
|
||||
msr_log(msr, (log_level > 3 ? log_level : log_level + 1), "Pausing transaction for "
|
||||
"%i msec.", actionset->intercept_pause);
|
||||
/* apr_sleep accepts microseconds */
|
||||
@@ -95,14 +110,14 @@ int perform_interception(modsec_rec *msr) {
|
||||
case ACTION_DENY :
|
||||
if (actionset->intercept_status != 0) {
|
||||
status = actionset->intercept_status;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code %i%s.", status,
|
||||
phase_text);
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code %i%s.",
|
||||
intreq_text, status, phase_text);
|
||||
} else {
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
"(Internal Error: Invalid status code requested %i).", phase_text,
|
||||
actionset->intercept_status);
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Internal Error: Invalid status code requested %i).",
|
||||
intreq_text, phase_text, actionset->intercept_status);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -111,23 +126,25 @@ int perform_interception(modsec_rec *msr) {
|
||||
if (ap_find_linked_module("mod_proxy.c") == NULL) {
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Configuration Error: Proxy action to %s requested but mod_proxy not found).",
|
||||
phase_text, log_escape_nq(msr->mp, actionset->intercept_uri));
|
||||
intreq_text, phase_text,
|
||||
log_escape_nq(msr->mp, actionset->intercept_uri));
|
||||
} else {
|
||||
msr->r->filename = apr_psprintf(msr->mp, "proxy:%s", actionset->intercept_uri);
|
||||
msr->r->proxyreq = PROXYREQ_REVERSE;
|
||||
msr->r->handler = "proxy-server";
|
||||
status = OK;
|
||||
message = apr_psprintf(msr->mp, "Access denied using proxy to %s%s.",
|
||||
phase_text, log_escape_nq(msr->mp, actionset->intercept_uri));
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied using proxy to%s %s.",
|
||||
intreq_text, phase_text,
|
||||
log_escape_nq(msr->mp, actionset->intercept_uri));
|
||||
}
|
||||
} else {
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Configuration Error: Proxy action requested but it does not work in output phases).",
|
||||
phase_text);
|
||||
intreq_text, phase_text);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -144,29 +161,30 @@ int perform_interception(modsec_rec *msr) {
|
||||
if (csd) {
|
||||
if (apr_socket_close(csd) == APR_SUCCESS) {
|
||||
status = HTTP_FORBIDDEN;
|
||||
message = apr_psprintf(msr->mp, "Access denied with connection close%s.",
|
||||
phase_text);
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with connection close%s.",
|
||||
intreq_text, phase_text);
|
||||
} else {
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Error: Connection drop requested but failed to close the "
|
||||
" socket).", phase_text);
|
||||
" socket).",
|
||||
intreq_text, phase_text);
|
||||
}
|
||||
} else {
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Error: Connection drop requested but socket not found.",
|
||||
phase_text);
|
||||
intreq_text, phase_text);
|
||||
}
|
||||
}
|
||||
#else
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Error: Connection drop not implemented on this platform).",
|
||||
phase_text);
|
||||
intreq_text, phase_text);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -179,23 +197,25 @@ int perform_interception(modsec_rec *msr) {
|
||||
} else {
|
||||
status = HTTP_MOVED_TEMPORARILY;
|
||||
}
|
||||
message = apr_psprintf(msr->mp, "Access denied with redirection to %s using "
|
||||
"status %i%s.", log_escape_nq(msr->mp, actionset->intercept_uri), status,
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with redirection to %s using "
|
||||
"status %i%s.",
|
||||
intreq_text,
|
||||
log_escape_nq(msr->mp, actionset->intercept_uri), status,
|
||||
phase_text);
|
||||
break;
|
||||
|
||||
case ACTION_ALLOW :
|
||||
status = DECLINED;
|
||||
message = apr_psprintf(msr->mp, "Access allowed%s.", phase_text);
|
||||
message = apr_psprintf(msr->mp, "%sAccess allowed%s.", intreq_text, phase_text);
|
||||
msr->was_intercepted = 0;
|
||||
break;
|
||||
|
||||
default :
|
||||
log_level = 1;
|
||||
status = HTTP_INTERNAL_SERVER_ERROR;
|
||||
message = apr_psprintf(msr->mp, "Access denied with code 500%s "
|
||||
message = apr_psprintf(msr->mp, "%sAccess denied with code 500%s "
|
||||
"(Internal Error: invalid interception action %i).",
|
||||
phase_text, actionset->intercept_action);
|
||||
intreq_text, phase_text, actionset->intercept_action);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -333,6 +353,8 @@ static modsec_rec *create_tx_context(request_rec *r) {
|
||||
msr_log(msr, 4, "Transaction context created (dcfg %x).", msr->dcfg1);
|
||||
}
|
||||
|
||||
msr->msc_rule_mptmp = NULL;
|
||||
|
||||
return msr;
|
||||
}
|
||||
|
||||
@@ -562,6 +584,10 @@ static int hook_request_late(request_rec *r) {
|
||||
|
||||
/* Has this phase been completed already? */
|
||||
if (msr->phase_request_body_complete) {
|
||||
if (msr->was_intercepted) {
|
||||
msr_log(msr, 4, "Phase REQUEST_BODY request already intercepted. Intercepting additional request.");
|
||||
return perform_interception(msr);
|
||||
}
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Phase REQUEST_BODY already complete, skipping.");
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: modsecurity.c,v 1.7 2006/12/28 10:39:13 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
@@ -297,6 +295,9 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) {
|
||||
msr->collections_dirty = apr_table_make(msr->mp, 8);
|
||||
if (msr->collections_dirty == NULL) return -1;
|
||||
|
||||
msr->tcache = apr_hash_make(msr->mp);
|
||||
if (msr->tcache == NULL) return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: modsecurity.h,v 1.27 2007/02/05 12:44:40 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MODSECURITY_H_
|
||||
@@ -26,7 +24,7 @@ typedef struct msc_data_chunk msc_data_chunk;
|
||||
typedef struct msc_arg msc_arg;
|
||||
typedef struct msc_string msc_string;
|
||||
|
||||
#if !(defined(WIN32) || defined(NETWARE))
|
||||
#if !(defined(WIN32) || defined(NETWARE) || defined(SOLARIS2))
|
||||
#define DSOLOCAL __attribute__((visibility("hidden")))
|
||||
#else
|
||||
#define DSOLOCAL
|
||||
@@ -45,13 +43,14 @@ typedef struct msc_string msc_string;
|
||||
#include "ap_config.h"
|
||||
#include "apr_md5.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_hash.h"
|
||||
#include "httpd.h"
|
||||
#include "http_config.h"
|
||||
#include "http_log.h"
|
||||
#include "http_protocol.h"
|
||||
|
||||
#define MODULE_NAME "ModSecurity"
|
||||
#define MODULE_RELEASE "2.2.0-dev1"
|
||||
#define MODULE_RELEASE "2.5.0-dev2"
|
||||
#define MODULE_NAME_FULL (MODULE_NAME " v" MODULE_RELEASE " (Apache 2.x)")
|
||||
|
||||
#define PHASE_REQUEST_HEADERS 1
|
||||
@@ -59,6 +58,8 @@ typedef struct msc_string msc_string;
|
||||
#define PHASE_RESPONSE_HEADERS 3
|
||||
#define PHASE_RESPONSE_BODY 4
|
||||
#define PHASE_LOGGING 5
|
||||
#define PHASE_FIRST PHASE_REQUEST_HEADERS
|
||||
#define PHASE_LAST PHASE_LOGGING
|
||||
|
||||
#define NOT_SET -1
|
||||
#define NOT_SET_P (void *)-1
|
||||
@@ -319,6 +320,9 @@ struct modsec_rec {
|
||||
apr_off_t content_prepend_len;
|
||||
const char *content_append;
|
||||
apr_off_t content_append_len;
|
||||
|
||||
/* data cache */
|
||||
apr_hash_t *tcache;
|
||||
};
|
||||
|
||||
struct directory_config {
|
||||
@@ -406,6 +410,7 @@ struct directory_config {
|
||||
int pdfp_timeout;
|
||||
const char *pdfp_token_name;
|
||||
int pdfp_only_get;
|
||||
int pdfp_method;
|
||||
|
||||
/* Geo Lookup */
|
||||
geo_db *geo;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
MOD_SECURITY2 = mod_security2 apache2_config apache2_io apache2_util \
|
||||
re re_operators re_actions re_tfns re_variables \
|
||||
msc_logging msc_xml msc_multipart modsecurity msc_parsers msc_util msc_pcre \
|
||||
persist_dbm msc_reqbody pdf_protect msc_geo
|
||||
persist_dbm msc_reqbody pdf_protect msc_geo acmp
|
||||
|
||||
H = re.h modsecurity.h msc_logging.h msc_multipart.h msc_parsers.h \
|
||||
msc_pcre.h msc_util.h msc_xml.h persist_dbm.h apache2.h pdf_protect.h \
|
||||
msc_geo.h
|
||||
msc_geo.h acmp.h utf8tables.h
|
||||
|
||||
${MOD_SECURITY2:=.slo}: ${H}
|
||||
${MOD_SECURITY2:=.lo}: ${H}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_geo.h"
|
||||
@@ -228,6 +228,23 @@ static int db_open(directory_config *dcfg, char **error_msg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int field_length(const char *field, int maxlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (field == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < maxlen; i++) {
|
||||
if (field[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise Geo data structure
|
||||
*/
|
||||
@@ -375,21 +392,21 @@ int geo_lookup(modsec_rec *msr, geo_rec *georec, const char *target, char **erro
|
||||
remaining -= rec_offset;
|
||||
|
||||
/* Region */
|
||||
field_len = strnlen((const char *)cbuf+rec_offset,remaining);
|
||||
field_len = field_length((const char *)cbuf+rec_offset, remaining);
|
||||
msr_log(msr, 9, "GEO: region=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4));
|
||||
georec->region = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining));
|
||||
rec_offset += field_len + 1;
|
||||
remaining -= field_len + 1;
|
||||
|
||||
/* City */
|
||||
field_len = strnlen((const char *)cbuf+rec_offset,remaining);
|
||||
field_len = field_length((const char *)cbuf+rec_offset, remaining);
|
||||
msr_log(msr, 9, "GEO: city=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4));
|
||||
georec->city = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining));
|
||||
rec_offset += field_len + 1;
|
||||
remaining -= field_len + 1;
|
||||
|
||||
/* Postal Code */
|
||||
field_len = strnlen((const char *)cbuf+rec_offset,remaining);
|
||||
field_len = field_length((const char *)cbuf+rec_offset, remaining);
|
||||
msr_log(msr, 9, "GEO: postal_code=\"%.*s\"", ((field_len+1)*4), log_escape_raw(msr->mp, cbuf, sizeof(cbuf))+(rec_offset*4));
|
||||
georec->postal_code = apr_pstrmemdup(msr->mp, (const char *)cbuf+rec_offset, (remaining));
|
||||
rec_offset += field_len + 1;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_GEO_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_logging.c,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_logging.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_logging.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_LOGGING_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_multipart.c,v 1.2 2006/10/16 04:41:51 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_multipart.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_MULTIPART_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_parsers.c,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_parsers.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_parsers.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_PARSERS_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_pcre.c,v 1.2 2006/12/28 10:39:13 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_pcre.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_pcre.h,v 1.3 2006/12/28 10:39:13 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_PCRE_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_reqbody.c,v 1.2 2006/12/04 21:54:10 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_util.c,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_util.h"
|
||||
@@ -561,8 +559,18 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len)
|
||||
if ( (VALID_HEX(input[i + 2]))&&(VALID_HEX(input[i + 3]))
|
||||
&&(VALID_HEX(input[i + 4]))&&(VALID_HEX(input[i + 5])) )
|
||||
{
|
||||
/* We make use of the lower byte here, ignoring the higher byte. */
|
||||
*d++ = x2c(&input[i + 4]);
|
||||
/* We first make use of the lower byte here, ignoring the higher byte. */
|
||||
*d = x2c(&input[i + 4]);
|
||||
|
||||
/* Full width ASCII (ff01 - ff5e) needs 0x20 added */
|
||||
if ( (*d > 0x00) && (*d < 0x5f)
|
||||
&& ((input[i + 2] == 'f') || (input[i + 2] == 'F'))
|
||||
&& ((input[i + 3] == 'f') || (input[i + 3] == 'F')))
|
||||
{
|
||||
*d += 0x20;
|
||||
}
|
||||
|
||||
d++;
|
||||
count++;
|
||||
i += 6;
|
||||
} else {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_util.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _UTIL_H_
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_xml.c,v 1.2 2006/12/04 20:04:09 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifdef WITH_LIBXML2
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: msc_xml.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_XML_H_
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id$
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "modsecurity.h"
|
||||
// #include "apache2.h"
|
||||
#include "pdf_protect.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -225,17 +222,21 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
|
||||
if (msr == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, f->r->server,
|
||||
"ModSecurity: Internal Error: msr is null in PDF output filter.");
|
||||
"ModSecurity: Internal Error: Unable to retrieve context in PDF output filter.");
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return send_error_bucket(f, HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (msr->txcfg->pdfp_enabled == 1) {
|
||||
// TODO Should we look at err_headers_out too?
|
||||
const char *h_content_type = apr_table_get(f->r->headers_out, "Content-Type");
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: r->content_type=%s, header C-T=%s",
|
||||
f->r->content_type, h_content_type);
|
||||
log_escape_nq(msr->mp, f->r->content_type),
|
||||
log_escape_nq(msr->mp, h_content_type));
|
||||
}
|
||||
|
||||
/* Have we been asked to tweak the headers? */
|
||||
@@ -255,6 +256,10 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
}
|
||||
|
||||
/* Proceed to detect dynamically-generated PDF files. */
|
||||
|
||||
// TODO application/x-pdf, application/vnd.fdf, application/vnd.adobe.xfdf,
|
||||
// application/vnd.adobe.xdp+xml, application/vnd.adobe.xfd+xml, application/vnd.pdf
|
||||
// application/acrobat, text/pdf, text/x-pdf ???
|
||||
if (((f->r->content_type != NULL)&&(strcasecmp(f->r->content_type, "application/pdf") == 0))
|
||||
|| ((h_content_type != NULL)&&(strcasecmp(h_content_type, "application/pdf") == 0)))
|
||||
{
|
||||
@@ -263,16 +268,35 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: Detected a dynamically-generated PDF in %s",
|
||||
r->uri);
|
||||
log_escape_nq(msr->mp, r->uri));
|
||||
}
|
||||
|
||||
/* If we are configured with ForcedDownload protection method then we
|
||||
* can do our thing here and finish early.
|
||||
*/
|
||||
if (msr->txcfg->pdfp_method == PDF_PROTECT_METHOD_FORCED_DOWNLOAD) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: Forcing download of a dynamically "
|
||||
"generated PDF file.");
|
||||
}
|
||||
|
||||
apr_table_set(f->r->headers_out, "Content-Disposition", DISPOSITION_VALUE);
|
||||
f->r->content_type = ATTACHMENT_MIME_TYPE;
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return ap_pass_brigade(f->next, bb_in);
|
||||
}
|
||||
|
||||
/* If we are here that means TokenRedirection is the desired protection method. */
|
||||
|
||||
/* Is this a non-GET request? */
|
||||
if ((f->r->method_number != M_GET)&&
|
||||
((msr->txcfg->pdfp_only_get == 1)||(msr->txcfg->pdfp_only_get == -1))
|
||||
) {
|
||||
/* This is a non-GET request and we have been configured
|
||||
* not to intercept it. We are not going to do that but
|
||||
* we are going to tweak the headers to force download.
|
||||
* not to intercept it. So we are going to tweak the headers
|
||||
* to force download.
|
||||
*/
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: Forcing download of a dynamically "
|
||||
@@ -283,6 +307,7 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
f->r->content_type = ATTACHMENT_MIME_TYPE;
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return ap_pass_brigade(f->next, bb_in);
|
||||
}
|
||||
|
||||
@@ -298,10 +323,11 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
/* Redirect user to the new URI. */
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: PDF request without a token - "
|
||||
"redirecting to %s.", new_uri);
|
||||
"redirecting to %s.", log_escape_nq(msr->mp, new_uri));
|
||||
}
|
||||
|
||||
apr_table_set(r->headers_out, "Location", new_uri);
|
||||
|
||||
return send_error_bucket(f, REDIRECT_STATUS);
|
||||
}
|
||||
} else { /* Token found. */
|
||||
@@ -353,6 +379,16 @@ int pdfp_check(modsec_rec *msr) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "PdfProtect: Not enabled here.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msr->txcfg->pdfp_method != PDF_PROTECT_METHOD_TOKEN_REDIRECTION) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "PdfProtect: Configured with ForcedDownload as protection method, "
|
||||
"skipping detection on the inbound.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -365,17 +401,18 @@ int pdfp_check(modsec_rec *msr) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "PdfProtect: Unable to inspect URI because it is NULL.");
|
||||
}
|
||||
/* TODO Should we return -1 instead? */
|
||||
return 0;
|
||||
|
||||
return -1; /* Error. */
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: URI=%s, filename=%s, QUERY_STRING=%s.",
|
||||
msr->r->uri, msr->r->filename, msr->r->args);
|
||||
log_escape_nq(msr->mp, msr->r->uri), log_escape_nq(msr->mp, msr->r->filename),
|
||||
log_escape_nq(msr->mp, msr->r->args));
|
||||
}
|
||||
|
||||
uri = apr_pstrdup(msr->mp, msr->r->uri);
|
||||
if (uri == NULL) return -1;
|
||||
if (uri == NULL) return -1; /* Error. */
|
||||
ap_str_tolower(uri);
|
||||
|
||||
/* Attempt to figure out if this is a request for a PDF file. We are
|
||||
@@ -389,17 +426,19 @@ int pdfp_check(modsec_rec *msr) {
|
||||
msr_log(msr, 4, "PdfProtect: No indication in the URI this is a "
|
||||
"request for a PDF file.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore request methods other than GET if
|
||||
/* Ignore request methods other than GET and HEAD if
|
||||
* configured to do so.
|
||||
*/
|
||||
if ((msr->r->method_number != M_GET)&&(cfg->pdfp_only_get != 0)) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "PdfProtect: Configured not to intercept non-GET requests "
|
||||
"(method=%s/%i).", msr->r->method, msr->r->method_number);
|
||||
msr_log(msr, 4, "PdfProtect: Not intercepting a GET/HEAD request "
|
||||
"(method=%s/%i).", log_escape_nq(msr->mp, msr->r->method), msr->r->method_number);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -421,7 +460,7 @@ int pdfp_check(modsec_rec *msr) {
|
||||
/* Redirect user to the new URI. */
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: PDF request without a token - redirecting to %s.",
|
||||
new_uri);
|
||||
log_escape_nq(msr->mp, new_uri));
|
||||
}
|
||||
|
||||
apr_table_set(msr->r->headers_out, "Location", new_uri);
|
||||
@@ -437,6 +476,7 @@ int pdfp_check(modsec_rec *msr) {
|
||||
msr_log(msr, 9, "PdfProtect: PDF request with a valid token - "
|
||||
"serving PDF file normally.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else { /* Not valid. */
|
||||
/* The token is not valid. We will tweak the response
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2007 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id$
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PDF_PROTECT_H_
|
||||
#define _PDF_PROTECT_H_
|
||||
|
||||
#define PDF_PROTECT_METHOD_TOKEN_REDIRECTION 1
|
||||
#define PDF_PROTECT_METHOD_FORCED_DOWNLOAD 2
|
||||
|
||||
apr_status_t DSOLOCAL pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in);
|
||||
|
||||
int DSOLOCAL pdfp_check(modsec_rec *msr);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: persist_dbm.c,v 1.3 2006/12/21 19:57:41 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "persist_dbm.h"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: persist_dbm.h,v 1.1.1.1 2006/10/14 09:30:43 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _PERSIST_DBM_H_
|
||||
|
||||
179
apache2/re.c
179
apache2/re.c
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re.c,v 1.15 2006/12/29 10:44:25 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <ctype.h>
|
||||
@@ -294,7 +292,7 @@ int msre_parse_generic(apr_pool_t *mp, const char *text, apr_table_t *vartable,
|
||||
|
||||
/* we are at the beginning of the name */
|
||||
name = p;
|
||||
while((*p != '\0')&&(*p != '|')&&(*p != ':')&&(*p != ',')&&(!isspace(*p))) p++; // ENH replace with isvarnamechar()
|
||||
while((*p != '\0')&&(*p != '|')&&(*p != ':')&&(*p != ',')&&(!isspace(*p))) p++; /* ENH replace with isvarnamechar() */
|
||||
|
||||
/* get the name */
|
||||
name = apr_pstrmemdup(mp, name, p - name);
|
||||
@@ -421,6 +419,7 @@ msre_actionset *msre_actionset_create(msre_engine *engine, const char *text,
|
||||
actionset->msg = NOT_SET_P;
|
||||
actionset->phase = NOT_SET;
|
||||
actionset->severity = -1;
|
||||
actionset->rule = NOT_SET_P;
|
||||
|
||||
/* Flow */
|
||||
actionset->is_chained = NOT_SET;
|
||||
@@ -495,6 +494,7 @@ msre_actionset *msre_actionset_merge(msre_engine *engine, msre_actionset *parent
|
||||
if (child->msg != NOT_SET_P) merged->msg = child->msg;
|
||||
if (child->severity != NOT_SET) merged->severity = child->severity;
|
||||
if (child->phase != NOT_SET) merged->phase = child->phase;
|
||||
if (child->rule != NOT_SET_P) merged->rule = child->rule;
|
||||
|
||||
/* Flow */
|
||||
merged->is_chained = child->is_chained;
|
||||
@@ -550,6 +550,7 @@ static void msre_actionset_set_defaults(msre_actionset *actionset) {
|
||||
if (actionset->msg == NOT_SET_P) actionset->msg = NULL;
|
||||
if (actionset->phase == NOT_SET) actionset->phase = 2;
|
||||
if (actionset->severity == -1); /* leave at -1 */
|
||||
if (actionset->rule == NOT_SET_P) actionset->rule = NULL;
|
||||
|
||||
/* Flow */
|
||||
if (actionset->is_chained == NOT_SET) actionset->is_chained = 0;
|
||||
@@ -844,6 +845,8 @@ int msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase) {
|
||||
*/
|
||||
|
||||
msre_actionset_set_defaults(rule->actionset);
|
||||
rule->actionset->rule = rule;
|
||||
|
||||
*(const msre_rule **)apr_array_push(arr) = rule;
|
||||
|
||||
return 1;
|
||||
@@ -972,14 +975,23 @@ char *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset) {
|
||||
char *msg = "";
|
||||
char *severity = "";
|
||||
char *tags = "";
|
||||
char *fn = "";
|
||||
int k;
|
||||
|
||||
if (actionset == NULL) return "";
|
||||
|
||||
if (actionset->id != NULL) id = apr_psprintf(msr->mp, " [id \"%s\"]",
|
||||
log_escape(msr->mp, actionset->id));
|
||||
if (actionset->rev != NULL) rev = apr_psprintf(msr->mp, " [rev \"%s\"]",
|
||||
log_escape(msr->mp, actionset->rev));
|
||||
if ((actionset->rule != NULL) && (actionset->rule->filename != NULL)) {
|
||||
fn = apr_psprintf(msr->mp, " [file \"%s\"] [line \"%d\"]",
|
||||
actionset->rule->filename, actionset->rule->line_num);
|
||||
}
|
||||
if (actionset->id != NULL) {
|
||||
id = apr_psprintf(msr->mp, " [id \"%s\"]",
|
||||
log_escape(msr->mp, actionset->id));
|
||||
}
|
||||
if (actionset->rev != NULL) {
|
||||
rev = apr_psprintf(msr->mp, " [rev \"%s\"]",
|
||||
log_escape(msr->mp, actionset->rev));
|
||||
}
|
||||
if (actionset->msg != NULL) {
|
||||
/* Expand variables in the message string. */
|
||||
msc_string *var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
@@ -988,11 +1000,11 @@ char *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset) {
|
||||
expand_macros(msr, var, NULL, msr->mp);
|
||||
|
||||
msg = apr_psprintf(msr->mp, " [msg \"%s\"]",
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
}
|
||||
if ((actionset->severity >= 0)&&(actionset->severity <= 7)) {
|
||||
severity = apr_psprintf(msr->mp, " [severity \"%s\"]",
|
||||
msre_format_severity(actionset->severity));
|
||||
msre_format_severity(actionset->severity));
|
||||
}
|
||||
|
||||
/* Extract rule tags from the action list. */
|
||||
@@ -1007,7 +1019,7 @@ char *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset) {
|
||||
}
|
||||
}
|
||||
|
||||
return apr_pstrcat(msr->mp, id, rev, msg, severity, tags, NULL);
|
||||
return apr_pstrcat(msr->mp, fn, id, rev, msg, severity, tags, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1175,7 +1187,7 @@ static void msre_perform_disruptive_actions(modsec_rec *msr, msre_rule *rule,
|
||||
static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
|
||||
msre_actionset *acting_actionset, apr_pool_t *mptmp)
|
||||
{
|
||||
apr_time_t time_before_regex;
|
||||
apr_time_t time_before_regex = 0;
|
||||
char *my_error_msg = NULL;
|
||||
const char *full_varname = NULL;
|
||||
int rc;
|
||||
@@ -1210,7 +1222,9 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr,
|
||||
var->value_len));
|
||||
}
|
||||
|
||||
time_before_regex = apr_time_now(); /* IMP1 time_before_regex? */
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
time_before_regex = apr_time_now(); /* IMP1 time_before_regex? */
|
||||
}
|
||||
rc = rule->op_metadata->execute(msr, rule, var, &my_error_msg);
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Operator completed in %" APR_TIME_T_FMT " usec.",
|
||||
@@ -1280,9 +1294,6 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
|
||||
/* Use a fresh memory sub-pool for processing each rule */
|
||||
if (msr->msc_rule_mptmp == NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Creating new rule processing memory pool");
|
||||
}
|
||||
if (apr_pool_create(&msr->msc_rule_mptmp, msr->mp) != APR_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1351,11 +1362,27 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
{
|
||||
const apr_array_header_t *tarr;
|
||||
const apr_table_entry_t *telts;
|
||||
msre_cache_rec **carr = NULL;
|
||||
msre_cache_rec *crec = NULL;
|
||||
char *tfnsvar = NULL;
|
||||
char *tfnskey = NULL;
|
||||
int tfnscount = 0;
|
||||
int usecache = 0;
|
||||
apr_table_t *normtab;
|
||||
int k;
|
||||
msre_action *action;
|
||||
msre_tfn_metadata *metadata;
|
||||
|
||||
/* Is this var cacheable? */
|
||||
if (var->metadata->is_cacheable == VAR_CACHE) {
|
||||
usecache = 1;
|
||||
tfnsvar = apr_psprintf(msr->mp, "%lx;%s", (unsigned long)var, var->name);
|
||||
tfnskey = tfnsvar;
|
||||
}
|
||||
else {
|
||||
msr_log(msr, 9, "CACHE: %s transformations are not cacheable", var->name);
|
||||
}
|
||||
|
||||
normtab = apr_table_make(mptmp, 10);
|
||||
if (normtab == NULL) return -1;
|
||||
tarr = apr_table_elts(rule->actionset->actions);
|
||||
@@ -1367,6 +1394,8 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
if (strcmp(telts[k].key, "t") == 0) {
|
||||
if (strcmp(action->param, "none") == 0) {
|
||||
apr_table_clear(normtab);
|
||||
tfnskey = tfnsvar;
|
||||
tfnscount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1374,12 +1403,55 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
apr_table_unset(normtab, action->param);
|
||||
} else {
|
||||
apr_table_addn(normtab, action->param, (void *)action);
|
||||
tfnskey = apr_psprintf(msr->mp, "%s,%s", tfnskey, action->param);
|
||||
tfnscount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform transformations. */
|
||||
|
||||
/* Try to fetch the full multi-transformation from cache */
|
||||
if (usecache && tfnscount > 1 && !multi_match) {
|
||||
crec = NULL;
|
||||
msr_log(msr, 9, "CACHE: Fetching %s (multi)", tfnskey);
|
||||
carr = (msre_cache_rec **)apr_hash_get(msr->tcache, tfnskey, APR_HASH_KEY_STRING);
|
||||
if (carr != NULL) {
|
||||
crec = carr[msr->phase];
|
||||
}
|
||||
|
||||
/* Cache Miss - Reset the key to perform transformations */
|
||||
if (crec == NULL) {
|
||||
tfnskey = tfnsvar;
|
||||
}
|
||||
/* Cache Hit - Use cache value and execute immediatly */
|
||||
else {
|
||||
crec->hits++;
|
||||
if (crec->changed) {
|
||||
var->value = apr_pmemdup(msr->mp, crec->val, crec->val_len);
|
||||
var->value_len = crec->val_len;
|
||||
}
|
||||
|
||||
msr_log(msr, 9, "T (%i) %s: \"%s\" [cached hits=%d]", crec->changed, (tfnskey + strlen(tfnsvar) + 1), log_escape_nq_ex(mptmp, var->value, var->value_len), crec->hits);
|
||||
|
||||
rc = execute_operator(var, rule, msr, acting_actionset, mptmp);
|
||||
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (rc == RULE_MATCH) {
|
||||
/* Return straight away if the transaction
|
||||
* was intercepted - no need to process the remaining
|
||||
* targets.
|
||||
*/
|
||||
if (msr->was_intercepted) {
|
||||
return RULE_MATCH;
|
||||
}
|
||||
}
|
||||
continue; /* next target */
|
||||
}
|
||||
}
|
||||
|
||||
tarr = apr_table_elts(normtab);
|
||||
|
||||
/* Make a copy of the variable value so that
|
||||
@@ -1392,6 +1464,7 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
|
||||
/* Execute transformations in a loop. */
|
||||
|
||||
tfnskey = tfnsvar;
|
||||
changed = 1;
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
for (k = 0; k < tarr->nelts; k++) {
|
||||
@@ -1429,6 +1502,31 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
action = (msre_action *)telts[k].val;
|
||||
metadata = (msre_tfn_metadata *)action->param_data;
|
||||
|
||||
/* Try to use the cache */
|
||||
if (usecache) {
|
||||
/* Generate the cache key */
|
||||
tfnskey = apr_psprintf(msr->mp, "%s,%s", tfnskey, action->param);
|
||||
|
||||
/* Try to fetch this transformation from cache */
|
||||
msr_log(msr, 9, "CACHE: Fetching %s", tfnskey);
|
||||
crec = NULL;
|
||||
carr = (msre_cache_rec **)apr_hash_get(msr->tcache, tfnskey, APR_HASH_KEY_STRING);
|
||||
if (carr != NULL) {
|
||||
crec = carr[msr->phase];
|
||||
}
|
||||
if (crec != NULL) {
|
||||
crec->hits++;
|
||||
|
||||
if ((changed = crec->changed) == 1) {
|
||||
var->value = apr_pmemdup(msr->mp, crec->val, crec->val_len);
|
||||
var->value_len = crec->val_len;
|
||||
}
|
||||
|
||||
msr_log(msr, 9, "T (%i) %s: \"%s\" [cached hits=%i]", crec->changed, metadata->name, log_escape_nq_ex(mptmp, var->value, var->value_len), crec->hits);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rc = metadata->execute(mptmp, (unsigned char *)var->value, var->value_len,
|
||||
&rval, &rval_length);
|
||||
if (rc < 0) {
|
||||
@@ -1440,6 +1538,26 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
var->value = rval;
|
||||
var->value_len = rval_length;
|
||||
|
||||
/* Cache the transformation */
|
||||
if (usecache) {
|
||||
/* ENH1: Add flag to vars to tell which ones can change across phases store the rest in a global cache */
|
||||
if (carr == NULL) {
|
||||
carr = (msre_cache_rec **)apr_pcalloc(msr->mp, (sizeof(msre_cache_rec *) * (PHASE_LAST + 1)));
|
||||
if (carr == NULL) return -1;
|
||||
memset(carr, 0, (sizeof(msre_cache_rec *) * (PHASE_LAST + 1)));
|
||||
apr_hash_set(msr->tcache, tfnskey, APR_HASH_KEY_STRING, carr);
|
||||
}
|
||||
crec = carr[msr->phase] = (msre_cache_rec *)apr_pcalloc(msr->mp, sizeof(msre_cache_rec));
|
||||
if (crec == NULL) return -1;
|
||||
|
||||
crec->hits = 0;
|
||||
crec->changed = changed;
|
||||
crec->key = tfnskey;
|
||||
crec->val = changed ? apr_pmemdup(msr->mp, rval, rval_length) : NULL;
|
||||
crec->val_len = changed ? rval_length : -1;
|
||||
msr_log(msr, 9, "CACHE: Caching %s=\"%.*s\"", tfnskey, crec->val_len, crec->val);
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%i) %s: \"%s\"", rc, metadata->name,
|
||||
log_escape_nq_ex(mptmp, var->value, var->value_len));
|
||||
@@ -1475,6 +1593,33 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
}
|
||||
|
||||
|
||||
msr_log(msr, 9, "CACHE: size=%u", apr_hash_count(msr->tcache));
|
||||
#ifdef CACHE_DEBUG
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
apr_hash_index_t *hi;
|
||||
void *dummy;
|
||||
msre_cache_rec **rec;
|
||||
int hn = 0;
|
||||
int ri;
|
||||
for (hi = apr_hash_first(msr->mp, msr->tcache); hi; hi = apr_hash_next(hi)) {
|
||||
hn++;
|
||||
apr_hash_this(hi, NULL, NULL, &dummy);
|
||||
rec = (msre_cache_rec **)dummy;
|
||||
if (rec == NULL) continue;
|
||||
|
||||
for (ri = PHASE_FIRST; ri <= PHASE_LAST; ri++) {
|
||||
if (rec[ri] == NULL) continue;
|
||||
if (rec[ri]->changed) {
|
||||
msr_log(msr, 9, "CACHE: %5d) phase=%d hits=%d %s=\"%s\"", hn, msr->phase, rec[ri]->hits, rec[ri]->key, log_escape_nq_ex(mptmp, rec[ri]->val, rec[ri]->val_len));
|
||||
}
|
||||
else {
|
||||
msr_log(msr, 9, "CACHE: %5d) phase=%d hits=%d %s=<no change>", hn, msr->phase, rec[ri]->hits, rec[ri]->key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (match_count ? RULE_MATCH : RULE_NO_MATCH);
|
||||
}
|
||||
|
||||
|
||||
19
apache2/re.h
19
apache2/re.h
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re.h,v 1.7 2006/12/29 10:31:38 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef _MSC_RE_H_
|
||||
@@ -28,6 +26,7 @@ typedef struct msre_tfn_metadata msre_tfn_metadata;
|
||||
typedef struct msre_actionset msre_actionset;
|
||||
typedef struct msre_action_metadata msre_action_metadata;
|
||||
typedef struct msre_action msre_action;
|
||||
typedef struct msre_cache_rec msre_cache_rec;
|
||||
|
||||
#include "apr_general.h"
|
||||
#include "apr_tables.h"
|
||||
@@ -226,6 +225,7 @@ struct msre_actionset {
|
||||
const char *msg;
|
||||
int severity;
|
||||
int phase;
|
||||
msre_rule *rule;
|
||||
|
||||
/* Flow */
|
||||
int is_chained;
|
||||
@@ -303,4 +303,15 @@ apr_status_t DSOLOCAL msre_parse_vars(msre_ruleset *ruleset, const char *text,
|
||||
|
||||
char DSOLOCAL *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset);
|
||||
|
||||
|
||||
/* -- Data Cache -- */
|
||||
|
||||
struct msre_cache_rec {
|
||||
int hits;
|
||||
int changed;
|
||||
const char *key;
|
||||
const char *val;
|
||||
apr_size_t val_len;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re_actions.c,v 1.9 2007/02/02 18:16:41 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "re.h"
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re_operators.c,v 1.7 2007/01/23 16:08:15 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "re.h"
|
||||
#include "msc_pcre.h"
|
||||
#include "msc_geo.h"
|
||||
#include "apr_lib.h"
|
||||
#include "apr_strmatch.h"
|
||||
#include "acmp.h"
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -109,15 +109,12 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
/* Are we supposed to capture subexpressions? */
|
||||
capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0;
|
||||
|
||||
/* Warn when the regex captures but "capture" is not set */
|
||||
if (msr->txcfg->debuglog_level >= 3) {
|
||||
/* Show when the regex captures but "capture" is not set */
|
||||
if (msr->txcfg->debuglog_level >= 6) {
|
||||
int capcount = 0;
|
||||
rc = msc_fullinfo(regex, PCRE_INFO_CAPTURECOUNT, &capcount);
|
||||
if ((capture == 0) && (capcount > 0)) {
|
||||
msr_log(msr, 4, "Ignoring regex captures since \"capture\" action is not enabled.");
|
||||
}
|
||||
if ((capture == 1) && (capcount == 0)) {
|
||||
msr_log(msr, 3, "Notice. The \"capture\" action is enabled, but the regex does not have explicit captures.");
|
||||
msr_log(msr, 6, "Ignoring regex captures since \"capture\" action is not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,23 +179,247 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* contains */
|
||||
/* pm */
|
||||
|
||||
static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
const char *match = (const char *)rule->op_param;
|
||||
static int msre_op_pm_param_init(msre_rule *rule, char **error_msg) {
|
||||
if ((rule->op_param == NULL)||(strlen(rule->op_param) == 0)) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Missing parameter for operator 'pm'.");
|
||||
return 0; /* ERROR */
|
||||
}
|
||||
|
||||
ACMP *p = acmp_create(0, rule->ruleset->mp);
|
||||
if (p == NULL) return 0;
|
||||
|
||||
const char *phrase = apr_pstrdup(rule->ruleset->mp, rule->op_param);
|
||||
const char *next = rule->op_param + strlen(rule->op_param);
|
||||
|
||||
/* Loop through phrases */
|
||||
/* ENH: Need to allow quoted phrases w/space */
|
||||
for (;;) {
|
||||
while((isspace(*phrase) != 0) && (*phrase != '\0')) phrase++;
|
||||
if (*phrase == '\0') break;
|
||||
next = phrase;
|
||||
while((isspace(*next) == 0) && (*next != 0)) next++;
|
||||
acmp_add_pattern(p, phrase, NULL, NULL, next - phrase);
|
||||
phrase = next;
|
||||
}
|
||||
acmp_prepare(p);
|
||||
rule->op_param_data = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* pmFromFile */
|
||||
|
||||
static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
|
||||
char errstr[1024];
|
||||
char buf[HUGE_STRING_LEN + 1];
|
||||
char *fn;
|
||||
char *next;
|
||||
char *ptr;
|
||||
const char *rulefile_path;
|
||||
apr_status_t rc;
|
||||
apr_file_t *fd;
|
||||
|
||||
if ((rule->op_param == NULL)||(strlen(rule->op_param) == 0)) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Missing parameter for operator 'pm'.");
|
||||
return 0; /* ERROR */
|
||||
}
|
||||
|
||||
ACMP *p = acmp_create(0, rule->ruleset->mp);
|
||||
if (p == NULL) return 0;
|
||||
|
||||
fn = apr_pstrdup(rule->ruleset->mp, rule->op_param);
|
||||
next = fn + strlen(rule->op_param);
|
||||
|
||||
/* Get the path of the rule filename to use as a base */
|
||||
rulefile_path = apr_pstrndup(rule->ruleset->mp, rule->filename, strlen(rule->filename) - strlen(apr_filepath_name_get(rule->filename)));
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr, "Rulefile path: \"%s\"\n", rulefile_path);
|
||||
#endif
|
||||
|
||||
/* Loop through filenames */
|
||||
/* ENH: Need to allow quoted filenames w/space */
|
||||
for (;;) {
|
||||
const char *rootpath = NULL;
|
||||
const char *filepath = NULL;
|
||||
int line = 0;
|
||||
|
||||
/* Trim whitespace */
|
||||
while((isspace(*fn) != 0) && (*fn != '\0')) fn++;
|
||||
if (*fn == '\0') break;
|
||||
next = fn;
|
||||
while((isspace(*next) == 0) && (*next != '\0')) next++;
|
||||
while((isspace(*next) != 0) && (*next != '\0')) *next++ = '\0';
|
||||
|
||||
/* Add path of the rule filename for a relative phrase filename */
|
||||
filepath = fn;
|
||||
if (apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, rule->ruleset->mp) != APR_SUCCESS) {
|
||||
/* We are not an absolute path. It could mean an error, but
|
||||
* let that pass through to the open call for a better error */
|
||||
apr_filepath_merge(&fn, rulefile_path, fn, APR_FILEPATH_TRUENAME, rule->ruleset->mp);
|
||||
}
|
||||
|
||||
/* Open file and read */
|
||||
rc = apr_file_open(&fd, fn, APR_READ | 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;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr, "Loading phrase file: \"%s\"\n", fn);
|
||||
#endif
|
||||
|
||||
/* Read one pattern per line skipping empty/commented */
|
||||
for(;;) {
|
||||
line++;
|
||||
rc = apr_file_gets(buf, HUGE_STRING_LEN, fd);
|
||||
if (rc == APR_EOF) break;
|
||||
if (rc != APR_SUCCESS) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Could read \"%s\" line %d: %s", fn, line, apr_strerror(rc, errstr, 1024));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove newline */
|
||||
ptr = buf;
|
||||
while(*ptr != '\0') ptr++;
|
||||
if ((ptr > buf) && (*(ptr - 1) == '\n')) *(ptr - 1) = '\0';
|
||||
|
||||
/* Ignore empty lines and comments */
|
||||
ptr = buf;
|
||||
while((*ptr != '\0') && apr_isspace(*ptr)) ptr++;
|
||||
if ((*ptr == '\0') || (*ptr == '#')) continue;
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr, "Adding phrase file pattern: \"%s\"\n", buf);
|
||||
#endif
|
||||
|
||||
acmp_add_pattern(p, buf, NULL, NULL, strlen(buf));
|
||||
}
|
||||
fn = next;
|
||||
}
|
||||
if (fd != NULL) apr_file_close(fd);
|
||||
acmp_prepare(p);
|
||||
rule->op_param_data = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
const char *match = NULL;
|
||||
apr_status_t rc = 0;
|
||||
|
||||
/* Nothing to read */
|
||||
if ((var->value == NULL) || (var->value_len == 0)) return 0;
|
||||
|
||||
ACMPT pt = {(ACMP *)rule->op_param_data, NULL};
|
||||
|
||||
rc = acmp_process_quick(&pt, &match, var->value, var->value_len);
|
||||
if (rc) {
|
||||
char *match_escaped = log_escape(msr->mp, match ? match : "<Unknown Match>");
|
||||
|
||||
/* This message will be logged. */
|
||||
if (strlen(match_escaped) > 252) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Matched phrase \"%.252s ...\" at %s.",
|
||||
match_escaped, var->name);
|
||||
} else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Matched phrase \"%s\" at %s.",
|
||||
match_escaped, var->name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* within */
|
||||
|
||||
static int msre_op_within_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
msc_string *str = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
const char *match = NULL;
|
||||
const char *target;
|
||||
unsigned int match_length;
|
||||
unsigned int target_length;
|
||||
unsigned int target_length = 0;
|
||||
unsigned int i, i_max;
|
||||
|
||||
str->value = (char *)rule->op_param;
|
||||
str->value_len = strlen(str->value);
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if (match == NULL) {
|
||||
if (str->value == NULL) {
|
||||
*error_msg = "Internal Error: match string is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
expand_macros(msr, str, rule, msr->mp);
|
||||
|
||||
match = (const char *)str->value;
|
||||
match_length = str->value_len;
|
||||
|
||||
/* If the given target is null we give up without a match */
|
||||
if (var->value == NULL) {
|
||||
/* No match. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
target = var->value;
|
||||
target_length = var->value_len;
|
||||
|
||||
/* These are impossible to match */
|
||||
if ((match_length == 0) || (target_length > match_length)) {
|
||||
/* No match. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* scan for first character, then compare from there until we
|
||||
* have a match or there is no room left in the target
|
||||
*/
|
||||
msr_log(msr, 9, "match[%d]='%s' target[%d]='%s'", match_length, match, target_length, target);
|
||||
i_max = match_length - target_length;
|
||||
for (i = 0; i <= i_max; i++) {
|
||||
if (match[i] == target[0]) {
|
||||
if (strncmp(target, (match + i), target_length) == 0) {
|
||||
/* match. */
|
||||
*error_msg = apr_psprintf(msr->mp, "String match %s=\"%s\" within \"%s\".",
|
||||
var->name,
|
||||
log_escape_ex(msr->mp, target, target_length),
|
||||
log_escape_ex(msr->mp, match, match_length));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No match. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* contains */
|
||||
|
||||
static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
msc_string *str = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
const char *match = NULL;
|
||||
const char *target;
|
||||
unsigned int match_length;
|
||||
unsigned int target_length = 0;
|
||||
unsigned int i, i_max;
|
||||
|
||||
str->value = (char *)rule->op_param;
|
||||
str->value_len = strlen(str->value);
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if (str->value == NULL) {
|
||||
*error_msg = "Internal Error: match string is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
expand_macros(msr, str, rule, msr->mp);
|
||||
|
||||
match = (const char *)str->value;
|
||||
match_length = str->value_len;
|
||||
|
||||
/* If the given target is null run against an empty
|
||||
* string. This is a behaviour consistent with previous
|
||||
* releases.
|
||||
@@ -211,8 +432,6 @@ static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
target_length = var->value_len;
|
||||
}
|
||||
|
||||
match_length = strlen(match);
|
||||
|
||||
/* These are impossible to match */
|
||||
if ((match_length == 0) || (match_length > target_length)) {
|
||||
/* No match. */
|
||||
@@ -294,22 +513,31 @@ static int msre_op_streq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* startsWith */
|
||||
/* beginsWith */
|
||||
|
||||
static int msre_op_startsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
const char *match = (const char *)rule->op_param;
|
||||
static int msre_op_beginsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
msc_string *str = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
const char *match = NULL;
|
||||
const char *target;
|
||||
unsigned int match_length;
|
||||
unsigned int target_length;
|
||||
|
||||
str->value = (char *)rule->op_param;
|
||||
str->value_len = strlen(str->value);
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if (match == NULL) {
|
||||
if (str->value == NULL) {
|
||||
*error_msg = "Internal Error: match string is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
expand_macros(msr, str, rule, msr->mp);
|
||||
|
||||
match = (const char *)str->value;
|
||||
match_length = str->value_len;
|
||||
|
||||
/* If the given target is null run against an empty
|
||||
* string. This is a behaviour consistent with previous
|
||||
* releases.
|
||||
@@ -322,8 +550,6 @@ static int msre_op_startsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
target_length = var->value_len;
|
||||
}
|
||||
|
||||
match_length = strlen(match);
|
||||
|
||||
/* These are impossible to match */
|
||||
if ((match_length == 0) || (match_length > target_length)) {
|
||||
/* No match. */
|
||||
@@ -345,19 +571,28 @@ static int msre_op_startsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
/* endsWith */
|
||||
|
||||
static int msre_op_endsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) {
|
||||
const char *match = (const char *)rule->op_param;
|
||||
msc_string *str = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
const char *match = NULL;
|
||||
const char *target;
|
||||
unsigned int match_length;
|
||||
unsigned int target_length;
|
||||
|
||||
str->value = (char *)rule->op_param;
|
||||
str->value_len = strlen(str->value);
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if (match == NULL) {
|
||||
if (str->value == NULL) {
|
||||
*error_msg = "Internal Error: match string is null.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
expand_macros(msr, str, rule, msr->mp);
|
||||
|
||||
match = (const char *)str->value;
|
||||
match_length = str->value_len;
|
||||
|
||||
/* If the given target is null run against an empty
|
||||
* string. This is a behaviour consistent with previous
|
||||
* releases.
|
||||
@@ -370,8 +605,6 @@ static int msre_op_endsWith_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
target_length = var->value_len;
|
||||
}
|
||||
|
||||
match_length = strlen(match);
|
||||
|
||||
/* These are impossible to match */
|
||||
if ((match_length == 0) || (match_length > target_length)) {
|
||||
/* No match. */
|
||||
@@ -1197,6 +1430,27 @@ void msre_engine_register_default_operators(msre_engine *engine) {
|
||||
msre_op_rx_execute
|
||||
);
|
||||
|
||||
/* pm */
|
||||
msre_engine_op_register(engine,
|
||||
"pm",
|
||||
msre_op_pm_param_init,
|
||||
msre_op_pm_execute
|
||||
);
|
||||
|
||||
/* pmFromFile */
|
||||
msre_engine_op_register(engine,
|
||||
"pmFromFile",
|
||||
msre_op_pmFromFile_param_init,
|
||||
msre_op_pm_execute
|
||||
);
|
||||
|
||||
/* within */
|
||||
msre_engine_op_register(engine,
|
||||
"within",
|
||||
NULL, /* ENH init function to flag var substitution */
|
||||
msre_op_within_execute
|
||||
);
|
||||
|
||||
/* contains */
|
||||
msre_engine_op_register(engine,
|
||||
"contains",
|
||||
@@ -1211,11 +1465,11 @@ void msre_engine_register_default_operators(msre_engine *engine) {
|
||||
msre_op_streq_execute
|
||||
);
|
||||
|
||||
/* startsWith */
|
||||
/* beginsWith */
|
||||
msre_engine_op_register(engine,
|
||||
"startsWith",
|
||||
"beginsWith",
|
||||
NULL, /* ENH init function to flag var substitution */
|
||||
msre_op_startsWith_execute
|
||||
msre_op_beginsWith_execute
|
||||
);
|
||||
|
||||
/* endsWith */
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re_tfns.c,v 1.3 2006/12/04 12:00:24 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2006 Thinking Stone (http://www.thinkingstone.com)
|
||||
*
|
||||
* $Id: re_variables.c,v 1.7 2007/01/23 16:08:15 ivanr Exp $
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Thinking Stone at contact@thinkingstone.com.
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "http_core.h"
|
||||
@@ -1670,14 +1668,6 @@ static int var_response_status_generate(modsec_rec *msr, msre_var *var, msre_rul
|
||||
return var_simple_generate(var, vartab, mptmp, value);
|
||||
}
|
||||
|
||||
/* RESPONSE_CONTENT_ENCODING */
|
||||
|
||||
static int var_response_content_encoding(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
return var_simple_generate(var, vartab, mptmp, msr->r->content_encoding);
|
||||
}
|
||||
|
||||
/* RESPONSE_CONTENT_TYPE */
|
||||
|
||||
static int var_response_content_type(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
@@ -2470,17 +2460,6 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
PHASE_RESPONSE_HEADERS
|
||||
);
|
||||
|
||||
/* RESPONSE_CONTENT_ENCODING */
|
||||
msre_engine_variable_register(engine,
|
||||
"RESPONSE_CONTENT_ENCODING",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_response_content_encoding,
|
||||
VAR_CACHE,
|
||||
PHASE_RESPONSE_HEADERS
|
||||
);
|
||||
|
||||
/* RESPONSE_CONTENT_TYPE */
|
||||
msre_engine_variable_register(engine,
|
||||
"RESPONSE_CONTENT_TYPE",
|
||||
|
||||
810
apache2/utf8tables.h
Normal file
810
apache2/utf8tables.h
Normal file
@@ -0,0 +1,810 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
*
|
||||
*/
|
||||
#ifndef UTF8TABLES_H_
|
||||
#define UTF8TABLES_H_
|
||||
|
||||
/**
|
||||
* This include file is used by acmp.c only, it's not included anywhere else
|
||||
*/
|
||||
|
||||
typedef long acmp_utf8_char_t;
|
||||
|
||||
static const char utf8_seq_lengths[256] = {
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,
|
||||
4,4,4,4,4,4,4,4, 5,5,5,5,6,6,6,6,
|
||||
};
|
||||
|
||||
static const acmp_utf8_char_t utf8_offsets[6] = {
|
||||
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL
|
||||
};
|
||||
|
||||
/**
|
||||
* How many element pairs are there in utf8_lcase_map
|
||||
*/
|
||||
#define UTF8_LCASEMAP_LEN 759
|
||||
|
||||
/**
|
||||
* Table mapping is from PHP's mbstring extension, maps uppercase
|
||||
*/
|
||||
static const acmp_utf8_char_t utf8_lcase_map[UTF8_LCASEMAP_LEN * 2] = {
|
||||
0x00000061, 0x00000041,
|
||||
0x00000062, 0x00000042,
|
||||
0x00000063, 0x00000043,
|
||||
0x00000064, 0x00000044,
|
||||
0x00000065, 0x00000045,
|
||||
0x00000066, 0x00000046,
|
||||
0x00000067, 0x00000047,
|
||||
0x00000068, 0x00000048,
|
||||
0x00000069, 0x00000049,
|
||||
0x0000006a, 0x0000004a,
|
||||
0x0000006b, 0x0000004b,
|
||||
0x0000006c, 0x0000004c,
|
||||
0x0000006d, 0x0000004d,
|
||||
0x0000006e, 0x0000004e,
|
||||
0x0000006f, 0x0000004f,
|
||||
0x00000070, 0x00000050,
|
||||
0x00000071, 0x00000051,
|
||||
0x00000072, 0x00000052,
|
||||
0x00000073, 0x00000053,
|
||||
0x00000074, 0x00000054,
|
||||
0x00000075, 0x00000055,
|
||||
0x00000076, 0x00000056,
|
||||
0x00000077, 0x00000057,
|
||||
0x00000078, 0x00000058,
|
||||
0x00000079, 0x00000059,
|
||||
0x0000007a, 0x0000005a,
|
||||
0x000000b5, 0x0000039c,
|
||||
0x000000e0, 0x000000c0,
|
||||
0x000000e1, 0x000000c1,
|
||||
0x000000e2, 0x000000c2,
|
||||
0x000000e3, 0x000000c3,
|
||||
0x000000e4, 0x000000c4,
|
||||
0x000000e5, 0x000000c5,
|
||||
0x000000e6, 0x000000c6,
|
||||
0x000000e7, 0x000000c7,
|
||||
0x000000e8, 0x000000c8,
|
||||
0x000000e9, 0x000000c9,
|
||||
0x000000ea, 0x000000ca,
|
||||
0x000000eb, 0x000000cb,
|
||||
0x000000ec, 0x000000cc,
|
||||
0x000000ed, 0x000000cd,
|
||||
0x000000ee, 0x000000ce,
|
||||
0x000000ef, 0x000000cf,
|
||||
0x000000f0, 0x000000d0,
|
||||
0x000000f1, 0x000000d1,
|
||||
0x000000f2, 0x000000d2,
|
||||
0x000000f3, 0x000000d3,
|
||||
0x000000f4, 0x000000d4,
|
||||
0x000000f5, 0x000000d5,
|
||||
0x000000f6, 0x000000d6,
|
||||
0x000000f8, 0x000000d8,
|
||||
0x000000f9, 0x000000d9,
|
||||
0x000000fa, 0x000000da,
|
||||
0x000000fb, 0x000000db,
|
||||
0x000000fc, 0x000000dc,
|
||||
0x000000fd, 0x000000dd,
|
||||
0x000000fe, 0x000000de,
|
||||
0x000000ff, 0x00000178,
|
||||
0x00000101, 0x00000100,
|
||||
0x00000103, 0x00000102,
|
||||
0x00000105, 0x00000104,
|
||||
0x00000107, 0x00000106,
|
||||
0x00000109, 0x00000108,
|
||||
0x0000010b, 0x0000010a,
|
||||
0x0000010d, 0x0000010c,
|
||||
0x0000010f, 0x0000010e,
|
||||
0x00000111, 0x00000110,
|
||||
0x00000113, 0x00000112,
|
||||
0x00000115, 0x00000114,
|
||||
0x00000117, 0x00000116,
|
||||
0x00000119, 0x00000118,
|
||||
0x0000011b, 0x0000011a,
|
||||
0x0000011d, 0x0000011c,
|
||||
0x0000011f, 0x0000011e,
|
||||
0x00000121, 0x00000120,
|
||||
0x00000123, 0x00000122,
|
||||
0x00000125, 0x00000124,
|
||||
0x00000127, 0x00000126,
|
||||
0x00000129, 0x00000128,
|
||||
0x0000012b, 0x0000012a,
|
||||
0x0000012d, 0x0000012c,
|
||||
0x0000012f, 0x0000012e,
|
||||
0x00000131, 0x00000049,
|
||||
0x00000133, 0x00000132,
|
||||
0x00000135, 0x00000134,
|
||||
0x00000137, 0x00000136,
|
||||
0x0000013a, 0x00000139,
|
||||
0x0000013c, 0x0000013b,
|
||||
0x0000013e, 0x0000013d,
|
||||
0x00000140, 0x0000013f,
|
||||
0x00000142, 0x00000141,
|
||||
0x00000144, 0x00000143,
|
||||
0x00000146, 0x00000145,
|
||||
0x00000148, 0x00000147,
|
||||
0x0000014b, 0x0000014a,
|
||||
0x0000014d, 0x0000014c,
|
||||
0x0000014f, 0x0000014e,
|
||||
0x00000151, 0x00000150,
|
||||
0x00000153, 0x00000152,
|
||||
0x00000155, 0x00000154,
|
||||
0x00000157, 0x00000156,
|
||||
0x00000159, 0x00000158,
|
||||
0x0000015b, 0x0000015a,
|
||||
0x0000015d, 0x0000015c,
|
||||
0x0000015f, 0x0000015e,
|
||||
0x00000161, 0x00000160,
|
||||
0x00000163, 0x00000162,
|
||||
0x00000165, 0x00000164,
|
||||
0x00000167, 0x00000166,
|
||||
0x00000169, 0x00000168,
|
||||
0x0000016b, 0x0000016a,
|
||||
0x0000016d, 0x0000016c,
|
||||
0x0000016f, 0x0000016e,
|
||||
0x00000171, 0x00000170,
|
||||
0x00000173, 0x00000172,
|
||||
0x00000175, 0x00000174,
|
||||
0x00000177, 0x00000176,
|
||||
0x0000017a, 0x00000179,
|
||||
0x0000017c, 0x0000017b,
|
||||
0x0000017e, 0x0000017d,
|
||||
0x0000017f, 0x00000053,
|
||||
0x00000183, 0x00000182,
|
||||
0x00000185, 0x00000184,
|
||||
0x00000188, 0x00000187,
|
||||
0x0000018c, 0x0000018b,
|
||||
0x00000192, 0x00000191,
|
||||
0x00000195, 0x000001f6,
|
||||
0x00000199, 0x00000198,
|
||||
0x0000019e, 0x00000220,
|
||||
0x000001a1, 0x000001a0,
|
||||
0x000001a3, 0x000001a2,
|
||||
0x000001a5, 0x000001a4,
|
||||
0x000001a8, 0x000001a7,
|
||||
0x000001ad, 0x000001ac,
|
||||
0x000001b0, 0x000001af,
|
||||
0x000001b4, 0x000001b3,
|
||||
0x000001b6, 0x000001b5,
|
||||
0x000001b9, 0x000001b8,
|
||||
0x000001bd, 0x000001bc,
|
||||
0x000001bf, 0x000001f7,
|
||||
0x000001c6, 0x000001c4,
|
||||
0x000001c9, 0x000001c7,
|
||||
0x000001cc, 0x000001ca,
|
||||
0x000001ce, 0x000001cd,
|
||||
0x000001d0, 0x000001cf,
|
||||
0x000001d2, 0x000001d1,
|
||||
0x000001d4, 0x000001d3,
|
||||
0x000001d6, 0x000001d5,
|
||||
0x000001d8, 0x000001d7,
|
||||
0x000001da, 0x000001d9,
|
||||
0x000001dc, 0x000001db,
|
||||
0x000001dd, 0x0000018e,
|
||||
0x000001df, 0x000001de,
|
||||
0x000001e1, 0x000001e0,
|
||||
0x000001e3, 0x000001e2,
|
||||
0x000001e5, 0x000001e4,
|
||||
0x000001e7, 0x000001e6,
|
||||
0x000001e9, 0x000001e8,
|
||||
0x000001eb, 0x000001ea,
|
||||
0x000001ed, 0x000001ec,
|
||||
0x000001ef, 0x000001ee,
|
||||
0x000001f3, 0x000001f1,
|
||||
0x000001f5, 0x000001f4,
|
||||
0x000001f9, 0x000001f8,
|
||||
0x000001fb, 0x000001fa,
|
||||
0x000001fd, 0x000001fc,
|
||||
0x000001ff, 0x000001fe,
|
||||
0x00000201, 0x00000200,
|
||||
0x00000203, 0x00000202,
|
||||
0x00000205, 0x00000204,
|
||||
0x00000207, 0x00000206,
|
||||
0x00000209, 0x00000208,
|
||||
0x0000020b, 0x0000020a,
|
||||
0x0000020d, 0x0000020c,
|
||||
0x0000020f, 0x0000020e,
|
||||
0x00000211, 0x00000210,
|
||||
0x00000213, 0x00000212,
|
||||
0x00000215, 0x00000214,
|
||||
0x00000217, 0x00000216,
|
||||
0x00000219, 0x00000218,
|
||||
0x0000021b, 0x0000021a,
|
||||
0x0000021d, 0x0000021c,
|
||||
0x0000021f, 0x0000021e,
|
||||
0x00000223, 0x00000222,
|
||||
0x00000225, 0x00000224,
|
||||
0x00000227, 0x00000226,
|
||||
0x00000229, 0x00000228,
|
||||
0x0000022b, 0x0000022a,
|
||||
0x0000022d, 0x0000022c,
|
||||
0x0000022f, 0x0000022e,
|
||||
0x00000231, 0x00000230,
|
||||
0x00000233, 0x00000232,
|
||||
0x00000253, 0x00000181,
|
||||
0x00000254, 0x00000186,
|
||||
0x00000256, 0x00000189,
|
||||
0x00000257, 0x0000018a,
|
||||
0x00000259, 0x0000018f,
|
||||
0x0000025b, 0x00000190,
|
||||
0x00000260, 0x00000193,
|
||||
0x00000263, 0x00000194,
|
||||
0x00000268, 0x00000197,
|
||||
0x00000269, 0x00000196,
|
||||
0x0000026f, 0x0000019c,
|
||||
0x00000272, 0x0000019d,
|
||||
0x00000275, 0x0000019f,
|
||||
0x00000280, 0x000001a6,
|
||||
0x00000283, 0x000001a9,
|
||||
0x00000288, 0x000001ae,
|
||||
0x0000028a, 0x000001b1,
|
||||
0x0000028b, 0x000001b2,
|
||||
0x00000292, 0x000001b7,
|
||||
0x00000345, 0x00000399,
|
||||
0x000003ac, 0x00000386,
|
||||
0x000003ad, 0x00000388,
|
||||
0x000003ae, 0x00000389,
|
||||
0x000003af, 0x0000038a,
|
||||
0x000003b1, 0x00000391,
|
||||
0x000003b2, 0x00000392,
|
||||
0x000003b3, 0x00000393,
|
||||
0x000003b4, 0x00000394,
|
||||
0x000003b5, 0x00000395,
|
||||
0x000003b6, 0x00000396,
|
||||
0x000003b7, 0x00000397,
|
||||
0x000003b8, 0x00000398,
|
||||
0x000003b9, 0x00000399,
|
||||
0x000003ba, 0x0000039a,
|
||||
0x000003bb, 0x0000039b,
|
||||
0x000003bc, 0x0000039c,
|
||||
0x000003bd, 0x0000039d,
|
||||
0x000003be, 0x0000039e,
|
||||
0x000003bf, 0x0000039f,
|
||||
0x000003c0, 0x000003a0,
|
||||
0x000003c1, 0x000003a1,
|
||||
0x000003c2, 0x000003a3,
|
||||
0x000003c3, 0x000003a3,
|
||||
0x000003c4, 0x000003a4,
|
||||
0x000003c5, 0x000003a5,
|
||||
0x000003c6, 0x000003a6,
|
||||
0x000003c7, 0x000003a7,
|
||||
0x000003c8, 0x000003a8,
|
||||
0x000003c9, 0x000003a9,
|
||||
0x000003ca, 0x000003aa,
|
||||
0x000003cb, 0x000003ab,
|
||||
0x000003cc, 0x0000038c,
|
||||
0x000003cd, 0x0000038e,
|
||||
0x000003ce, 0x0000038f,
|
||||
0x000003d0, 0x00000392,
|
||||
0x000003d1, 0x00000398,
|
||||
0x000003d5, 0x000003a6,
|
||||
0x000003d6, 0x000003a0,
|
||||
0x000003d9, 0x000003d8,
|
||||
0x000003db, 0x000003da,
|
||||
0x000003dd, 0x000003dc,
|
||||
0x000003df, 0x000003de,
|
||||
0x000003e1, 0x000003e0,
|
||||
0x000003e3, 0x000003e2,
|
||||
0x000003e5, 0x000003e4,
|
||||
0x000003e7, 0x000003e6,
|
||||
0x000003e9, 0x000003e8,
|
||||
0x000003eb, 0x000003ea,
|
||||
0x000003ed, 0x000003ec,
|
||||
0x000003ef, 0x000003ee,
|
||||
0x000003f0, 0x0000039a,
|
||||
0x000003f1, 0x000003a1,
|
||||
0x000003f2, 0x000003a3,
|
||||
0x000003f5, 0x00000395,
|
||||
0x00000430, 0x00000410,
|
||||
0x00000431, 0x00000411,
|
||||
0x00000432, 0x00000412,
|
||||
0x00000433, 0x00000413,
|
||||
0x00000434, 0x00000414,
|
||||
0x00000435, 0x00000415,
|
||||
0x00000436, 0x00000416,
|
||||
0x00000437, 0x00000417,
|
||||
0x00000438, 0x00000418,
|
||||
0x00000439, 0x00000419,
|
||||
0x0000043a, 0x0000041a,
|
||||
0x0000043b, 0x0000041b,
|
||||
0x0000043c, 0x0000041c,
|
||||
0x0000043d, 0x0000041d,
|
||||
0x0000043e, 0x0000041e,
|
||||
0x0000043f, 0x0000041f,
|
||||
0x00000440, 0x00000420,
|
||||
0x00000441, 0x00000421,
|
||||
0x00000442, 0x00000422,
|
||||
0x00000443, 0x00000423,
|
||||
0x00000444, 0x00000424,
|
||||
0x00000445, 0x00000425,
|
||||
0x00000446, 0x00000426,
|
||||
0x00000447, 0x00000427,
|
||||
0x00000448, 0x00000428,
|
||||
0x00000449, 0x00000429,
|
||||
0x0000044a, 0x0000042a,
|
||||
0x0000044b, 0x0000042b,
|
||||
0x0000044c, 0x0000042c,
|
||||
0x0000044d, 0x0000042d,
|
||||
0x0000044e, 0x0000042e,
|
||||
0x0000044f, 0x0000042f,
|
||||
0x00000450, 0x00000400,
|
||||
0x00000451, 0x00000401,
|
||||
0x00000452, 0x00000402,
|
||||
0x00000453, 0x00000403,
|
||||
0x00000454, 0x00000404,
|
||||
0x00000455, 0x00000405,
|
||||
0x00000456, 0x00000406,
|
||||
0x00000457, 0x00000407,
|
||||
0x00000458, 0x00000408,
|
||||
0x00000459, 0x00000409,
|
||||
0x0000045a, 0x0000040a,
|
||||
0x0000045b, 0x0000040b,
|
||||
0x0000045c, 0x0000040c,
|
||||
0x0000045d, 0x0000040d,
|
||||
0x0000045e, 0x0000040e,
|
||||
0x0000045f, 0x0000040f,
|
||||
0x00000461, 0x00000460,
|
||||
0x00000463, 0x00000462,
|
||||
0x00000465, 0x00000464,
|
||||
0x00000467, 0x00000466,
|
||||
0x00000469, 0x00000468,
|
||||
0x0000046b, 0x0000046a,
|
||||
0x0000046d, 0x0000046c,
|
||||
0x0000046f, 0x0000046e,
|
||||
0x00000471, 0x00000470,
|
||||
0x00000473, 0x00000472,
|
||||
0x00000475, 0x00000474,
|
||||
0x00000477, 0x00000476,
|
||||
0x00000479, 0x00000478,
|
||||
0x0000047b, 0x0000047a,
|
||||
0x0000047d, 0x0000047c,
|
||||
0x0000047f, 0x0000047e,
|
||||
0x00000481, 0x00000480,
|
||||
0x0000048b, 0x0000048a,
|
||||
0x0000048d, 0x0000048c,
|
||||
0x0000048f, 0x0000048e,
|
||||
0x00000491, 0x00000490,
|
||||
0x00000493, 0x00000492,
|
||||
0x00000495, 0x00000494,
|
||||
0x00000497, 0x00000496,
|
||||
0x00000499, 0x00000498,
|
||||
0x0000049b, 0x0000049a,
|
||||
0x0000049d, 0x0000049c,
|
||||
0x0000049f, 0x0000049e,
|
||||
0x000004a1, 0x000004a0,
|
||||
0x000004a3, 0x000004a2,
|
||||
0x000004a5, 0x000004a4,
|
||||
0x000004a7, 0x000004a6,
|
||||
0x000004a9, 0x000004a8,
|
||||
0x000004ab, 0x000004aa,
|
||||
0x000004ad, 0x000004ac,
|
||||
0x000004af, 0x000004ae,
|
||||
0x000004b1, 0x000004b0,
|
||||
0x000004b3, 0x000004b2,
|
||||
0x000004b5, 0x000004b4,
|
||||
0x000004b7, 0x000004b6,
|
||||
0x000004b9, 0x000004b8,
|
||||
0x000004bb, 0x000004ba,
|
||||
0x000004bd, 0x000004bc,
|
||||
0x000004bf, 0x000004be,
|
||||
0x000004c2, 0x000004c1,
|
||||
0x000004c4, 0x000004c3,
|
||||
0x000004c6, 0x000004c5,
|
||||
0x000004c8, 0x000004c7,
|
||||
0x000004ca, 0x000004c9,
|
||||
0x000004cc, 0x000004cb,
|
||||
0x000004ce, 0x000004cd,
|
||||
0x000004d1, 0x000004d0,
|
||||
0x000004d3, 0x000004d2,
|
||||
0x000004d5, 0x000004d4,
|
||||
0x000004d7, 0x000004d6,
|
||||
0x000004d9, 0x000004d8,
|
||||
0x000004db, 0x000004da,
|
||||
0x000004dd, 0x000004dc,
|
||||
0x000004df, 0x000004de,
|
||||
0x000004e1, 0x000004e0,
|
||||
0x000004e3, 0x000004e2,
|
||||
0x000004e5, 0x000004e4,
|
||||
0x000004e7, 0x000004e6,
|
||||
0x000004e9, 0x000004e8,
|
||||
0x000004eb, 0x000004ea,
|
||||
0x000004ed, 0x000004ec,
|
||||
0x000004ef, 0x000004ee,
|
||||
0x000004f1, 0x000004f0,
|
||||
0x000004f3, 0x000004f2,
|
||||
0x000004f5, 0x000004f4,
|
||||
0x000004f9, 0x000004f8,
|
||||
0x00000501, 0x00000500,
|
||||
0x00000503, 0x00000502,
|
||||
0x00000505, 0x00000504,
|
||||
0x00000507, 0x00000506,
|
||||
0x00000509, 0x00000508,
|
||||
0x0000050b, 0x0000050a,
|
||||
0x0000050d, 0x0000050c,
|
||||
0x0000050f, 0x0000050e,
|
||||
0x00000561, 0x00000531,
|
||||
0x00000562, 0x00000532,
|
||||
0x00000563, 0x00000533,
|
||||
0x00000564, 0x00000534,
|
||||
0x00000565, 0x00000535,
|
||||
0x00000566, 0x00000536,
|
||||
0x00000567, 0x00000537,
|
||||
0x00000568, 0x00000538,
|
||||
0x00000569, 0x00000539,
|
||||
0x0000056a, 0x0000053a,
|
||||
0x0000056b, 0x0000053b,
|
||||
0x0000056c, 0x0000053c,
|
||||
0x0000056d, 0x0000053d,
|
||||
0x0000056e, 0x0000053e,
|
||||
0x0000056f, 0x0000053f,
|
||||
0x00000570, 0x00000540,
|
||||
0x00000571, 0x00000541,
|
||||
0x00000572, 0x00000542,
|
||||
0x00000573, 0x00000543,
|
||||
0x00000574, 0x00000544,
|
||||
0x00000575, 0x00000545,
|
||||
0x00000576, 0x00000546,
|
||||
0x00000577, 0x00000547,
|
||||
0x00000578, 0x00000548,
|
||||
0x00000579, 0x00000549,
|
||||
0x0000057a, 0x0000054a,
|
||||
0x0000057b, 0x0000054b,
|
||||
0x0000057c, 0x0000054c,
|
||||
0x0000057d, 0x0000054d,
|
||||
0x0000057e, 0x0000054e,
|
||||
0x0000057f, 0x0000054f,
|
||||
0x00000580, 0x00000550,
|
||||
0x00000581, 0x00000551,
|
||||
0x00000582, 0x00000552,
|
||||
0x00000583, 0x00000553,
|
||||
0x00000584, 0x00000554,
|
||||
0x00000585, 0x00000555,
|
||||
0x00000586, 0x00000556,
|
||||
0x00001e01, 0x00001e00,
|
||||
0x00001e03, 0x00001e02,
|
||||
0x00001e05, 0x00001e04,
|
||||
0x00001e07, 0x00001e06,
|
||||
0x00001e09, 0x00001e08,
|
||||
0x00001e0b, 0x00001e0a,
|
||||
0x00001e0d, 0x00001e0c,
|
||||
0x00001e0f, 0x00001e0e,
|
||||
0x00001e11, 0x00001e10,
|
||||
0x00001e13, 0x00001e12,
|
||||
0x00001e15, 0x00001e14,
|
||||
0x00001e17, 0x00001e16,
|
||||
0x00001e19, 0x00001e18,
|
||||
0x00001e1b, 0x00001e1a,
|
||||
0x00001e1d, 0x00001e1c,
|
||||
0x00001e1f, 0x00001e1e,
|
||||
0x00001e21, 0x00001e20,
|
||||
0x00001e23, 0x00001e22,
|
||||
0x00001e25, 0x00001e24,
|
||||
0x00001e27, 0x00001e26,
|
||||
0x00001e29, 0x00001e28,
|
||||
0x00001e2b, 0x00001e2a,
|
||||
0x00001e2d, 0x00001e2c,
|
||||
0x00001e2f, 0x00001e2e,
|
||||
0x00001e31, 0x00001e30,
|
||||
0x00001e33, 0x00001e32,
|
||||
0x00001e35, 0x00001e34,
|
||||
0x00001e37, 0x00001e36,
|
||||
0x00001e39, 0x00001e38,
|
||||
0x00001e3b, 0x00001e3a,
|
||||
0x00001e3d, 0x00001e3c,
|
||||
0x00001e3f, 0x00001e3e,
|
||||
0x00001e41, 0x00001e40,
|
||||
0x00001e43, 0x00001e42,
|
||||
0x00001e45, 0x00001e44,
|
||||
0x00001e47, 0x00001e46,
|
||||
0x00001e49, 0x00001e48,
|
||||
0x00001e4b, 0x00001e4a,
|
||||
0x00001e4d, 0x00001e4c,
|
||||
0x00001e4f, 0x00001e4e,
|
||||
0x00001e51, 0x00001e50,
|
||||
0x00001e53, 0x00001e52,
|
||||
0x00001e55, 0x00001e54,
|
||||
0x00001e57, 0x00001e56,
|
||||
0x00001e59, 0x00001e58,
|
||||
0x00001e5b, 0x00001e5a,
|
||||
0x00001e5d, 0x00001e5c,
|
||||
0x00001e5f, 0x00001e5e,
|
||||
0x00001e61, 0x00001e60,
|
||||
0x00001e63, 0x00001e62,
|
||||
0x00001e65, 0x00001e64,
|
||||
0x00001e67, 0x00001e66,
|
||||
0x00001e69, 0x00001e68,
|
||||
0x00001e6b, 0x00001e6a,
|
||||
0x00001e6d, 0x00001e6c,
|
||||
0x00001e6f, 0x00001e6e,
|
||||
0x00001e71, 0x00001e70,
|
||||
0x00001e73, 0x00001e72,
|
||||
0x00001e75, 0x00001e74,
|
||||
0x00001e77, 0x00001e76,
|
||||
0x00001e79, 0x00001e78,
|
||||
0x00001e7b, 0x00001e7a,
|
||||
0x00001e7d, 0x00001e7c,
|
||||
0x00001e7f, 0x00001e7e,
|
||||
0x00001e81, 0x00001e80,
|
||||
0x00001e83, 0x00001e82,
|
||||
0x00001e85, 0x00001e84,
|
||||
0x00001e87, 0x00001e86,
|
||||
0x00001e89, 0x00001e88,
|
||||
0x00001e8b, 0x00001e8a,
|
||||
0x00001e8d, 0x00001e8c,
|
||||
0x00001e8f, 0x00001e8e,
|
||||
0x00001e91, 0x00001e90,
|
||||
0x00001e93, 0x00001e92,
|
||||
0x00001e95, 0x00001e94,
|
||||
0x00001e9b, 0x00001e60,
|
||||
0x00001ea1, 0x00001ea0,
|
||||
0x00001ea3, 0x00001ea2,
|
||||
0x00001ea5, 0x00001ea4,
|
||||
0x00001ea7, 0x00001ea6,
|
||||
0x00001ea9, 0x00001ea8,
|
||||
0x00001eab, 0x00001eaa,
|
||||
0x00001ead, 0x00001eac,
|
||||
0x00001eaf, 0x00001eae,
|
||||
0x00001eb1, 0x00001eb0,
|
||||
0x00001eb3, 0x00001eb2,
|
||||
0x00001eb5, 0x00001eb4,
|
||||
0x00001eb7, 0x00001eb6,
|
||||
0x00001eb9, 0x00001eb8,
|
||||
0x00001ebb, 0x00001eba,
|
||||
0x00001ebd, 0x00001ebc,
|
||||
0x00001ebf, 0x00001ebe,
|
||||
0x00001ec1, 0x00001ec0,
|
||||
0x00001ec3, 0x00001ec2,
|
||||
0x00001ec5, 0x00001ec4,
|
||||
0x00001ec7, 0x00001ec6,
|
||||
0x00001ec9, 0x00001ec8,
|
||||
0x00001ecb, 0x00001eca,
|
||||
0x00001ecd, 0x00001ecc,
|
||||
0x00001ecf, 0x00001ece,
|
||||
0x00001ed1, 0x00001ed0,
|
||||
0x00001ed3, 0x00001ed2,
|
||||
0x00001ed5, 0x00001ed4,
|
||||
0x00001ed7, 0x00001ed6,
|
||||
0x00001ed9, 0x00001ed8,
|
||||
0x00001edb, 0x00001eda,
|
||||
0x00001edd, 0x00001edc,
|
||||
0x00001edf, 0x00001ede,
|
||||
0x00001ee1, 0x00001ee0,
|
||||
0x00001ee3, 0x00001ee2,
|
||||
0x00001ee5, 0x00001ee4,
|
||||
0x00001ee7, 0x00001ee6,
|
||||
0x00001ee9, 0x00001ee8,
|
||||
0x00001eeb, 0x00001eea,
|
||||
0x00001eed, 0x00001eec,
|
||||
0x00001eef, 0x00001eee,
|
||||
0x00001ef1, 0x00001ef0,
|
||||
0x00001ef3, 0x00001ef2,
|
||||
0x00001ef5, 0x00001ef4,
|
||||
0x00001ef7, 0x00001ef6,
|
||||
0x00001ef9, 0x00001ef8,
|
||||
0x00001f00, 0x00001f08,
|
||||
0x00001f01, 0x00001f09,
|
||||
0x00001f02, 0x00001f0a,
|
||||
0x00001f03, 0x00001f0b,
|
||||
0x00001f04, 0x00001f0c,
|
||||
0x00001f05, 0x00001f0d,
|
||||
0x00001f06, 0x00001f0e,
|
||||
0x00001f07, 0x00001f0f,
|
||||
0x00001f10, 0x00001f18,
|
||||
0x00001f11, 0x00001f19,
|
||||
0x00001f12, 0x00001f1a,
|
||||
0x00001f13, 0x00001f1b,
|
||||
0x00001f14, 0x00001f1c,
|
||||
0x00001f15, 0x00001f1d,
|
||||
0x00001f20, 0x00001f28,
|
||||
0x00001f21, 0x00001f29,
|
||||
0x00001f22, 0x00001f2a,
|
||||
0x00001f23, 0x00001f2b,
|
||||
0x00001f24, 0x00001f2c,
|
||||
0x00001f25, 0x00001f2d,
|
||||
0x00001f26, 0x00001f2e,
|
||||
0x00001f27, 0x00001f2f,
|
||||
0x00001f30, 0x00001f38,
|
||||
0x00001f31, 0x00001f39,
|
||||
0x00001f32, 0x00001f3a,
|
||||
0x00001f33, 0x00001f3b,
|
||||
0x00001f34, 0x00001f3c,
|
||||
0x00001f35, 0x00001f3d,
|
||||
0x00001f36, 0x00001f3e,
|
||||
0x00001f37, 0x00001f3f,
|
||||
0x00001f40, 0x00001f48,
|
||||
0x00001f41, 0x00001f49,
|
||||
0x00001f42, 0x00001f4a,
|
||||
0x00001f43, 0x00001f4b,
|
||||
0x00001f44, 0x00001f4c,
|
||||
0x00001f45, 0x00001f4d,
|
||||
0x00001f51, 0x00001f59,
|
||||
0x00001f53, 0x00001f5b,
|
||||
0x00001f55, 0x00001f5d,
|
||||
0x00001f57, 0x00001f5f,
|
||||
0x00001f60, 0x00001f68,
|
||||
0x00001f61, 0x00001f69,
|
||||
0x00001f62, 0x00001f6a,
|
||||
0x00001f63, 0x00001f6b,
|
||||
0x00001f64, 0x00001f6c,
|
||||
0x00001f65, 0x00001f6d,
|
||||
0x00001f66, 0x00001f6e,
|
||||
0x00001f67, 0x00001f6f,
|
||||
0x00001f70, 0x00001fba,
|
||||
0x00001f71, 0x00001fbb,
|
||||
0x00001f72, 0x00001fc8,
|
||||
0x00001f73, 0x00001fc9,
|
||||
0x00001f74, 0x00001fca,
|
||||
0x00001f75, 0x00001fcb,
|
||||
0x00001f76, 0x00001fda,
|
||||
0x00001f77, 0x00001fdb,
|
||||
0x00001f78, 0x00001ff8,
|
||||
0x00001f79, 0x00001ff9,
|
||||
0x00001f7a, 0x00001fea,
|
||||
0x00001f7b, 0x00001feb,
|
||||
0x00001f7c, 0x00001ffa,
|
||||
0x00001f7d, 0x00001ffb,
|
||||
0x00001f80, 0x00001f88,
|
||||
0x00001f81, 0x00001f89,
|
||||
0x00001f82, 0x00001f8a,
|
||||
0x00001f83, 0x00001f8b,
|
||||
0x00001f84, 0x00001f8c,
|
||||
0x00001f85, 0x00001f8d,
|
||||
0x00001f86, 0x00001f8e,
|
||||
0x00001f87, 0x00001f8f,
|
||||
0x00001f90, 0x00001f98,
|
||||
0x00001f91, 0x00001f99,
|
||||
0x00001f92, 0x00001f9a,
|
||||
0x00001f93, 0x00001f9b,
|
||||
0x00001f94, 0x00001f9c,
|
||||
0x00001f95, 0x00001f9d,
|
||||
0x00001f96, 0x00001f9e,
|
||||
0x00001f97, 0x00001f9f,
|
||||
0x00001fa0, 0x00001fa8,
|
||||
0x00001fa1, 0x00001fa9,
|
||||
0x00001fa2, 0x00001faa,
|
||||
0x00001fa3, 0x00001fab,
|
||||
0x00001fa4, 0x00001fac,
|
||||
0x00001fa5, 0x00001fad,
|
||||
0x00001fa6, 0x00001fae,
|
||||
0x00001fa7, 0x00001faf,
|
||||
0x00001fb0, 0x00001fb8,
|
||||
0x00001fb1, 0x00001fb9,
|
||||
0x00001fb3, 0x00001fbc,
|
||||
0x00001fbe, 0x00000399,
|
||||
0x00001fc3, 0x00001fcc,
|
||||
0x00001fd0, 0x00001fd8,
|
||||
0x00001fd1, 0x00001fd9,
|
||||
0x00001fe0, 0x00001fe8,
|
||||
0x00001fe1, 0x00001fe9,
|
||||
0x00001fe5, 0x00001fec,
|
||||
0x00001ff3, 0x00001ffc,
|
||||
0x00002170, 0x00002160,
|
||||
0x00002171, 0x00002161,
|
||||
0x00002172, 0x00002162,
|
||||
0x00002173, 0x00002163,
|
||||
0x00002174, 0x00002164,
|
||||
0x00002175, 0x00002165,
|
||||
0x00002176, 0x00002166,
|
||||
0x00002177, 0x00002167,
|
||||
0x00002178, 0x00002168,
|
||||
0x00002179, 0x00002169,
|
||||
0x0000217a, 0x0000216a,
|
||||
0x0000217b, 0x0000216b,
|
||||
0x0000217c, 0x0000216c,
|
||||
0x0000217d, 0x0000216d,
|
||||
0x0000217e, 0x0000216e,
|
||||
0x0000217f, 0x0000216f,
|
||||
0x000024d0, 0x000024b6,
|
||||
0x000024d1, 0x000024b7,
|
||||
0x000024d2, 0x000024b8,
|
||||
0x000024d3, 0x000024b9,
|
||||
0x000024d4, 0x000024ba,
|
||||
0x000024d5, 0x000024bb,
|
||||
0x000024d6, 0x000024bc,
|
||||
0x000024d7, 0x000024bd,
|
||||
0x000024d8, 0x000024be,
|
||||
0x000024d9, 0x000024bf,
|
||||
0x000024da, 0x000024c0,
|
||||
0x000024db, 0x000024c1,
|
||||
0x000024dc, 0x000024c2,
|
||||
0x000024dd, 0x000024c3,
|
||||
0x000024de, 0x000024c4,
|
||||
0x000024df, 0x000024c5,
|
||||
0x000024e0, 0x000024c6,
|
||||
0x000024e1, 0x000024c7,
|
||||
0x000024e2, 0x000024c8,
|
||||
0x000024e3, 0x000024c9,
|
||||
0x000024e4, 0x000024ca,
|
||||
0x000024e5, 0x000024cb,
|
||||
0x000024e6, 0x000024cc,
|
||||
0x000024e7, 0x000024cd,
|
||||
0x000024e8, 0x000024ce,
|
||||
0x000024e9, 0x000024cf,
|
||||
0x0000ff41, 0x0000ff21,
|
||||
0x0000ff42, 0x0000ff22,
|
||||
0x0000ff43, 0x0000ff23,
|
||||
0x0000ff44, 0x0000ff24,
|
||||
0x0000ff45, 0x0000ff25,
|
||||
0x0000ff46, 0x0000ff26,
|
||||
0x0000ff47, 0x0000ff27,
|
||||
0x0000ff48, 0x0000ff28,
|
||||
0x0000ff49, 0x0000ff29,
|
||||
0x0000ff4a, 0x0000ff2a,
|
||||
0x0000ff4b, 0x0000ff2b,
|
||||
0x0000ff4c, 0x0000ff2c,
|
||||
0x0000ff4d, 0x0000ff2d,
|
||||
0x0000ff4e, 0x0000ff2e,
|
||||
0x0000ff4f, 0x0000ff2f,
|
||||
0x0000ff50, 0x0000ff30,
|
||||
0x0000ff51, 0x0000ff31,
|
||||
0x0000ff52, 0x0000ff32,
|
||||
0x0000ff53, 0x0000ff33,
|
||||
0x0000ff54, 0x0000ff34,
|
||||
0x0000ff55, 0x0000ff35,
|
||||
0x0000ff56, 0x0000ff36,
|
||||
0x0000ff57, 0x0000ff37,
|
||||
0x0000ff58, 0x0000ff38,
|
||||
0x0000ff59, 0x0000ff39,
|
||||
0x0000ff5a, 0x0000ff3a,
|
||||
0x00010428, 0x00010400,
|
||||
0x00010429, 0x00010401,
|
||||
0x0001042a, 0x00010402,
|
||||
0x0001042b, 0x00010403,
|
||||
0x0001042c, 0x00010404,
|
||||
0x0001042d, 0x00010405,
|
||||
0x0001042e, 0x00010406,
|
||||
0x0001042f, 0x00010407,
|
||||
0x00010430, 0x00010408,
|
||||
0x00010431, 0x00010409,
|
||||
0x00010432, 0x0001040a,
|
||||
0x00010433, 0x0001040b,
|
||||
0x00010434, 0x0001040c,
|
||||
0x00010435, 0x0001040d,
|
||||
0x00010436, 0x0001040e,
|
||||
0x00010437, 0x0001040f,
|
||||
0x00010438, 0x00010410,
|
||||
0x00010439, 0x00010411,
|
||||
0x0001043a, 0x00010412,
|
||||
0x0001043b, 0x00010413,
|
||||
0x0001043c, 0x00010414,
|
||||
0x0001043d, 0x00010415,
|
||||
0x0001043e, 0x00010416,
|
||||
0x0001043f, 0x00010417,
|
||||
0x00010440, 0x00010418,
|
||||
0x00010441, 0x00010419,
|
||||
0x00010442, 0x0001041a,
|
||||
0x00010443, 0x0001041b,
|
||||
0x00010444, 0x0001041c,
|
||||
0x00010445, 0x0001041d,
|
||||
0x00010446, 0x0001041e,
|
||||
0x00010447, 0x0001041f,
|
||||
0x00010448, 0x00010420,
|
||||
0x00010449, 0x00010421,
|
||||
0x0001044a, 0x00010422,
|
||||
0x0001044b, 0x00010423,
|
||||
0x0001044c, 0x00010424,
|
||||
0x0001044d, 0x00010425,
|
||||
};
|
||||
|
||||
#endif /*UTF8TABLES_H_*/
|
||||
@@ -3,7 +3,7 @@
|
||||
<title>ModSecurity Reference Manual</title>
|
||||
|
||||
<articleinfo>
|
||||
<releaseinfo>Version 2.2.0-dev1 / (May 11, 2007)</releaseinfo>
|
||||
<releaseinfo>Version 2.5.0-dev2 / (June 21, 2007)</releaseinfo>
|
||||
|
||||
<copyright>
|
||||
<year>2004-2007</year>
|
||||
@@ -1087,7 +1087,7 @@ SecAuditLogStorageDir logs/audit
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>SecPdfProtect (Experimental)</title>
|
||||
<title><literal>SecPdfProtect</literal> (Experimental)</title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Enables the PDF XSS
|
||||
protection functionality. Once enabled access to PDF files is tracked.
|
||||
@@ -1101,7 +1101,25 @@ SecAuditLogStorageDir logs/audit
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>SecPdfProtectSecret (Experimental)</title>
|
||||
<title><literal>SecPdfProtectMethod</literal> (Experimental)</title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Configure desired
|
||||
protection method to be used when requests for PDF files are detected.
|
||||
Possible values are <literal>TokenRedirection</literal> and
|
||||
<literal>ForcedDownload</literal>. The token redirection approach will
|
||||
attempt to redirect with tokens where possible. This allows PDF files to
|
||||
continue to be opened inline but only works for GET requests. Forced
|
||||
download always causes PDF files to be delivered as opaque binaries and
|
||||
attachments. The latter will always be used for non-GET requests. Forced
|
||||
download is considered to be more secure but may cause usability
|
||||
problems for users ("This PDF won't open anymore!").</para>
|
||||
|
||||
<para><emphasis role="bold">Default:</emphasis>
|
||||
<literal>TokenRedirection</literal></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>SecPdfProtectSecret</literal> (Experimental)</title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Defines the secret
|
||||
that will be used to construct one-time tokens. You should use a
|
||||
@@ -1113,7 +1131,7 @@ SecAuditLogStorageDir logs/audit
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>SecPdfProtectTimeout (Experimental)</title>
|
||||
<title><literal>SecPdfProtectTimeout</literal> (Experimental)</title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Defines the token
|
||||
timeout. After token expires it can no longer be used to allow access to
|
||||
@@ -1125,7 +1143,7 @@ SecAuditLogStorageDir logs/audit
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>SecPdfProtectTokenName (Experimental)</title>
|
||||
<title><literal>SecPdfProtectTokenName</literal> (Experimental)</title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Defines the name of
|
||||
the token. The only reason you would want to change the name of the
|
||||
@@ -2422,21 +2440,23 @@ SecRule XML "@validateDTD /opt/apache-frontend/conf/xml.dtd"</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>RESPONSE_CONTENT_LENGTH</literal> (Experimental)</title>
|
||||
<title><literal>RESPONSE_CONTENT_LENGTH</literal></title>
|
||||
|
||||
<para>Response body length in bytes. Can be available starting with
|
||||
phase 3 but it does not have to be (as the length of response body is
|
||||
not always known in advance.) Does not exist of the content length is
|
||||
not know. (We will consider making it empty if the size is not
|
||||
known.)</para>
|
||||
not always known in advance.) If the size is not known this variable
|
||||
will contain a zero. If <literal>RESPONSE_CONTENT_LENGTH</literal>
|
||||
contains a zero in phase 5 that means the actual size of the response
|
||||
body was 0.</para>
|
||||
|
||||
<para>The value of this variable can change between phases if the body
|
||||
is modified. For example, in embedded mode mod_deflate can compress the
|
||||
response body between phases 4 and 5.</para>
|
||||
is modified. For example, in embedded mode
|
||||
<literal>mod_deflate</literal> can compress the response body between
|
||||
phases 4 and 5.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>RESPONSE_CONTENT_TYPE</literal> (Experimental)</title>
|
||||
<title><literal>RESPONSE_CONTENT_TYPE</literal></title>
|
||||
|
||||
<para>Response content type. Only available starting with phase
|
||||
3.</para>
|
||||
@@ -2814,6 +2834,72 @@ SecRule REQBODY_PROCESSOR "<emphasis role="bold">!^XML$</emphasis>" skip:2
|
||||
SecRule <emphasis role="bold">XML:/employees/employee/name/text()</emphasis> Fred
|
||||
SecRule <emphasis role="bold">XML:/xq:employees/employee/name/text()</emphasis> Fred \
|
||||
xmlns:xq=http://www.example.com/employees</programlisting>
|
||||
|
||||
<para>The first XPath expression does not use namespaces. It would match
|
||||
against payload such as this one:</para>
|
||||
|
||||
<programlisting><employees>
|
||||
<employee>
|
||||
<name>Fred Jones</name>
|
||||
<address location="home">
|
||||
<street>900 Aurora Ave.</street>
|
||||
<city>Seattle</city>
|
||||
<state>WA</state>
|
||||
<zip>98115</zip>
|
||||
</address>
|
||||
<address location="work">
|
||||
<street>2011 152nd Avenue NE</street>
|
||||
<city>Redmond</city>
|
||||
<state>WA</state>
|
||||
<zip>98052</zip>
|
||||
</address>
|
||||
<phone location="work">(425)555-5665</phone>
|
||||
<phone location="home">(206)555-5555</phone>
|
||||
<phone location="mobile">(206)555-4321</phone>
|
||||
</employee>
|
||||
</employees></programlisting>
|
||||
|
||||
<para>The second XPath expression does use namespaces. It would match
|
||||
the following payload:</para>
|
||||
|
||||
<programlisting><xq:employees xmlns:xq="http://www.example.com/employees">
|
||||
<employee>
|
||||
<name>Fred Jones</name>
|
||||
<address location="home">
|
||||
<street>900 Aurora Ave.</street>
|
||||
<city>Seattle</city>
|
||||
<state>WA</state>
|
||||
<zip>98115</zip>
|
||||
</address>
|
||||
<address location="work">
|
||||
<street>2011 152nd Avenue NE</street>
|
||||
<city>Redmond</city>
|
||||
<state>WA</state>
|
||||
<zip>98052</zip>
|
||||
</address>
|
||||
<phone location="work">(425)555-5665</phone>
|
||||
<phone location="home">(206)555-5555</phone>
|
||||
<phone location="mobile">(206)555-4321</phone>
|
||||
</employee>
|
||||
</xq:employees></programlisting>
|
||||
|
||||
<para>Note the different namespace used in the second example.</para>
|
||||
|
||||
<para>To learn more about XPath we suggest the following
|
||||
resources:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para><ulink url="http://www.w3.org/TR/xpath">XPath
|
||||
Standard</ulink></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><ulink
|
||||
url="http://www.zvon.org/xxl/XPathTutorial/General/examples.html">XPath
|
||||
Tutorial</ulink></para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -3035,8 +3121,10 @@ SecRule <emphasis role="bold">XML:/xq:employees/employee/name/text()</emphasis>
|
||||
|
||||
<para>In addition to decoding %xx like <literal
|
||||
moreinfo="none">urlDecode, urlDecodeUni also </literal>decodes<literal
|
||||
moreinfo="none"> <literal>%uXXXX</literal> </literal>encoding (only the
|
||||
lower byte will be used, the higher byte will be discarded).</para>
|
||||
moreinfo="none"> <literal>%uXXXX</literal> </literal>encoding. If the
|
||||
code is in the range of FF01-FF5E (the full width ASCII codes), then the
|
||||
higher byte is used to detect and adjust the lower byte. Otherwise, only
|
||||
the lower byte will be used and the higher byte zeroed.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -3544,6 +3632,17 @@ SecRule REQUEST_URI "^/cgi-bin/script\.pl" \
|
||||
moreinfo="none"> SESSION</literal>, and <literal
|
||||
moreinfo="none">USER</literal>.</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>Please note that ModSecurity does not implement atomic updates
|
||||
of persistent variables at this time. Variables are read from storage
|
||||
whenever <literal>initcol</literal> is encountered in the rules and
|
||||
persisted at the end of request processing. On busy servers requests
|
||||
often run in parallel, leading to situations where one request
|
||||
overwrites the changes made by another request. We anticipate
|
||||
implementing atomic updates of counter values in a future
|
||||
version.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -4285,6 +4384,62 @@ SecRule ARGS:route "!<emphasis role="bold">@endsWith %{REQUEST_ADDR}</emphasis>"
|
||||
role="bold">@lt </emphasis>15"</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>pm</literal></title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Phrase Match
|
||||
operator. This operator uses a set based matching engine (Aho-Corasick)
|
||||
for faster matches of keyword lists. It will match any one of its
|
||||
arguments anywhere in the target value.</para>
|
||||
|
||||
<para>Example:</para>
|
||||
|
||||
<programlisting format="linespecific">SecRule REQUEST_HEADERS:User-Agent "<emphasis
|
||||
role="bold">@pm</emphasis> WebZIP WebCopier Webster WebStripper SiteSnagger ProWebWalker CheeseBot" "deny,status:403</programlisting>
|
||||
|
||||
<para>The above would deny access with 403 if any of the words matched
|
||||
within the User-Agent HTTP header value.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>pmFromFile</literal></title>
|
||||
|
||||
<para><emphasis role="bold">Description:</emphasis> Phrase Match
|
||||
operator. This operator uses a set based matching engine (Aho-Corasick)
|
||||
for faster matches of keyword lists. This operator is the same as
|
||||
<literal>@pm</literal> except that it takes a list of files as
|
||||
arguments. It will match any one of the phrases listed in the file(s)
|
||||
anywhere in the target value.</para>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
</orderedlist>
|
||||
|
||||
<para>Example:</para>
|
||||
|
||||
<programlisting format="linespecific">SecRule REQUEST_HEADERS:User-Agent "<emphasis
|
||||
role="bold">@pm</emphasis> /path/to/blacklist1 blacklist2" "deny,status:403</programlisting>
|
||||
|
||||
<para>The above would deny access with 403 if any of the patterns in the
|
||||
two files matched within the User-Agent HTTP header value. The
|
||||
<literal>blacklist2</literal> file would need to be placed in the same
|
||||
path as the file containing the rule.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>rbl</literal></title>
|
||||
|
||||
@@ -4494,5 +4649,24 @@ SecRule XML "<emphasis role="bold">@validateSchema /path/to/apache2/conf/xml.xsd
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>within</literal></title>
|
||||
|
||||
<para><emphasis role="bold">Description: </emphasis>This operator is a
|
||||
string comparison and returns true if the input value is found anywhere
|
||||
within the parameter value. Note that this is similar to
|
||||
<literal>@contains</literal>, except that the target and match values
|
||||
are reversed. Macro expansion is performed so you may use variable names
|
||||
such as %{TX.1}, etc.</para>
|
||||
|
||||
<para>Example:</para>
|
||||
|
||||
<programlisting format="linespecific">SecRule REQUEST_METHOD "!<emphasis
|
||||
role="bold">@within get,post,head</emphasis>" t:lowercase,deny,status:403
|
||||
|
||||
SecAction "pass,setvar:'tx.allowed_methods=get,post,head'"
|
||||
SecRule REQUEST_METHOD "!<emphasis role="bold">@within %{tx.allowed_methods}</emphasis>" t:lowercase,deny,status:403</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
188
rules/CHANGELOG
188
rules/CHANGELOG
@@ -1,66 +1,122 @@
|
||||
|
||||
|
||||
version 1.3.2 build 4 2007/01/17
|
||||
|
||||
Fixed apache 2.4 dummy requests exclusion
|
||||
Added persistent PDF UXSS detection rule
|
||||
|
||||
|
||||
Vervion 1.3.2 build 3 2007/01/10
|
||||
|
||||
Fixed regular expresion in rule 960010 (file #30) to allow mulipart-data content
|
||||
|
||||
|
||||
Version 1.3.2 - 2006/12/27
|
||||
|
||||
New events:
|
||||
- 960037 Directory is restricted by policy
|
||||
- 960038 HTTP header is restricted by policy
|
||||
|
||||
Regular expressions fixes:
|
||||
- Regular expressions with @ at end of beginning (for example "@import)
|
||||
- Regular expressions with un-escaped "."
|
||||
- Command Injections now always require certain characters both before and after the command. Important since many are common English words (finger, mail)
|
||||
- The command injection wget is not searched in the UA header as it has different meaning there.
|
||||
- LDAP Fixed to reduce FPs:
|
||||
+ More accurate regular expressions
|
||||
+ high bit characters not accpeted between signature tokens.
|
||||
- Do not detect <?xml as a PHP tag in both PHP injection and PHP source leakage
|
||||
- Removed Java from automation UA
|
||||
- When validating encoding, added regexp based chained rule that accepts both %xx and %uxxxxx encoding bypassing a limitation of "@validateUrlEncoding"
|
||||
|
||||
Additional rules logic:
|
||||
- Checks for empty headers in addition to missing ones (Host, Accept and User-Agent)
|
||||
- OPTIONS method does not require an accept header.
|
||||
- Apache keep alive request exception.
|
||||
- PROPFIND and OPTIONS can be used without content-encoding (like HEAD and GET)
|
||||
- Validate byte range checks by default only that no NULL char exists.
|
||||
- Added CSS to allowed extensions in strict rule sets.
|
||||
- Changed default action in file #50 to pass instead of deny.
|
||||
- Moved IP host header from protocol violations to protocol anomalies.
|
||||
|
||||
Modified descriptions:
|
||||
- 950107: URL Encoding Abuse Attack Attempt
|
||||
- 950801: UTF8 Encoding Abuse Attack Attempt
|
||||
- Added matched pattern in many events using capture and %{TX.0}
|
||||
- Added ctl:auditLogParts=+E for outbound events and attacks to collect response.
|
||||
|
||||
--
|
||||
Version 1.2 - 2006/11/19
|
||||
|
||||
Changes:
|
||||
+ Move all events to the range of events allocated to Thinking Stone, now Breach
|
||||
by prefixing all event IDs with "9".
|
||||
+ Reverse severities to follow the Syslog format used by ModSecurity, now 1 is
|
||||
the highest and 5 the lowest.
|
||||
|
||||
Bug fixes:
|
||||
+ Removed quotes from list of mime types inspected on exit (directive
|
||||
SecResponseBodyMimeType)
|
||||
+ Corrected "cd .." signature. Now the periods are escaped.
|
||||
+ Too many FPs with events 950903 & 950905. Commented them out until fixed.
|
||||
|
||||
--
|
||||
Version 1.1 - 2006/10/18
|
||||
|
||||
Initial version
|
||||
|
||||
--------------------------------
|
||||
version 1.4 build 2 - 2007/05/17
|
||||
--------------------------------
|
||||
New Feature:
|
||||
- Search for signatures in XML content
|
||||
|
||||
New Events:
|
||||
- 950107 - Unicode Full/Half Width Abuse Attack Attempt
|
||||
- 960911 - Invalid HTTP request line
|
||||
- 960904 - Request Missing Content-Type (when there is content)
|
||||
- 970018 - IIS installed in default location (any drive)
|
||||
- 950019 - Email Injection
|
||||
|
||||
Regular expressions fixes:
|
||||
- Further optimization of some regular expressions (using the non-greediness operator)
|
||||
|
||||
------------------------
|
||||
version 1.4 - 2007/05/02
|
||||
------------------------
|
||||
|
||||
New Events:
|
||||
- 970021 - WebLogic information disclosure
|
||||
Matching of "<title>JSP compile error</title>" in the response body, will trigger this rule, with severity 4 (Warning)
|
||||
- 950015,950910,950911 - HTTP Response Splitting
|
||||
Looking for HTTP Response Splitting patterns as described in Amit Klein's excellent article:
|
||||
http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf
|
||||
ModSecurity does not support compressed content at the moment. Thus, the following rules have been added:
|
||||
- 960902 - Content-Encoding in request not supported
|
||||
Any incoming compressed request will be denied
|
||||
- 960903 - Content-Encoding in response not suppoted
|
||||
An outgoing compressed response will be logged to alert, but ONLY ONCE.
|
||||
|
||||
False Positives Fixes:
|
||||
- Removed <.exe>,<.shtml> from restricted extensions
|
||||
- Will not be looking for SQL Injection signatures <root@>,<coalesce> in the Via request header
|
||||
- Excluded Referer header from SQL injection, XSS and command injection rules
|
||||
- Excluded X-OS-Prefs header from command injection rule
|
||||
- Will be looking for command injection signatures in
|
||||
REQUEST_COOKIES|REQUEST_COOKIES_NAMES instead of REQUEST_HEADERS:Cookie.
|
||||
- Allowing charset specification in the <application/x-www-form-urlencoded> Content-Type
|
||||
|
||||
Additional rules logic:
|
||||
- Corrected match of OPTIONS method in event 960015
|
||||
- Changed location for event 960014 (proxy access) to REQUEST_URI_RAW
|
||||
- Moved all rules apart from method inspection from phase 1 to phase 2 -
|
||||
This will enable viewing content if such a rule triggers as well as setting
|
||||
exceptions using Apache scope tags.
|
||||
- Added match for double quote in addition to single quote for <or x=x> signature (SQL Injection)
|
||||
- Added 1=1 signature (SQL Injection)
|
||||
|
||||
--------------------------------
|
||||
version 1.3.2 build 4 2007/01/17
|
||||
--------------------------------
|
||||
|
||||
Fixed apache 2.4 dummy requests exclusion
|
||||
Added persistent PDF UXSS detection rule
|
||||
|
||||
--------------------------------
|
||||
Version 1.3.2 build 3 2007/01/10
|
||||
--------------------------------
|
||||
|
||||
Fixed regular expression in rule 960010 (file #30) to allow multipart form data
|
||||
content
|
||||
|
||||
--------------------------
|
||||
Version 1.3.2 - 2006/12/27
|
||||
--------------------------
|
||||
|
||||
New events:
|
||||
- 960037 Directory is restricted by policy
|
||||
- 960038 HTTP header is restricted by policy
|
||||
|
||||
Regular expressions fixes:
|
||||
- Regular expressions with @ at end of beginning (for example "@import)
|
||||
- Regular expressions with un-escaped "."
|
||||
- Command Injections now always require certain characters both before and after the command. Important since many are common English words (finger, mail)
|
||||
- The command injection wget is not searched in the UA header as it has different meaning there.
|
||||
- LDAP Fixed to reduce FPs:
|
||||
+ More accurate regular expressions
|
||||
+ high bit characters not accpeted between signature tokens.
|
||||
- Do not detect <?xml as a PHP tag in both PHP injection and PHP source leakage
|
||||
- Removed Java from automation UA
|
||||
- When validating encoding, added regexp based chained rule that accepts both %xx and %uxxxxx encoding bypassing a limitation of "@validateUrlEncoding"
|
||||
|
||||
Additional rules logic:
|
||||
- Checks for empty headers in addition to missing ones (Host, Accept and User-Agent)
|
||||
- OPTIONS method does not require an accept header.
|
||||
- Apache keep alive request exception.
|
||||
- PROPFIND and OPTIONS can be used without content-encoding (like HEAD and GET)
|
||||
- Validate byte range checks by default only that no NULL char exists.
|
||||
- Added CSS to allowed extensions in strict rule sets.
|
||||
- Changed default action in file #50 to pass instead of deny.
|
||||
- Moved IP host header from protocol violations to protocol anomalies.
|
||||
|
||||
Modified descriptions:
|
||||
- 950107: URL Encoding Abuse Attack Attempt
|
||||
- 950801: UTF8 Encoding Abuse Attack Attempt
|
||||
- Added matched pattern in many events using capture and %{TX.0}
|
||||
- Added ctl:auditLogParts=+E for outbound events and attacks to collect response.
|
||||
|
||||
------------------------
|
||||
Version 1.2 - 2006/11/19
|
||||
------------------------
|
||||
|
||||
Changes:
|
||||
+ Move all events to the range of events allocated to Thinking Stone, now Breach
|
||||
by prefixing all event IDs with "9".
|
||||
+ Reverse severities to follow the Syslog format used by ModSecurity, now 1 is
|
||||
the highest and 5 the lowest.
|
||||
|
||||
Bug fixes:
|
||||
+ Removed quotes from list of mime types inspected on exit (directive
|
||||
SecResponseBodyMimeType)
|
||||
+ Corrected "cd .." signature. Now the periods are escaped.
|
||||
+ Too many FPs with events 950903 & 950905. Commented them out until fixed.
|
||||
|
||||
------------------------
|
||||
Version 1.1 - 2006/10/18
|
||||
------------------------
|
||||
|
||||
Initial version
|
||||
|
||||
678
rules/LICENSE
678
rules/LICENSE
@@ -1,339 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
358
rules/README
358
rules/README
@@ -1,179 +1,179 @@
|
||||
|
||||
|
||||
ModSecurity Core Rule Set
|
||||
==============================
|
||||
|
||||
(c) 2006 Breach Secuiry Inc.
|
||||
|
||||
The ModSecurity Core Rule Set is provided to you under the terms and
|
||||
conditions of GPL version 2
|
||||
|
||||
This directory contains the files for Core ModSecurity Rule Set
|
||||
The rules are compatible with ModSecurity 2.1 (as of version 1.3.2)
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Using ModSecurity requires rules. In order to enable users to take full
|
||||
advantage of ModSecurity immediately, Breach Security Inc. is providing a free
|
||||
Core rule set. Unlike intrusion detection and prevention systems which
|
||||
rely on signature specific to known vulnerabilities, the Core Rule Set
|
||||
provides generic protection from unknown vulnerabilities often found in web
|
||||
application that are in most cases custom coded.
|
||||
|
||||
Keep in mind that a predefined rule set is only part of the work required to
|
||||
protect your web site. We strongly urge you to consult Ivan Ristic's book,
|
||||
"Apache Security" in order to harden your Apache web server. You may also
|
||||
consider writing custom rules for providing a positive security envelope to
|
||||
your application or critical parts of it. Breach Security can provide you with
|
||||
training and professional services to assist you in doing that. The Core
|
||||
Rule Set is heavily commented to allow it to be used as a step-by-step
|
||||
deployment guide for ModSecurity.
|
||||
|
||||
For more information refer to the Core Rule Set page at
|
||||
http://www.modsecurity.org/
|
||||
|
||||
|
||||
Core Rule Set Structure & Usage
|
||||
------------------------------------
|
||||
|
||||
To activate the rules for your web server installation:
|
||||
|
||||
1) You may want to edit and customize modsecurity_crs_10_config.conf.
|
||||
Additionally you may want to edit modsecurity_crs_30_http_policy.conf
|
||||
which enforces an application specific HTTP protocol usage.
|
||||
|
||||
2) Add the following line to your httpd.conf (assuming
|
||||
you've placed the rule files into conf/modsecurity/):
|
||||
|
||||
Include conf/modsecurity/*.conf
|
||||
|
||||
3) Restart web server.
|
||||
|
||||
4) Make sure your web sites are still running fine.
|
||||
|
||||
5) Simulate an attack against the web server. Then check
|
||||
the attack was correctly logged in the Apache error log,
|
||||
ModSecurity debug log (if you enabled it) and ModSecurity
|
||||
audit log (if you enabled it).
|
||||
|
||||
6) If you configured your audit log entries to be transported
|
||||
to ModSecurity Console in real time, check the alert was
|
||||
correctly recorded there too.
|
||||
|
||||
About Regular Expressions
|
||||
-------------------------
|
||||
|
||||
One of the advantages of the Core Rule Set, being a set of text files is your
|
||||
ability to modify it. However you will find that the regular expressions used
|
||||
are very complex.
|
||||
|
||||
Since regular expressions are much more efficient if assembled into a single
|
||||
expression and optimized, a generation script takes a list of patterns that
|
||||
are required for a rule and optimize them into a most efficient regular
|
||||
expression.
|
||||
|
||||
We plan to release the optimization script shortly to allow much easier editing
|
||||
of regular expressions.
|
||||
|
||||
|
||||
Core Rule Set Content
|
||||
--------------------------
|
||||
|
||||
In order to provide generic web applications protection, the Core Rule Set
|
||||
uses the following techniques:
|
||||
|
||||
1. HTTP protection - detecting violations of the HTTP protocol and a locally
|
||||
defined usage policy.
|
||||
|
||||
2. Common Web Attacks Protection - detecting common web application security
|
||||
attack.
|
||||
|
||||
3. Automation detection - Detecting bots, crawlers, scanners and other surface
|
||||
malicious activity.
|
||||
|
||||
4. Trojan Protection - Detecting access to Trojans horses.
|
||||
|
||||
5. Errors Hiding <EFBFBD> Disguising error messages sent by the server
|
||||
|
||||
In addition the rule set also hints at the power of ModSecurity beyond
|
||||
providing security by reporting access from the major search engines to your
|
||||
site.
|
||||
|
||||
|
||||
HTTP Protection - This first line of protection ensures that all abnormal HTTP
|
||||
requests are detected. This line of defense eliminates a large number of
|
||||
automated and non targeted attacks as well as protects the web server itself.
|
||||
Common Web Attacks Protection Rules on the second level address the common web
|
||||
application security attack methods. These are the issues that can appear in
|
||||
any web application. Some of the issues addressed are:
|
||||
|
||||
- SQL Injection
|
||||
- Cross-Site Scripting (XSS)
|
||||
- OS Command execution
|
||||
- Remote code inclusion
|
||||
- LDAP Injection
|
||||
- SSI Injection
|
||||
- Information leak
|
||||
- Buffer overflows
|
||||
- File disclosure
|
||||
|
||||
Automation Detection - Automated clients are both a security risk and a
|
||||
commercial risk. Automated crawlers collect information from your site, consume
|
||||
bandwidth and might also search for vulnerabilities on the web site. Automation
|
||||
detection is especially useful for generic detection of comments spam.
|
||||
|
||||
|
||||
Trojan Protection - ModSecurity Core Rule Set detects access to back doors
|
||||
installed on a web server. This feature is very important in a hosting
|
||||
environment when some of this backdoors may be uploaded in a legitimate way and
|
||||
used maliciously. In addition the Core Rule Set includes a hook for adding
|
||||
an Anti-Virus program such as ClamAV for checking file uploads.
|
||||
|
||||
Errors Hiding - If all fails, the Core Rule Set will detect errors sent by
|
||||
the web server. Detecting and blocking errors prevents attackers from
|
||||
collecting reconnaissance information about the web application and also server
|
||||
as a last line of defense in case an attack was not detected eariler.
|
||||
|
||||
|
||||
Few Word of Caution
|
||||
-------------------
|
||||
|
||||
As with every new technology, using the ModSecurity Core Rule Set requires some caution:
|
||||
|
||||
- Every Rule Set can have false positive in new environments and any new
|
||||
installation should initially use the log only Rule Set version or if no such
|
||||
version is available, set ModSecurity to Detection only using the SecRuleEngine
|
||||
DetectionOnly command.
|
||||
|
||||
After running ModSecurity in a detection only mode for a while review the evens
|
||||
generated and decide if any modification to the rule set should be made before
|
||||
moving to protection mode.
|
||||
|
||||
- Freely available wide spread signatures have their down side as attackers may
|
||||
examine them and find ways to bypass them. Especially note that the automation
|
||||
detection signatures are relatively easy to evade and should not be viewed as a
|
||||
security mechanism but only as a "nuisance reduction" mechanism.
|
||||
|
||||
|
||||
Road Map
|
||||
--------
|
||||
|
||||
This rule set is both young and old. Breach Security has a long experience with
|
||||
rules and signatures for application security protection and the Core Rule
|
||||
Set is based on this experience. On the other hand, this is a first cut of a
|
||||
ModSecurity rule set so your feedback and remarks, either directly or through
|
||||
the ModSecurity mailing list would be greatly appreciated.
|
||||
|
||||
Going forward we plan to:
|
||||
|
||||
- Utilize ModSecurity 2.0 support for events correlation to detect denial of
|
||||
service attacks, brute force attacks and attack reconnaissance
|
||||
|
||||
- Add a framework for validating SOAP requests.
|
||||
|
||||
- Add signatures for key known vulnerabilities.
|
||||
|
||||
Anything else you would want?
|
||||
|
||||
|
||||
|
||||
ModSecurity Core Rule Set
|
||||
==============================
|
||||
|
||||
(c) 2006 Breach Secuiry Inc.
|
||||
|
||||
The ModSecurity Core Rule Set is provided to you under the terms and
|
||||
conditions of GPL version 2
|
||||
|
||||
This directory contains the files for Core ModSecurity Rule Set
|
||||
The rules are compatible with ModSecurity 2.1 (as of version 1.3.2)
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Using ModSecurity requires rules. In order to enable users to take full
|
||||
advantage of ModSecurity immediately, Breach Security Inc. is providing a free
|
||||
Core rule set. Unlike intrusion detection and prevention systems which
|
||||
rely on signature specific to known vulnerabilities, the Core Rule Set
|
||||
provides generic protection from unknown vulnerabilities often found in web
|
||||
application that are in most cases custom coded.
|
||||
|
||||
Keep in mind that a predefined rule set is only part of the work required to
|
||||
protect your web site. We strongly urge you to consult Ivan Ristic's book,
|
||||
"Apache Security" in order to harden your Apache web server. You may also
|
||||
consider writing custom rules for providing a positive security envelope to
|
||||
your application or critical parts of it. Breach Security can provide you with
|
||||
training and professional services to assist you in doing that. The Core
|
||||
Rule Set is heavily commented to allow it to be used as a step-by-step
|
||||
deployment guide for ModSecurity.
|
||||
|
||||
For more information refer to the Core Rule Set page at
|
||||
http://www.modsecurity.org/
|
||||
|
||||
|
||||
Core Rule Set Structure & Usage
|
||||
------------------------------------
|
||||
|
||||
To activate the rules for your web server installation:
|
||||
|
||||
1) You may want to edit and customize modsecurity_crs_10_config.conf.
|
||||
Additionally you may want to edit modsecurity_crs_30_http_policy.conf
|
||||
which enforces an application specific HTTP protocol usage.
|
||||
|
||||
2) Add the following line to your httpd.conf (assuming
|
||||
you've placed the rule files into conf/modsecurity/):
|
||||
|
||||
Include conf/modsecurity/*.conf
|
||||
|
||||
3) Restart web server.
|
||||
|
||||
4) Make sure your web sites are still running fine.
|
||||
|
||||
5) Simulate an attack against the web server. Then check
|
||||
the attack was correctly logged in the Apache error log,
|
||||
ModSecurity debug log (if you enabled it) and ModSecurity
|
||||
audit log (if you enabled it).
|
||||
|
||||
6) If you configured your audit log entries to be transported
|
||||
to ModSecurity Console in real time, check the alert was
|
||||
correctly recorded there too.
|
||||
|
||||
About Regular Expressions
|
||||
-------------------------
|
||||
|
||||
One of the advantages of the Core Rule Set, being a set of text files is your
|
||||
ability to modify it. However you will find that the regular expressions used
|
||||
are very complex.
|
||||
|
||||
Since regular expressions are much more efficient if assembled into a single
|
||||
expression and optimized, a generation script takes a list of patterns that
|
||||
are required for a rule and optimize them into a most efficient regular
|
||||
expression.
|
||||
|
||||
We plan to release the optimization script shortly to allow much easier editing
|
||||
of regular expressions.
|
||||
|
||||
|
||||
Core Rule Set Content
|
||||
--------------------------
|
||||
|
||||
In order to provide generic web applications protection, the Core Rule Set
|
||||
uses the following techniques:
|
||||
|
||||
1. HTTP protection - detecting violations of the HTTP protocol and a locally
|
||||
defined usage policy.
|
||||
|
||||
2. Common Web Attacks Protection - detecting common web application security
|
||||
attack.
|
||||
|
||||
3. Automation detection - Detecting bots, crawlers, scanners and other surface
|
||||
malicious activity.
|
||||
|
||||
4. Trojan Protection - Detecting access to Trojans horses.
|
||||
|
||||
5. Errors Hiding - Disguising error messages sent by the server
|
||||
|
||||
In addition the rule set also hints at the power of ModSecurity beyond
|
||||
providing security by reporting access from the major search engines to your
|
||||
site.
|
||||
|
||||
|
||||
HTTP Protection - This first line of protection ensures that all abnormal HTTP
|
||||
requests are detected. This line of defense eliminates a large number of
|
||||
automated and non targeted attacks as well as protects the web server itself.
|
||||
Common Web Attacks Protection Rules on the second level address the common web
|
||||
application security attack methods. These are the issues that can appear in
|
||||
any web application. Some of the issues addressed are:
|
||||
|
||||
- SQL Injection
|
||||
- Cross-Site Scripting (XSS)
|
||||
- OS Command execution
|
||||
- Remote code inclusion
|
||||
- LDAP Injection
|
||||
- SSI Injection
|
||||
- Information leak
|
||||
- Buffer overflows
|
||||
- File disclosure
|
||||
|
||||
Automation Detection - Automated clients are both a security risk and a
|
||||
commercial risk. Automated crawlers collect information from your site, consume
|
||||
bandwidth and might also search for vulnerabilities on the web site. Automation
|
||||
detection is especially useful for generic detection of comments spam.
|
||||
|
||||
|
||||
Trojan Protection - ModSecurity Core Rule Set detects access to back doors
|
||||
installed on a web server. This feature is very important in a hosting
|
||||
environment when some of this backdoors may be uploaded in a legitimate way and
|
||||
used maliciously. In addition the Core Rule Set includes a hook for adding
|
||||
an Anti-Virus program such as ClamAV for checking file uploads.
|
||||
|
||||
Errors Hiding - If all fails, the Core Rule Set will detect errors sent by
|
||||
the web server. Detecting and blocking errors prevents attackers from
|
||||
collecting reconnaissance information about the web application and also server
|
||||
as a last line of defense in case an attack was not detected eariler.
|
||||
|
||||
|
||||
Few Word of Caution
|
||||
-------------------
|
||||
|
||||
As with every new technology, using the ModSecurity Core Rule Set requires some caution:
|
||||
|
||||
- Every Rule Set can have false positive in new environments and any new
|
||||
installation should initially use the log only Rule Set version or if no such
|
||||
version is available, set ModSecurity to Detection only using the SecRuleEngine
|
||||
DetectionOnly command.
|
||||
|
||||
After running ModSecurity in a detection only mode for a while review the evens
|
||||
generated and decide if any modification to the rule set should be made before
|
||||
moving to protection mode.
|
||||
|
||||
- Freely available wide spread signatures have their down side as attackers may
|
||||
examine them and find ways to bypass them. Especially note that the automation
|
||||
detection signatures are relatively easy to evade and should not be viewed as a
|
||||
security mechanism but only as a "nuisance reduction" mechanism.
|
||||
|
||||
|
||||
Road Map
|
||||
--------
|
||||
|
||||
This rule set is both young and old. Breach Security has a long experience with
|
||||
rules and signatures for application security protection and the Core Rule
|
||||
Set is based on this experience. On the other hand, this is a first cut of a
|
||||
ModSecurity rule set so your feedback and remarks, either directly or through
|
||||
the ModSecurity mailing list would be greatly appreciated.
|
||||
|
||||
Going forward we plan to:
|
||||
|
||||
- Utilize ModSecurity 2.0 support for events correlation to detect denial of
|
||||
service attacks, brute force attacks and attack reconnaissance
|
||||
|
||||
- Add a framework for validating SOAP requests.
|
||||
|
||||
- Add signatures for key known vulnerabilities.
|
||||
|
||||
Anything else you would want?
|
||||
|
||||
|
||||
@@ -1,74 +1,84 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:1,status:400"
|
||||
|
||||
# Accept only digits in content length
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^\d+$" "deny,log,auditlog,status:400,msg:'Content-Length HTTP header is not numeric', severity:'2',id:'960016'"
|
||||
|
||||
# Do not accept GET or HEAD requests with bodies
|
||||
# HTTP standard allows GET requests to have a body but this
|
||||
# feature is not used in real life. Attackers could try to force
|
||||
# a request body on an unsuspecting web applications.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^(GET|HEAD)$" "chain,deny,log,auditlog,status:400,msg:'GET or HEAD requests with bodies', severity:'2',id:'960011'"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0?$"
|
||||
|
||||
# Require Content-Length to be provided with every POST request.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^POST$" "chain,deny,log,auditlog,status:400,msg:'POST request must have a Content-Length header',id:'960012',severity:'4'"
|
||||
SecRule &REQUEST_HEADERS:Content-Length "@eq 0"
|
||||
|
||||
# Don't accept transfer encodings we know we don't know how to handle
|
||||
#
|
||||
# NOTE ModSecurity does not support chunked transfer encodings at
|
||||
# this time. You MUST reject all such requests.
|
||||
#
|
||||
SecRule HTTP_Transfer-Encoding "!^$" "deny,log,auditlog,status:501,msg:'ModSecurity does not support transfer encodings',id:'960013',severity:'5'"
|
||||
|
||||
# Check decodings
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "@validateUrlEncoding" \
|
||||
"chain, deny,log,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950107',severity:'4'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\%(?![0-9a-fA-F]{2}|u[0-9a-fA-F]{4})"
|
||||
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "@validateUtf8Encoding" "deny,log,auditlog,status:400,msg:'UTF8 Encoding Abuse Attack Attempt',id:'950801',severity:'4'"
|
||||
|
||||
# Proxy access attempt
|
||||
# NOTE Apache blocks such access by default if not set as a proxy. The rule is
|
||||
# included in case Apache proxy is misconfigured.
|
||||
SecRule REQUEST_URI ^http:/ "deny,log,auditlog,status:400,msg:'Proxy access attempt', severity:'2',id:'960014'"
|
||||
|
||||
#
|
||||
# Restrict type of characters sent
|
||||
#
|
||||
# NOTE In order to be broad and support localized applications this rule
|
||||
# only validates that NULL Is not used.
|
||||
#
|
||||
# The strict policy version also validates that protocol and application
|
||||
# generated fields are limited to printable ASCII.
|
||||
#
|
||||
# TODO If your application use the range 32-126 for parameters.
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
|
||||
"@validateByteRange 32-126" \
|
||||
"deny,log,auditlog,status:400,msg:'Request Missing an Accept Header', severity:'2',id:'960015',t:urlDecodeUni,phase:1"
|
||||
|
||||
SecRule ARGS|ARGS_NAMES "@validateByteRange 1-255" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',id:'960901',severity:'4',t:urlDecodeUni,phase:2"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:2,status:400"
|
||||
|
||||
|
||||
# Validate request line
|
||||
SecRule REQUEST_LINE "!^[a-z]{3,10}\s*(?:http\:\/\/[\w\-\.\/]*)??\/[\w\-\.\/]*(?:\?[\S]*)??\s*http\/[01]\.[901]$" \
|
||||
"t:none,t:lowercase,deny,log,auditlog,status:400,msg:'Invalid HTTP Request Line',,id:'960911',severity:'2'"
|
||||
|
||||
|
||||
# Accept only digits in content length
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^\d+$" "deny,log,auditlog,status:400,msg:'Content-Length HTTP header is not numeric', severity:'2',,id:'960016',"
|
||||
|
||||
# Do not accept GET or HEAD requests with bodies
|
||||
# HTTP standard allows GET requests to have a body but this
|
||||
# feature is not used in real life. Attackers could try to force
|
||||
# a request body on an unsuspecting web applications.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^(GET|HEAD)$" "chain,deny,log,auditlog,status:400,msg:'GET or HEAD requests with bodies', severity:'2',,id:'960011',"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0?$"
|
||||
|
||||
# Require Content-Length to be provided with every POST request.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^POST$" "chain,deny,log,auditlog,status:400,msg:'POST request must have a Content-Length header',,id:'960012',severity:'4'"
|
||||
SecRule &REQUEST_HEADERS:Content-Length "@eq 0"
|
||||
|
||||
# Don't accept transfer encodings we know we don't know how to handle
|
||||
#
|
||||
# NOTE ModSecurity does not support chunked transfer encodings at
|
||||
# this time. You MUST reject all such requests.
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Transfer-Encoding "!^$" "deny,log,auditlog,status:501,msg:'ModSecurity does not support transfer encodings',,id:'960013',severity:'3'"
|
||||
|
||||
# Check decodings
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "@validateUrlEncoding" \
|
||||
"chain, deny,log,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',,id:'950107',severity:'4'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\%(?!$|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})"
|
||||
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "@validateUtf8Encoding" "deny,log,auditlog,status:400,msg:'UTF8 Encoding Abuse Attack Attempt',,id:'950801',severity:'4'"
|
||||
|
||||
# Disallow use of full-width unicode
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\%u[fF]{2}[0-9a-fA-F]{2}" \
|
||||
"t:none,deny,log,auditlog,status:400,msg:'Unicode Full/Half Width Abuse Attack Attempt',,id:'950116',severity:'4'"
|
||||
|
||||
# Proxy access attempt
|
||||
# NOTE Apache blocks such access by default if not set as a proxy. The rule is
|
||||
# included in case Apache proxy is misconfigured.
|
||||
SecRule REQUEST_URI_RAW ^http:/ "deny,log,auditlog,status:400,msg:'Proxy access attempt', severity:'2',,id:'960014',"
|
||||
|
||||
#
|
||||
# Restrict type of characters sent
|
||||
#
|
||||
# NOTE In order to be broad and support localized applications this rule
|
||||
# only validates that NULL Is not used.
|
||||
#
|
||||
# The strict policy version also validates that protocol and application
|
||||
# generated fields are limited to printable ASCII.
|
||||
#
|
||||
# TODO If your application use the range 32-126 for parameters.
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
|
||||
"@validateByteRange 32-126" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',,id:'960018',severity:'4',t:urlDecodeUni,phase:1"
|
||||
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS:Referer "@validateByteRange 1-255" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',,id:'960901',severity:'4',t:urlDecodeUni,phase:2"
|
||||
|
||||
@@ -1,50 +1,55 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:1,status:400"
|
||||
|
||||
# Do not accept requests without common headers.
|
||||
#
|
||||
# Implies either an attacker or a legitimate automation client.
|
||||
#
|
||||
SecRule REQUEST_URI "^/$" "chain,skip:4"
|
||||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^Apache.*\(internal dummy connection\)$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||||
"skip:1,deny,log,auditlog,status:400,msg:'Request Missing a Host Header',id:'960008',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Host "^$" \
|
||||
"deny,log,auditlog,status:400,msg:'Request Missing a Host Header',id:'960008',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
|
||||
"chain,skip:1,deny,log,auditlog,status:400,msg:'Request Missing an Accept Header', severity:'2',id:'960015'"
|
||||
SecRule REQUEST_METHOD "!OPTIONS"
|
||||
SecRule REQUEST_HEADERS:Accept "^$" \
|
||||
"chain,deny,log,auditlog,status:400,msg:'Request Missing an Accept Header', severity:'2',id:'960015'"
|
||||
SecRule REQUEST_METHOD "!OPTIONS"
|
||||
|
||||
SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \
|
||||
"skip:1,deny,log,auditlog,status:400,msg:'Request Missing a User Agent Header',id:'960009',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^$" \
|
||||
"deny,log,auditlog,status:400,msg:'Request Missing a User Agent Header',id:'960009',severity:'4'"
|
||||
|
||||
|
||||
# Check that the host header is not an IP address
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Host "^[\d\.]+$" "deny,log,auditlog,status:400,msg:'Host header is a numeric IP address', severity:'2',id:'960017'"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:2,status:400"
|
||||
|
||||
# Do not accept requests without common headers.
|
||||
#
|
||||
# Implies either an attacker or a legitimate automation client.
|
||||
#
|
||||
SecRule REQUEST_URI "^/$" "chain,skip:4"
|
||||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^Apache.*\(internal dummy connection\)$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||||
"skip:1,deny,log,auditlog,status:400,msg:'Request Missing a Host Header',,id:'960008',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Host "^$" \
|
||||
"deny,log,auditlog,status:400,msg:'Request Missing a Host Header',,id:'960008',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
|
||||
"chain,skip:1,deny,log,auditlog,status:400,msg:'Request Missing an Accept Header', severity:'2',,id:'960015',"
|
||||
SecRule REQUEST_METHOD "!^OPTIONS$" "t:none"
|
||||
SecRule REQUEST_HEADERS:Accept "^$" \
|
||||
"chain,deny,log,auditlog,status:400,msg:'Request Missing an Accept Header', severity:'2',,id:'960015',"
|
||||
SecRule REQUEST_METHOD "!^OPTIONS$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \
|
||||
"skip:1,deny,log,auditlog,status:400,msg:'Request Missing a User Agent Header',,id:'960009',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^$" \
|
||||
"deny,log,auditlog,status:400,msg:'Request Missing a User Agent Header',,id:'960009',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Content-Type "@eq 0" \
|
||||
"chain,deny,log,auditlog,status:400,msg:'Request Containing Content, but Missing Content-Type header',,id:'960904',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0$"
|
||||
|
||||
|
||||
# Check that the host header is not an IP address
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Host "^[\d\.]+$" "deny,log,auditlog,status:400,msg:'Host header is a numeric IP address', severity:'2',,id:'960017',"
|
||||
|
||||
@@ -1,83 +1,94 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO While some of the pattern groups such as command injection are usually
|
||||
# safe of false positives, other pattern groups such as SQL injection and
|
||||
# XSS may require setting exceptions and therefore are set to log only by
|
||||
# default.
|
||||
#
|
||||
# Start ModSecurity in monitoring only mode and check whether your
|
||||
# application requires exceptions for a specific URL, Pattern or source IP
|
||||
# before moving to blocking mode.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,status:500,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
|
||||
|
||||
# Session fixation
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\.cookie\b.*?;\W*?(?:expires|domain)\W*?=|\bhttp-equiv\W+set-cookie\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Session Fixation. Matched signature <%{TX.0}>',id:'950009',severity:'2'"
|
||||
|
||||
# Blind SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:ys\.(?:user_(?:(?:t(?:ab(?:_column|le)|rigger)|object|view)s|c(?:onstraints|atalog))|all_tables|tab)|elect\b.{0,40}\b(?:substring|ascii|user))|m(?:sys(?:(?:queri|ac)e|relationship|column|object)s|ysql.user)|c(?:onstraint_type|harindex)|attnotnull)\b|(?:locate|instr)\W+\()|\@\@spid\b)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950007',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:benchmark|encode)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950903',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:(?:s(?:ys(?:(?:(?:process|tabl)e|filegroup|object)s|c(?:o(?:nstraint|lumn)s|at)|dba|ibm)|ubstr(?:ing)?)|user_(?:(?:(?:constrain|objec)t|tab(?:_column|le)|ind_column|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|(?:dba|mb)_users|xtype\W+\bchar|rownum)\b|t(?:able_name\b|extpos\W+\())" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950904',severity:'2'"
|
||||
|
||||
# SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:elect\b(?:.{1,100}?\b(?:(?:length|count|top)\b.{1,100}?\bfrom|from\b.{1,100}?\bwhere)|.*?\b(?:d(?:ump\b.*\bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebtask)|ql_(?:longvarchar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|e(?:xecresultset|numdsn)|(?:terminat|dirtre)e|availablemedia|loginconfig|cmdshell|filelist|makecab|ntsec)|u(?:nion\b.{1,100}?\bselect|tl_(?:file|http))|group\b.*\bby\b.{1,100}?\bhaving|load\b\W*?\bdata\b.*\binfile|(?:n?varcha|tbcreato)r|autonomous_transaction|open(?:rowset|query)|dbms_java)\b|i(?:n(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)\b|(?:f(?:\b\W*?\(\W*?\bbenchmark|null\b)|snull\b)\W*?\()|(?:having|or|and)\b\s+?(?:\d{1,10}|'[^=]{1,10}')\s*?[=<>]+|(?:print\]\b\W*?\@|root)\@|c(?:ast\b\W*?\(|oalesce\b))|(?:;\W*?\b(?:shutdown|drop)|\@\@version)\b|'(?:s(?:qloledb|a)|msdasql|dbo)')" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950001',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:rel(?:(?:nam|typ)e|kind)|a(?:ttn(?:ame|um)|scii)|c(?:o(?:nver|un)t|ha?r)|s(?:hutdown|elect)|to_(?:numbe|cha)r|u(?:pdate|nion)|d(?:elete|rop)|group\b\W*\bby|having|insert|length|where)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950905',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:user_(?:(?:object|table|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|substr(?:ing)?|table_name|mb_users|rownum)\b" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950906',severity:'2'"
|
||||
|
||||
# XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:on(?:(?:mo(?:use(?:o(?:ver|ut)|down|move|up)|ve)|key(?:press|down|up)|c(?:hange|lick)|s(?:elec|ubmi)t|(?:un)?load|dragdrop|resize|focus|blur)\b\W*?=|abort\b)|(?:l(?:owsrc\b\W*?\b(?:(?:java|vb)script|shell)|ivescript)|(?:href|url)\b\W*?\b(?:(?:java|vb)script|shell)|background-image|mocha):|type\b\W*?\b(?:text\b(?:\W*?\b(?:j(?:ava)?|ecma)script\b| [vbscript])|application\b\W*?\bx-(?:java|vb)script\b)|s(?:(?:tyle\b\W*=.*\bexpression\b\W*|ettimeout\b\W*?)\(|rc\b\W*?\b(?:(?:java|vb)script|shell|http):)|(?:c(?:opyparentfolder|reatetextrange)|get(?:special|parent)folder)\b|a(?:ctivexobject\b|lert\b\W*?\())|<(?:(?:body\b.*?\b(?:backgroun|onloa)d|input\b.*?\\btype\b\W*?\bimage)\b|!\[CDATA\[|script|meta)|(?:\.(?:(?:execscrip|addimpor)t|(?:fromcharcod|cooki)e|innerhtml)|\@import)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Cross-site Scripting (XSS) Attack. Matched signature <%{TX.0}>',id:'950004',severity:'2'"
|
||||
|
||||
# file injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:\.(?:ht(?:access|passwd|group)|www_?acl)|global\.asa|httpd\.conf|boot\.ini)\b|\/etc\/)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Remote File Access Attempt. Matched signature <%{TX.0}>',id:'950005',severity:'2'"
|
||||
|
||||
# Command access
|
||||
SecRule REQUEST_FILENAME "\b(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Access. Matched signature <%{TX.0}>',id:'950002',severity:'2'"
|
||||
|
||||
# Command injection
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:(?:n(?:et(?:\b\W+?\blocalgroup|\.exe)|(?:map|c)\.exe)|t(?:racer(?:oute|t)|elnet\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\.exe|echo\b\W*?\by+)\b|c(?:md(?:(?:32)?\.exe\b|\b\W*?\/c)|d(?:\b\W*?[\\\/]|\W*?\.\.)|hmod.{0,40}?\+.{0,3}x))|[\;\|\`]\W*?\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\b|g(?:\+\+|cc\b))|\/(?:c(?:h(?:grp|mod|own|sh)|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|g(?:\+\+|cc)|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)(?:[\'\"\|\;\`\-\s]|$))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',id:'950006',severity:'2'"
|
||||
SecRule "ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent" \
|
||||
"\bwget\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',id:'950907',severity:'2'"
|
||||
|
||||
# Coldfusion injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "\bcf(?:usion_(?:d(?:bconnections_flush|ecrypt)|set(?:tings_refresh|odbcini)|getodbc(?:dsn|ini)|verifymail|encrypt)|_(?:(?:iscoldfusiondatasourc|getdatasourceusernam)e|setdatasource(?:password|username))|newinternal(?:adminsecurit|registr)y|admin_registry_(?:delete|set)|internaldebug)\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Injection of Undocumented ColdFusion Tags. Matched signature <%{TX.0}>',id:'950008',severity:'2'"
|
||||
|
||||
# LDAP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|])" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'LDAP Injection Attack. Matched signature <%{TX.0}>',id:'950010',severity:'2'"
|
||||
|
||||
# SSI injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "<!--\W*?#\W*?(?:e(?:cho|xec)|printenv|include|cmd)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SSI injection Attack. Matched signature <%{TX.0}>',id:'950011',severity:'2'"
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b|<\?(?!xml))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'PHP Injection Attack. Matched signature <%{TX.0}>',id:'950013',severity:'2'"
|
||||
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "http:\/\/[\w\.]+?\/.*?\.pdf\b[^\x0d\x0a]*#" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Persistent Universal PDF XSS attack',id:'950018',severity:'2'"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO While some of the pattern groups such as command injection are usually
|
||||
# safe of false positives, other pattern groups such as SQL injection and
|
||||
# XSS may require setting exceptions and therefore are set to log only by
|
||||
# default.
|
||||
#
|
||||
# Start ModSecurity in monitoring only mode and check whether your
|
||||
# application requires exceptions for a specific URL, Pattern or source IP
|
||||
# before moving to blocking mode.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,status:500,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
|
||||
|
||||
# Session fixation
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "(?:\.cookie\b.*?;\W*?(?:expires|domain)\W*?=|\bhttp-equiv\W+set-cookie\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Session Fixation. Matched signature <%{TX.0}>',,id:'950009',severity:'2'"
|
||||
|
||||
# Blind SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:ys\.(?:user_(?:(?:t(?:ab(?:_column|le)|rigger)|object|view)s|c(?:onstraints|atalog))|all_tables|tab)|elect\b.{0,40}\b(?:substring|ascii|user))|m(?:sys(?:(?:queri|ac)e|relationship|column|object)s|ysql.user)|c(?:onstraint_type|harindex)|attnotnull)\b|(?:locate|instr)\W+\()|\@\@spid\b)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950007',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "\b(?:benchmark|encode)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950903',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "\b(?:(?:s(?:ys(?:(?:(?:process|tabl)e|filegroup|object)s|c(?:o(?:nstraint|lumn)s|at)|dba|ibm)|ubstr(?:ing)?)|user_(?:(?:(?:constrain|objec)t|tab(?:_column|le)|ind_column|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|(?:dba|mb)_users|xtype\W+\bchar|rownum)\b|t(?:able_name\b|extpos\W+\())" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950904',severity:'2'"
|
||||
|
||||
# SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:elect\b(?:.{1,100}?\b(?:(?:length|count|top)\b.{1,100}?\bfrom|from\b.{1,100}?\bwhere)|.*?\b(?:d(?:ump\b.*\bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebtask)|ql_(?:longvarchar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|e(?:xecresultset|numdsn)|(?:terminat|dirtre)e|availablemedia|loginconfig|cmdshell|filelist|makecab|ntsec)|u(?:nion\b.{1,100}?\bselect|tl_(?:file|http))|group\b.*\bby\b.{1,100}?\bhaving|load\b\W*?\bdata\b.*\binfile|(?:n?varcha|tbcreato)r|autonomous_transaction|open(?:rowset|query)|1\s*=\s*1|dbms_java)\b|i(?:n(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)\b|(?:f(?:\b\W*?\(\W*?\bbenchmark|null\b)|snull\b)\W*?\()|(?:having|or|and)\b\s+(?:\d{1,10}|[\'\"][^=]{1,10}[\'\"])\s*[=<>]+|print\]\b\W*?\@\@|cast\b\W*?\()|(?:;\W*?\b(?:shutdown|drop)|\@\@version)\b|'(?:s(?:qloledb|a)|msdasql|dbo)')" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950001',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "\b(?:rel(?:(?:nam|typ)e|kind)|a(?:ttn(?:ame|um)|scii)|c(?:o(?:nver|un)t|ha?r)|s(?:hutdown|elect)|to_(?:numbe|cha)r|u(?:pdate|nion)|d(?:elete|rop)|group\b\W*\bby|having|insert|length|where)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950905',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "\b(?:user_(?:(?:object|table|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|substr(?:ing)?|table_name|mb_users|rownum)\b" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950906',severity:'2'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:via "\b(?:coalesce\b|root\@)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950908',severity:'2'"
|
||||
|
||||
# XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "(?:\b(?:on(?:(?:mo(?:use(?:o(?:ver|ut)|down|move|up)|ve)|key(?:press|down|up)|c(?:hange|lick)|s(?:elec|ubmi)t|(?:un)?load|dragdrop|resize|focus|blur)\b\W*?=|abort\b)|(?:l(?:owsrc\b\W*?\b(?:(?:java|vb)script|shell)|ivescript)|(?:href|url)\b\W*?\b(?:(?:java|vb)script|shell)|background-image|mocha):|type\b\W*?\b(?:text\b(?:\W*?\b(?:j(?:ava)?|ecma)script\b| [vbscript])|application\b\W*?\bx-(?:java|vb)script\b)|s(?:(?:tyle\b\W*=.*\bexpression\b\W*|ettimeout\b\W*?)\(|rc\b\W*?\b(?:(?:java|vb)script|shell|http):)|(?:c(?:opyparentfolder|reatetextrange)|get(?:special|parent)folder)\b|a(?:ctivexobject\b|lert\b\W*?\())|<(?:(?:body\b.*?\b(?:backgroun|onloa)d|input\b.*?\\btype\b\W*?\bimage)\b|!\[CDATA\[|script|meta)|(?:\.(?:(?:execscrip|addimpor)t|(?:fromcharcod|cooki)e|innerhtml)|\@import)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Cross-site Scripting (XSS) Attack. Matched signature <%{TX.0}>',,id:'950004',severity:'2'"
|
||||
|
||||
# file injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "(?:\b(?:\.(?:ht(?:access|passwd|group)|www_?acl)|global\.asa|httpd\.conf|boot\.ini)\b|\/etc\/)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Remote File Access Attempt. Matched signature <%{TX.0}>',,id:'950005',severity:'2'"
|
||||
|
||||
# Command access
|
||||
SecRule REQUEST_FILENAME "\b(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Access. Matched signature <%{TX.0}>',,id:'950002',severity:'2'"
|
||||
|
||||
# Command injection
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:'/(Cookie|Referer|X-OS-Prefs)/'|REQUEST_COOKIES|REQUEST_COOKIES_NAMES "(?:\b(?:(?:n(?:et(?:\b\W+?\blocalgroup|\.exe)|(?:map|c)\.exe)|t(?:racer(?:oute|t)|elnet\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\.exe|echo\b\W*?\by+)\b|c(?:md(?:(?:32)?\.exe\b|\b\W*?\/c)|d(?:\b\W*?[\\\/]|\W*?\.\.)|hmod.{0,40}?\+.{0,3}x))|[\;\|\`]\W*?\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\b|g(?:\+\+|cc\b))|\/(?:c(?:h(?:grp|mod|own|sh)|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|g(?:\+\+|cc)|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)(?:[\'\"\|\;\`\-\s]|$))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',,id:'950006',severity:'2'"
|
||||
SecRule "ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:User-Agent" \
|
||||
"\bwget\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',,id:'950907',severity:'2'"
|
||||
|
||||
# Coldfusion injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "\bcf(?:usion_(?:d(?:bconnections_flush|ecrypt)|set(?:tings_refresh|odbcini)|getodbc(?:dsn|ini)|verifymail|encrypt)|_(?:(?:iscoldfusiondatasourc|getdatasourceusernam)e|setdatasource(?:password|username))|newinternal(?:adminsecurit|registr)y|admin_registry_(?:delete|set)|internaldebug)\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Injection of Undocumented ColdFusion Tags. Matched signature <%{TX.0}>',,id:'950008',severity:'2'"
|
||||
|
||||
# LDAP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://*|!REQUEST_HEADERS:Referer "(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|])" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'LDAP Injection Attack. Matched signature <%{TX.0}>',,id:'950010',severity:'2'"
|
||||
|
||||
# SSI injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "<!--\W*?#\W*?(?:e(?:cho|xec)|printenv|include|cmd)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SSI injection Attack. Matched signature <%{TX.0}>',,id:'950011',severity:'2'"
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "(?:(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b|<\?(?!xml))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'PHP Injection Attack. Matched signature <%{TX.0}>',,id:'950013',severity:'2'"
|
||||
|
||||
# HTTP Response Splitting
|
||||
SecRule REQUEST_URI|REQUEST_HEADERS|REQUEST_HEADERS_NAMES "%0[ad]" \
|
||||
"t:none,t:lowercase,capture,ctl:auditLogParts=+E,deny,log,auditlog,status:400,msg:'HTTP Response Splitting Attack. Matched signature <%{TX.0}>',,id:'950910',severity:'1'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "(?:\bhttp.(?:0\.9|1\.[01])|<(?:html|meta)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:400,msg:'HTTP Response Splitting Attack. Matched signature <%{TX.0}>',,id:'950911',severity:'1'"
|
||||
|
||||
# UPDF XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "http:\/\/[\w\.]+?\/.*?\.pdf\b[^\x0d\x0a]*#" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Persistent Universal PDF XSS attack',,id:'950018',severity:'2'"
|
||||
|
||||
# Email Injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML://* "[\n\r]\s*(?:to|bcc|cc)\s*:.*?\@" \
|
||||
"t:none,t:lowercase,t:urlDecode,capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Email Injection Attack. Matched signature <%{TX.0}>',,id:'950019',severity:'2'"
|
||||
|
||||
|
||||
@@ -1,285 +1,297 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# Configuration contained in this file should be customized
|
||||
# for your specific requirements before deployment.
|
||||
#
|
||||
# Next to each rule there is a description of what it does. Each
|
||||
# location where customization is needed is marked with "TODO". It
|
||||
# is recommended that you:
|
||||
#
|
||||
# 1) Keep a copy of the original file. This will allow you to use
|
||||
# the "diff" command to quickly see the changes. It will also
|
||||
# make upgrades to future rule sets easier.
|
||||
#
|
||||
# 2) Document your changes thoroughly.
|
||||
#
|
||||
# You are advised to start with ModSecurity in detection mode only.
|
||||
# Switch to protection when you are comfortable with your rule set.
|
||||
# For maximum protection monitor your logs on daily basis (or
|
||||
# better).
|
||||
#
|
||||
|
||||
# TODO You may want to provide an error friendly message to your
|
||||
# users when you start rejecting requests. You can do this using
|
||||
# the Apache ErrorDocument directive. You should also add
|
||||
# mod_unique_id to your configuration and display the unique
|
||||
# request ID on the error page. This would allow your users to
|
||||
# report the request ID back to you so that you can investigate
|
||||
# the false positive (if that's what it is). A nice error page
|
||||
# usually reduces the impact of false positives on the users.
|
||||
#
|
||||
# The drawback of this user friendly approach is that it is
|
||||
# easier for the attackers to figure out there is an web
|
||||
# application firewall protecting the application.
|
||||
#
|
||||
# ErrorDocument 403 /path/to/error_document.php
|
||||
#
|
||||
# For more information see
|
||||
# http://httpd.apache.org/docs-2.0/custom-error.html
|
||||
|
||||
|
||||
## -- Configuration ----------------------------------------------------------
|
||||
|
||||
# Turn ModSecurity on ("On"), set to monitoring only
|
||||
# ("DetectionOnly") or turn off ("Off").
|
||||
#
|
||||
SecRuleEngine On
|
||||
|
||||
# Define which part of the HTTP transaction to inspect.
|
||||
#
|
||||
# Inspecting request body (SecRequestBodyAccess) should probably be always set
|
||||
# to "on". Only very high volume sites that never use POST requests might want
|
||||
# to set it to "off" to optimize performance.
|
||||
#
|
||||
# Inspecting response body is useful for monitoring for information leaks,
|
||||
# or for signs of intrusion. However, it does require all responses to be
|
||||
# buffered in memory. For most sites this should not be a problem, but special
|
||||
# care must be taken to avoid buffering file downloads (through
|
||||
# MIME type selection, as shown below).
|
||||
#
|
||||
# TODO If you decide to enable output filtering make sure to
|
||||
# review the list of scanned MIME types. If pages of the types specified
|
||||
# for outbound inspection are smaller than 512K in you application
|
||||
# (which is usually the case) you may reduce the SecResponseBodyLimit
|
||||
# to protect from potential denial of service attacks.
|
||||
#
|
||||
SecRequestBodyAccess On
|
||||
SecResponseBodyAccess On
|
||||
SecResponseBodyMimeType (null) text/html text/plain text/xml
|
||||
SecResponseBodyLimit 524288
|
||||
|
||||
|
||||
# What to do when an error is encountered.
|
||||
#
|
||||
# The default is to log the error and let the request go through.
|
||||
# This is a reasonable setting to start with because you do not
|
||||
# want to reject legitimate requests with an untuned rule set.
|
||||
#
|
||||
# If, after monitoring the performance of the rule set after a
|
||||
# sufficient period, you determine the rules never (or rarely
|
||||
# trigger on legitimate requests) you can change to something
|
||||
# else, such as "log,deny,status:500". You can also leave the
|
||||
# default setting here as is, but use per rule action configuration
|
||||
# to only configure some rules to reject requests, leaving most
|
||||
# of them to work in detection mode.
|
||||
#
|
||||
#SecDefaultAction "phase:2,log,pass,status:500"
|
||||
|
||||
# Set web server identification string
|
||||
#
|
||||
# TODO In case you use Apache, you may want specify a simple server signature
|
||||
# instead of the detailed Apache default signature that list most modules
|
||||
# used on the specific Apache deployment:
|
||||
# "Apache/2.2.0 (Fedora)"
|
||||
#
|
||||
SecServerSignature "Apache/2.2.0 (Fedora)"
|
||||
|
||||
## -- File uploads configuration -----------------------------------------------
|
||||
# Temporary file storage path.
|
||||
#
|
||||
# TODO Change the temporary folder setting to a path where only
|
||||
# the web server has access.
|
||||
#
|
||||
SecUploadDir /tmp
|
||||
|
||||
# Whether or not to keep the stored files.
|
||||
#
|
||||
# In most cases you don't want to keep the uploaded files (especially
|
||||
# when there is a lot of them). It may be useful to change the setting
|
||||
# to "RelevantOnly", in which case the files uploaded in suspicious
|
||||
# requests will be stored.
|
||||
#
|
||||
SecUploadKeepFiles Off
|
||||
|
||||
# Inspect uploaded files.
|
||||
#
|
||||
# TODO If there is a danger of attack through uploaded files then it
|
||||
# is possible to configure an external script to inspect each file
|
||||
# before it is seen by the application. An example script is
|
||||
# included with ModSecurity (/util/modsec-clamscan.pl).
|
||||
#
|
||||
# Inspecting uploaded files is especially important in a hosting,
|
||||
# community or blogging environments where uploading files is permitted.
|
||||
#
|
||||
# NOTE the t:none action is required in order not to process the files names
|
||||
# passed to the script based on previously defined actions in a
|
||||
# SecDefaultAction directive.
|
||||
#
|
||||
# SecRule FILES_TMPNAMES "@inspectFile /opt/apache/bin/inspect_script.pl" \
|
||||
# "t:none"
|
||||
|
||||
## -- Logging ----------------------------------------------------------------
|
||||
|
||||
# Whether to log requests to the forensic log.
|
||||
#
|
||||
# By default, only requests that trigger a ModSecurity events (as detected
|
||||
# by) or a serer error are logged ("RelevantOnly"). This is a reasonable
|
||||
# setting. Full logging can be set by using # "on". If the system is used
|
||||
# for protection only and no logging is desired (not reccomended) logging can
|
||||
# be turned of using "off"
|
||||
#
|
||||
# NOTE It is also possible to configure forensic logging on the
|
||||
# per request basis using the "auditlog" and "noauditlog" rule
|
||||
# actions.
|
||||
#
|
||||
# TODO The default rule set logs requests that generate a 404 "file not found"
|
||||
# response. These events are interesting, but may log a lot of information.
|
||||
# you may consider removing it by setting SecAuditLogRelevantStatus
|
||||
# to "^(?:5|4\d[^4])".
|
||||
#
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogRelevantStatus "^[45]"
|
||||
|
||||
# Log files structure
|
||||
#
|
||||
# You can select to log all events to a single log file (set SecAuditLogType to
|
||||
# "Serial") or to log each request to a separate file (set it to "Concurrent").
|
||||
# The former is usually easier to use, but if full logging is required or if
|
||||
# the protected system supports a large transaction volume the later may
|
||||
# be a better option.
|
||||
#
|
||||
# TODO Set the SecAuditLog (for "Serial" logging) or SecAuditLogStorageDir (for
|
||||
# "Concurrent" logging).
|
||||
#
|
||||
# TODO If you change from "Serial" to "Concurrent" uncomment the
|
||||
# SecAuditLogStorageDir directive and make sure the direcory specified
|
||||
# exists and has write permissions for the Apache user.
|
||||
|
||||
SecAuditLogType Serial
|
||||
SecAuditLog logs/modsec_audit.log
|
||||
# SecAuditLogStorageDir logs/modsec_audit
|
||||
|
||||
# Select what portions of the request to log
|
||||
#
|
||||
# Modify the string by adding any of the letter below to it:
|
||||
# A - audit log header (mandatory)
|
||||
# B - request headers
|
||||
# C - request body (present only if the request body exists and ModSecurity is
|
||||
# configured to intercept it)
|
||||
# E - intermediary response body (present only if ModSecurity is configured to
|
||||
# intercept response bodies, and if the audit log engine is configured to
|
||||
# record it). Intermediary response body is the same as the actual response
|
||||
# body unless ModSecurity intercepts the intermediary response body, in
|
||||
# which case the actual response body will contain the error message
|
||||
# (either the Apache default error message, or the ErrorDocument page).
|
||||
# F - final response headers (excluding the Date and Server headers, which are
|
||||
# always added by Apache in the late stage of content delivery).
|
||||
# H - audit log trailer
|
||||
# I - This part is a replacement for part C. It will log the same data as C in
|
||||
# all cases except when multipart/form-data encoding in used. In this case
|
||||
# it will log a fake application/x-www-form-urlencoded body that contains
|
||||
# the information about parameters but not about the files. This is handy
|
||||
# if you don't want to have (often large) files stored in your audit logs.
|
||||
# Z - final boundary, signifies the end of the entry (mandatory)
|
||||
|
||||
SecAuditLogParts "ABIFHZ"
|
||||
|
||||
# Create a separate log to monitor performance.
|
||||
#
|
||||
# TODO Performance monitoring only works with Apache 2.x. You need
|
||||
# to add mod_unique_id and mod_logio to your configuration. Then
|
||||
# uncomment the following two lines.
|
||||
#
|
||||
# LogFormat "%V %h %t %{UNIQUE_ID}e \"%r\" %>s %X | %I %O | %<{mod_security-time1}n %<{mod_security-time2}n %<{mod_security-time3}n %D" mperformance
|
||||
# CustomLog logs/modsec_performance.log mperformance
|
||||
|
||||
# Custom application access log.
|
||||
#
|
||||
# TODO You should consider creating a custom access log. It could contain
|
||||
# the performance metrics from above, but should also record the
|
||||
# session ID for every request. That would make it possible to
|
||||
# list all requests performed as part of a session.
|
||||
#
|
||||
# One custom log should be used per application but if you want
|
||||
# multiple applications to share one log file make sure each
|
||||
# line includes a unique application ID (unless the hostname is
|
||||
# sufficient for differentiation).
|
||||
|
||||
## -- Tuning and debugging
|
||||
|
||||
# This section include tuning and debugging directives that usually require no
|
||||
# modifications unless
|
||||
|
||||
|
||||
# Parameters separator
|
||||
#
|
||||
# Specifies which character to use as separator for
|
||||
# application/x-www-form-urlencoded content.
|
||||
# Defaults to "&". Applications are sometimes (very rarely) written to use
|
||||
# a semicolon (";").
|
||||
#
|
||||
# NOTE Changing the value for this directive has significant influence on how
|
||||
# ModSecurity works. Make the change only if you are absolutely sure it
|
||||
# is required.
|
||||
SecArgumentSeparator "&"
|
||||
|
||||
|
||||
# Selects the cookie format that will be used in the current configuration
|
||||
# context.
|
||||
#
|
||||
# Possible values are:
|
||||
# 0 - use version 0 (Netscape) cookies. This is what most applications use.
|
||||
# It is the default value.
|
||||
# 1 - use version 1 cookies.
|
||||
|
||||
SecCookieFormat 0
|
||||
|
||||
# Maximum size of the request body to keep in memory
|
||||
#
|
||||
# A higher value requires more server memory while a lower number would slow
|
||||
# the server due to additional disk access. By default the limit is 128 KB:
|
||||
SecRequestBodyInMemoryLimit 131072
|
||||
|
||||
|
||||
# Whether to send ModSecurity messages to a separate debug log.
|
||||
#
|
||||
# Debug messages are very useful for, well, debugging. The default
|
||||
# setting here copies (they always appear in the Apache error log)
|
||||
# only the most important messages (errors and warnings).
|
||||
#
|
||||
# NOTE Debug logging is generally very slow. You should never
|
||||
# use values greater than "3" in production.
|
||||
#
|
||||
SecDebugLog logs/modsec_debug.log
|
||||
SecDebugLogLevel 3
|
||||
|
||||
# Path where persistent data (e.g. IP address data, session data, etc) is to
|
||||
# be stored. Must be writable by the web server user.
|
||||
#
|
||||
# TODO It is advisable to create a directory structure for ModSecurity such as
|
||||
# /var/log/msa and create sub directories for SecDataDir, SecTmpDir,
|
||||
# SecUploadDir, SecAuditLog and SecAuditLogStorageDir
|
||||
# underneath it and set the permission for read and write only by the
|
||||
# Apache user.
|
||||
|
||||
SecDataDir /tmp
|
||||
|
||||
# Configures the directory where temporary files will be created.
|
||||
SecTmpDir /tmp
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# Configuration contained in this file should be customized
|
||||
# for your specific requirements before deployment.
|
||||
#
|
||||
# Next to each rule there is a description of what it does. Each
|
||||
# location where customization is needed is marked with "TODO". It
|
||||
# is recommended that you:
|
||||
#
|
||||
# 1) Keep a copy of the original file. This will allow you to use
|
||||
# the "diff" command to quickly see the changes. It will also
|
||||
# make upgrades to future rule sets easier.
|
||||
#
|
||||
# 2) Document your changes thoroughly.
|
||||
#
|
||||
# You are advised to start with ModSecurity in detection mode only.
|
||||
# Switch to protection when you are comfortable with your rule set.
|
||||
# For maximum protection monitor your logs on daily basis (or
|
||||
# better).
|
||||
#
|
||||
|
||||
# TODO You may want to provide an error friendly message to your
|
||||
# users when you start rejecting requests. You can do this using
|
||||
# the Apache ErrorDocument directive. You should also add
|
||||
# mod_unique_id to your configuration and display the unique
|
||||
# request ID on the error page. This would allow your users to
|
||||
# report the request ID back to you so that you can investigate
|
||||
# the false positive (if that's what it is). A nice error page
|
||||
# usually reduces the impact of false positives on the users.
|
||||
#
|
||||
# The drawback of this user friendly approach is that it is
|
||||
# easier for the attackers to figure out there is an web
|
||||
# application firewall protecting the application.
|
||||
#
|
||||
# ErrorDocument 403 /path/to/error_document.php
|
||||
#
|
||||
# For more information see
|
||||
# http://httpd.apache.org/docs-2.0/custom-error.html
|
||||
|
||||
|
||||
## -- Configuration ----------------------------------------------------------
|
||||
|
||||
# Turn ModSecurity on ("On"), set to monitoring only
|
||||
# ("DetectionOnly") or turn off ("Off").
|
||||
#
|
||||
SecRuleEngine On
|
||||
|
||||
# Define which part of the HTTP transaction to inspect.
|
||||
#
|
||||
# Inspecting request body (SecRequestBodyAccess) should probably be always set
|
||||
# to "on". Only very high volume sites that never use POST requests might want
|
||||
# to set it to "off" to optimize performance.
|
||||
#
|
||||
# Inspecting response body is useful for monitoring for information leaks,
|
||||
# or for signs of intrusion. However, it does require all responses to be
|
||||
# buffered in memory. For most sites this should not be a problem, but special
|
||||
# care must be taken to avoid buffering file downloads (through
|
||||
# MIME type selection, as shown below).
|
||||
#
|
||||
# TODO If you decide to enable output filtering make sure to
|
||||
# review the list of scanned MIME types. If pages of the types specified
|
||||
# for outbound inspection are smaller than 512K in you application
|
||||
# (which is usually the case) you may reduce the SecResponseBodyLimit
|
||||
# to protect from potential denial of service attacks.
|
||||
#
|
||||
SecRequestBodyAccess On
|
||||
SecResponseBodyAccess On
|
||||
SecResponseBodyMimeType (null) text/html text/plain text/xml
|
||||
SecResponseBodyLimit 524288
|
||||
|
||||
|
||||
# Initiate XML Processor in case of xml content-type
|
||||
#
|
||||
# TODO Remove this rule if you don't wish to parse XML request
|
||||
# Note that this will disable XML protection
|
||||
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
|
||||
"phase:1,pass,nolog,ctl:requestBodyProcessor=XML"
|
||||
|
||||
|
||||
# What to do when an error is encountered.
|
||||
#
|
||||
# The default is to log the error and let the request go through.
|
||||
# This is a reasonable setting to start with because you do not
|
||||
# want to reject legitimate requests with an untuned rule set.
|
||||
#
|
||||
# If, after monitoring the performance of the rule set after a
|
||||
# sufficient period, you determine the rules never (or rarely
|
||||
# trigger on legitimate requests) you can change to something
|
||||
# else, such as "log,deny,status:500". You can also leave the
|
||||
# default setting here as is, but use per rule action configuration
|
||||
# to only configure some rules to reject requests, leaving most
|
||||
# of them to work in detection mode.
|
||||
#
|
||||
#SecDefaultAction "phase:2,log,pass,status:500"
|
||||
|
||||
# Set web server identification string
|
||||
#
|
||||
# TODO In case you use Apache, you may want specify a simple server signature
|
||||
# instead of the detailed Apache default signature that list most modules
|
||||
# used on the specific Apache deployment:
|
||||
# "Apache/2.2.0 (Fedora)"
|
||||
#
|
||||
SecServerSignature "Apache/2.2.0 (Fedora)"
|
||||
|
||||
## -- File uploads configuration -----------------------------------------------
|
||||
# Temporary file storage path.
|
||||
#
|
||||
# TODO Change the temporary folder setting to a path where only
|
||||
# the web server has access.
|
||||
#
|
||||
SecUploadDir /tmp
|
||||
|
||||
# Whether or not to keep the stored files.
|
||||
#
|
||||
# In most cases you don't want to keep the uploaded files (especially
|
||||
# when there is a lot of them). It may be useful to change the setting
|
||||
# to "RelevantOnly", in which case the files uploaded in suspicious
|
||||
# requests will be stored.
|
||||
#
|
||||
SecUploadKeepFiles Off
|
||||
|
||||
# Inspect uploaded files.
|
||||
#
|
||||
# TODO If there is a danger of attack through uploaded files then it
|
||||
# is possible to configure an external script to inspect each file
|
||||
# before it is seen by the application. An example script is
|
||||
# included with ModSecurity (/util/modsec-clamscan.pl).
|
||||
#
|
||||
# Inspecting uploaded files is especially important in a hosting,
|
||||
# community or blogging environments where uploading files is permitted.
|
||||
#
|
||||
# NOTE the t:none action is required in order not to process the files names
|
||||
# passed to the script based on previously defined actions in a
|
||||
# SecDefaultAction directive.
|
||||
#
|
||||
# SecRule FILES_TMPNAMES "@inspectFile /opt/apache/bin/inspect_script.pl" \
|
||||
# "t:none"
|
||||
|
||||
## -- Logging ----------------------------------------------------------------
|
||||
|
||||
# Whether to log requests to the forensic log.
|
||||
#
|
||||
# By default, only requests that trigger a ModSecurity events (as detected
|
||||
# by) or a serer error are logged ("RelevantOnly"). This is a reasonable
|
||||
# setting. Full logging can be set by using # "on". If the system is used
|
||||
# for protection only and no logging is desired (not reccomended) logging can
|
||||
# be turned of using "off"
|
||||
#
|
||||
# NOTE It is also possible to configure forensic logging on the
|
||||
# per request basis using the "auditlog" and "noauditlog" rule
|
||||
# actions.
|
||||
#
|
||||
# TODO The default rule set logs requests that generate a 404 "file not found"
|
||||
# response. These events are interesting, but may log a lot of information.
|
||||
# you may consider removing it by setting SecAuditLogRelevantStatus
|
||||
# to "^(?:5|4\d[^4])".
|
||||
#
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogRelevantStatus "^[45]"
|
||||
|
||||
# Log files structure
|
||||
#
|
||||
# You can select to log all events to a single log file (set SecAuditLogType to
|
||||
# "Serial") or to log each request to a separate file (set it to "Concurrent").
|
||||
# The former is usually easier to use, but if full logging is required or if
|
||||
# the protected system supports a large transaction volume the later may
|
||||
# be a better option.
|
||||
#
|
||||
# TODO Set the SecAuditLog (for "Serial" logging) or SecAuditLogStorageDir (for
|
||||
# "Concurrent" logging).
|
||||
#
|
||||
# TODO If you change from "Serial" to "Concurrent" uncomment the
|
||||
# SecAuditLogStorageDir directive and make sure the direcory specified
|
||||
# exists and has write permissions for the Apache user.
|
||||
|
||||
SecAuditLogType Serial
|
||||
SecAuditLog logs/modsec_audit.log
|
||||
# SecAuditLogStorageDir logs/modsec_audit
|
||||
|
||||
# Select what portions of the request to log
|
||||
#
|
||||
# Modify the string by adding any of the letter below to it:
|
||||
# A - audit log header (mandatory)
|
||||
# B - request headers
|
||||
# C - request body (present only if the request body exists and ModSecurity is
|
||||
# configured to intercept it)
|
||||
# E - intermediary response body (present only if ModSecurity is configured to
|
||||
# intercept response bodies, and if the audit log engine is configured to
|
||||
# record it). Intermediary response body is the same as the actual response
|
||||
# body unless ModSecurity intercepts the intermediary response body, in
|
||||
# which case the actual response body will contain the error message
|
||||
# (either the Apache default error message, or the ErrorDocument page).
|
||||
# F - final response headers (excluding the Date and Server headers, which are
|
||||
# always added by Apache in the late stage of content delivery).
|
||||
# H - audit log trailer
|
||||
# I - This part is a replacement for part C. It will log the same data as C in
|
||||
# all cases except when multipart/form-data encoding in used. In this case
|
||||
# it will log a fake application/x-www-form-urlencoded body that contains
|
||||
# the information about parameters but not about the files. This is handy
|
||||
# if you don't want to have (often large) files stored in your audit logs.
|
||||
# Z - final boundary, signifies the end of the entry (mandatory)
|
||||
|
||||
SecAuditLogParts "ABIFHZ"
|
||||
|
||||
# Create a separate log to monitor performance.
|
||||
#
|
||||
# TODO Performance monitoring only works with Apache 2.x. You need
|
||||
# to add mod_unique_id and mod_logio to your configuration. Then
|
||||
# uncomment the following two lines.
|
||||
#
|
||||
# LogFormat "%V %h %t %{UNIQUE_ID}e \"%r\" %>s %X | %I %O | %<{mod_security-time1}n %<{mod_security-time2}n %<{mod_security-time3}n %D" mperformance
|
||||
# CustomLog logs/modsec_performance.log mperformance
|
||||
|
||||
# Custom application access log.
|
||||
#
|
||||
# TODO You should consider creating a custom access log. It could contain
|
||||
# the performance metrics from above, but should also record the
|
||||
# session ID for every request. That would make it possible to
|
||||
# list all requests performed as part of a session.
|
||||
#
|
||||
# One custom log should be used per application but if you want
|
||||
# multiple applications to share one log file make sure each
|
||||
# line includes a unique application ID (unless the hostname is
|
||||
# sufficient for differentiation).
|
||||
|
||||
## -- Tuning and debugging
|
||||
|
||||
# This section include tuning and debugging directives that usually require no
|
||||
# modifications unless
|
||||
|
||||
|
||||
# Parameters separator
|
||||
#
|
||||
# Specifies which character to use as separator for
|
||||
# application/x-www-form-urlencoded content.
|
||||
# Defaults to "&". Applications are sometimes (very rarely) written to use
|
||||
# a semicolon (";").
|
||||
#
|
||||
# NOTE Changing the value for this directive has significant influence on how
|
||||
# ModSecurity works. Make the change only if you are absolutely sure it
|
||||
# is required.
|
||||
SecArgumentSeparator "&"
|
||||
|
||||
|
||||
# Selects the cookie format that will be used in the current configuration
|
||||
# context.
|
||||
#
|
||||
# Possible values are:
|
||||
# 0 - use version 0 (Netscape) cookies. This is what most applications use.
|
||||
# It is the default value.
|
||||
# 1 - use version 1 cookies.
|
||||
|
||||
SecCookieFormat 0
|
||||
|
||||
# Maximum size of the request body to keep in memory
|
||||
#
|
||||
# A higher value requires more server memory while a lower number would slow
|
||||
# the server due to additional disk access. By default the limit is 128 KB:
|
||||
SecRequestBodyInMemoryLimit 131072
|
||||
|
||||
|
||||
# Whether to send ModSecurity messages to a separate debug log.
|
||||
#
|
||||
# Debug messages are very useful for, well, debugging. The default
|
||||
# setting here copies (they always appear in the Apache error log)
|
||||
# only the most important messages (errors and warnings).
|
||||
#
|
||||
# NOTE Debug logging is generally very slow. You should never
|
||||
# use values greater than "3" in production.
|
||||
#
|
||||
SecDebugLog logs/modsec_debug.log
|
||||
SecDebugLogLevel 3
|
||||
|
||||
# Path where persistent data (e.g. IP address data, session data, etc) is to
|
||||
# be stored. Must be writable by the web server user.
|
||||
#
|
||||
# TODO It is advisable to create a directory structure for ModSecurity such as
|
||||
# /var/log/msa and create sub directories for SecDataDir, SecTmpDir,
|
||||
# SecUploadDir, SecAuditLog and SecAuditLogStorageDir
|
||||
# underneath it and set the permission for read and write only by the
|
||||
# Apache user.
|
||||
|
||||
SecDataDir /tmp
|
||||
|
||||
# Configures the directory where temporary files will be created.
|
||||
SecTmpDir /tmp
|
||||
|
||||
# Loades the variable collection relating to the requested resource
|
||||
# NOTE: We will not initiate a collection if there was an error (To prevent overloading)
|
||||
SecRule RESPONSE_STATUS "!^(?:30[12]|[45]\d\d)$" "phase:3,pass,nolog,initcol:resource=%{REQUEST_FILENAME}"
|
||||
|
||||
@@ -1,74 +1,84 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:1,status:400"
|
||||
|
||||
# Accept only digits in content length
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^\d+$" "deny,log,auditlog,status:400,msg:'Content-Length HTTP header is not numeric', severity:'2',id:'960016'"
|
||||
|
||||
# Do not accept GET or HEAD requests with bodies
|
||||
# HTTP standard allows GET requests to have a body but this
|
||||
# feature is not used in real life. Attackers could try to force
|
||||
# a request body on an unsuspecting web applications.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^(GET|HEAD)$" "chain,deny,log,auditlog,status:400,msg:'GET or HEAD requests with bodies', severity:'2',id:'960011'"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0?$"
|
||||
|
||||
# Require Content-Length to be provided with every POST request.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^POST$" "chain,deny,log,auditlog,status:400,msg:'POST request must have a Content-Length header',id:'960012',severity:'4'"
|
||||
SecRule &REQUEST_HEADERS:Content-Length "@eq 0"
|
||||
|
||||
# Don't accept transfer encodings we know we don't know how to handle
|
||||
#
|
||||
# NOTE ModSecurity does not support chunked transfer encodings at
|
||||
# this time. You MUST reject all such requests.
|
||||
#
|
||||
SecRule HTTP_Transfer-Encoding "!^$" "deny,log,auditlog,status:501,msg:'ModSecurity does not support transfer encodings',id:'960013',severity:'5'"
|
||||
|
||||
# Check decodings
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "@validateUrlEncoding" \
|
||||
"chain, deny,log,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',id:'950107',severity:'4'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\%(?![0-9a-fA-F]{2}|u[0-9a-fA-F]{4})"
|
||||
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "@validateUtf8Encoding" "deny,log,auditlog,status:400,msg:'UTF8 Encoding Abuse Attack Attempt',id:'950801',severity:'4'"
|
||||
|
||||
# Proxy access attempt
|
||||
# NOTE Apache blocks such access by default if not set as a proxy. The rule is
|
||||
# included in case Apache proxy is misconfigured.
|
||||
SecRule REQUEST_URI ^http:/ "deny,log,auditlog,status:400,msg:'Proxy access attempt', severity:'2',id:'960014'"
|
||||
|
||||
#
|
||||
# Restrict type of characters sent
|
||||
#
|
||||
# NOTE In order to be broad and support localized applications this rule
|
||||
# only validates that NULL Is not used.
|
||||
#
|
||||
# The strict policy version also validates that protocol and application
|
||||
# generated fields are limited to printable ASCII.
|
||||
#
|
||||
# TODO If your application use the range 32-126 for parameters.
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
|
||||
"@validateByteRange 1-255" \
|
||||
"log,auditlog,msg:'Request Missing an Accept Header', severity:'2',id:'960015',t:urlDecodeUni,phase:1"
|
||||
|
||||
SecRule ARGS|ARGS_NAMES "@validateByteRange 1-255" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',id:'960901',severity:'4',t:urlDecodeUni,phase:2"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:2,status:400"
|
||||
|
||||
|
||||
# Validate request line
|
||||
SecRule REQUEST_LINE "!^[a-z]{3,10}\s*(?:http\:\/\/[\w\-\.\/]*)??\/[\w\-\.\/]*(?:\?[\S]*)??\s*http\/[01]\.[901]$" \
|
||||
"t:none,t:lowercase,deny,log,auditlog,status:400,msg:'Invalid HTTP Request Line',,id:'960911',severity:'2'"
|
||||
|
||||
|
||||
# Accept only digits in content length
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^\d+$" "deny,log,auditlog,status:400,msg:'Content-Length HTTP header is not numeric', severity:'2',,id:'960016',"
|
||||
|
||||
# Do not accept GET or HEAD requests with bodies
|
||||
# HTTP standard allows GET requests to have a body but this
|
||||
# feature is not used in real life. Attackers could try to force
|
||||
# a request body on an unsuspecting web applications.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^(GET|HEAD)$" "chain,deny,log,auditlog,status:400,msg:'GET or HEAD requests with bodies', severity:'2',,id:'960011',"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0?$"
|
||||
|
||||
# Require Content-Length to be provided with every POST request.
|
||||
#
|
||||
SecRule REQUEST_METHOD "^POST$" "chain,deny,log,auditlog,status:400,msg:'POST request must have a Content-Length header',,id:'960012',severity:'4'"
|
||||
SecRule &REQUEST_HEADERS:Content-Length "@eq 0"
|
||||
|
||||
# Don't accept transfer encodings we know we don't know how to handle
|
||||
#
|
||||
# NOTE ModSecurity does not support chunked transfer encodings at
|
||||
# this time. You MUST reject all such requests.
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Transfer-Encoding "!^$" "deny,log,auditlog,status:501,msg:'ModSecurity does not support transfer encodings',,id:'960013',severity:'3'"
|
||||
|
||||
# Check decodings
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "@validateUrlEncoding" \
|
||||
"chain, deny,log,auditlog,status:400,msg:'URL Encoding Abuse Attack Attempt',,id:'950107',severity:'4'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\%(?!$|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})"
|
||||
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "@validateUtf8Encoding" "deny,log,auditlog,status:400,msg:'UTF8 Encoding Abuse Attack Attempt',,id:'950801',severity:'4'"
|
||||
|
||||
# Disallow use of full-width unicode
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\%u[fF]{2}[0-9a-fA-F]{2}" \
|
||||
"t:none,deny,log,auditlog,status:400,msg:'Unicode Full/Half Width Abuse Attack Attempt',,id:'950116',severity:'4'"
|
||||
|
||||
# Proxy access attempt
|
||||
# NOTE Apache blocks such access by default if not set as a proxy. The rule is
|
||||
# included in case Apache proxy is misconfigured.
|
||||
SecRule REQUEST_URI_RAW ^http:/ "deny,log,auditlog,status:400,msg:'Proxy access attempt', severity:'2',,id:'960014',"
|
||||
|
||||
#
|
||||
# Restrict type of characters sent
|
||||
#
|
||||
# NOTE In order to be broad and support localized applications this rule
|
||||
# only validates that NULL Is not used.
|
||||
#
|
||||
# The strict policy version also validates that protocol and application
|
||||
# generated fields are limited to printable ASCII.
|
||||
#
|
||||
# TODO If your application use the range 32-126 for parameters.
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer \
|
||||
"@validateByteRange 1-255" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',,id:'960018',severity:'4',t:urlDecodeUni,phase:1"
|
||||
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS:Referer "@validateByteRange 1-255" \
|
||||
"deny,log,auditlog,status:400,msg:'Invalid character in request',,id:'960901',severity:'4',t:urlDecodeUni,phase:2"
|
||||
|
||||
@@ -1,50 +1,55 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:1,status:400"
|
||||
|
||||
# Do not accept requests without common headers.
|
||||
#
|
||||
# Implies either an attacker or a legitimate automation client.
|
||||
#
|
||||
SecRule REQUEST_URI "^/$" "chain,skip:4"
|
||||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^Apache.*\(internal dummy connection\)$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||||
"skip:1,log,auditlog,msg:'Request Missing a Host Header',id:'960008',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Host "^$" \
|
||||
"log,auditlog,msg:'Request Missing a Host Header',id:'960008',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
|
||||
"chain,skip:1,log,auditlog,msg:'Request Missing an Accept Header', severity:'2',id:'960015'"
|
||||
SecRule REQUEST_METHOD "!OPTIONS"
|
||||
SecRule REQUEST_HEADERS:Accept "^$" \
|
||||
"chain,log,auditlog,msg:'Request Missing an Accept Header', severity:'2',id:'960015'"
|
||||
SecRule REQUEST_METHOD "!OPTIONS"
|
||||
|
||||
SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \
|
||||
"skip:1,log,auditlog,msg:'Request Missing a User Agent Header',id:'960009',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^$" \
|
||||
"log,auditlog,msg:'Request Missing a User Agent Header',id:'960009',severity:'4'"
|
||||
|
||||
|
||||
# Check that the host header is not an IP address
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Host "^[\d\.]+$" "deny,log,auditlog,status:400,msg:'Host header is a numeric IP address', severity:'2',id:'960017'"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO in some cases a valid client (usually automated) generates requests that
|
||||
# violates the HTTP protocol. Create exceptions for those clients, but try
|
||||
# to limit the exception to a source IP or other additional properties of
|
||||
# the request such as URL and not allow the violation generally.
|
||||
#
|
||||
|
||||
# Use status code 400 response status code by default as protocol violations
|
||||
# are in essence bad requests.
|
||||
SecDefaultAction "log,pass,phase:2,status:400"
|
||||
|
||||
# Do not accept requests without common headers.
|
||||
#
|
||||
# Implies either an attacker or a legitimate automation client.
|
||||
#
|
||||
SecRule REQUEST_URI "^/$" "chain,skip:4"
|
||||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^Apache.*\(internal dummy connection\)$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||||
"skip:1,log,auditlog,msg:'Request Missing a Host Header',,id:'960008',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Host "^$" \
|
||||
"log,auditlog,msg:'Request Missing a Host Header',,id:'960008',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
|
||||
"chain,skip:1,log,auditlog,msg:'Request Missing an Accept Header', severity:'2',,id:'960015',"
|
||||
SecRule REQUEST_METHOD "!^OPTIONS$" "t:none"
|
||||
SecRule REQUEST_HEADERS:Accept "^$" \
|
||||
"chain,log,auditlog,msg:'Request Missing an Accept Header', severity:'2',,id:'960015',"
|
||||
SecRule REQUEST_METHOD "!^OPTIONS$" "t:none"
|
||||
|
||||
SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \
|
||||
"skip:1,log,auditlog,msg:'Request Missing a User Agent Header',,id:'960009',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "^$" \
|
||||
"log,auditlog,msg:'Request Missing a User Agent Header',,id:'960009',severity:'4'"
|
||||
|
||||
|
||||
SecRule &REQUEST_HEADERS:Content-Type "@eq 0" \
|
||||
"chain,log,auditlog,msg:'Request Containing Content, but Missing Content-Type header',,id:'960904',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Content-Length "!^0$"
|
||||
|
||||
|
||||
# Check that the host header is not an IP address
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Host "^[\d\.]+$" "deny,log,auditlog,status:400,msg:'Host header is a numeric IP address', severity:'2',,id:'960017',"
|
||||
|
||||
@@ -1,137 +1,152 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#%name 30 - HTTP policy enforcement
|
||||
#%desc The HTTP policy enforcement rule set sets limitations on the use of HTTP by clients.
|
||||
|
||||
# Few applications require the breadth and depth of the HTTP protocol. On the
|
||||
# other hand many attacks abuse valid but rare HTTP use patterns. Restricting
|
||||
# HTTP protocol usage is effective in therefore effective in blocking many
|
||||
# application layer attacks.
|
||||
#
|
||||
# TODO If you are using the ModSecurity Core Ruleset template system you can set
|
||||
# the policy limitations in the ruleset.config file. Otherwise edit this
|
||||
# file manually to set you policy limitations.
|
||||
#
|
||||
# TODO Many automation programs use non standard HTTP requests. While you may
|
||||
# want to allow some of those, try not to create exceptions only for the
|
||||
# automated program based on properties such as their source IP address or
|
||||
# the URL they access.
|
||||
#
|
||||
|
||||
SecDefaultAction "pass,log,status:400,phase:1"
|
||||
|
||||
# allow request methods
|
||||
#
|
||||
# TODO Most applications only use GET, HEAD, and POST request
|
||||
# methods, if so uncomment the line below. Otherwise you are advised
|
||||
# to edit the line before uncommenting it.
|
||||
#
|
||||
SecRule REQUEST_METHOD "!^((?:(?:POS|GE)T|OPTIONS|HEAD))$" \
|
||||
"phase:1,log,auditlog,status:501,msg:'Method is not allowed by policy', severity:'2',id:'960032'"
|
||||
|
||||
|
||||
# Restrict witch content encodings we accept.
|
||||
#
|
||||
# TODO Most applications support only two encodings for request bodies
|
||||
# because that is all browsers know how to produce. If you are using
|
||||
# automated tools to talk to the application you may be using other
|
||||
# content types and would want to change the list of supported encodings.
|
||||
#
|
||||
# Note though that ModSecurity parses only three content encodings:
|
||||
# application/x-www-form-urlencoded, multipart/form-data request and
|
||||
# text/xml. The protection provided for any other type of encoding is
|
||||
# inferior.
|
||||
#
|
||||
# TODO There are many applications that are not using multipart/form-data
|
||||
# encoding (typically only used for file uploads). This content type
|
||||
# can be disabled if not used.
|
||||
#
|
||||
# NOTE We allow any content type to be specified with GET or HEAD
|
||||
# because some tools incorrectly supply content type information
|
||||
# even when the body is not present. There is a rule further in
|
||||
# the file to prevent GET and HEAD requests to have bodies to we're
|
||||
# safe in that respect.
|
||||
#
|
||||
# NOTE Use of WebDAV requires "text/xml" content type.
|
||||
#
|
||||
# NOTE Philippe Bourcier (pbourcier AT citali DOT com) reports
|
||||
# applications running on the PocketPC and AvantGo platforms use
|
||||
# non-standard content types:
|
||||
#
|
||||
# M-Business iAnywhere application/x-mal-client-data
|
||||
# UltraLite iAnywhere application/octet-stream
|
||||
#
|
||||
SecRule REQUEST_METHOD "!^(?:get|head|propfind|options)$" \
|
||||
"chain, t:lowercase, deny,log,auditlog,status:501,msg:'Request content encoding is not allowed by policy',id:'960010',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Content-Type "!(?:^(?:application/x-www-form-urlencoded$|multipart/form-data;)|text/xml)"
|
||||
|
||||
# Restrict protocol versions.
|
||||
#
|
||||
# TODO All modern browsers use HTTP version 1.1. For tight security, allow only
|
||||
# this version.
|
||||
#
|
||||
# NOTE Automation programs, both malicious and non malicious many times use
|
||||
# other HTTP versions. If you want to allow a specific automated program
|
||||
# to use your site, try to create a narrower expection and not allow any
|
||||
# client to send HTTP requests in a version lower than 1.1
|
||||
#
|
||||
SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.[01])$" \
|
||||
"t:none, deny,log,auditlog,status:505,msg:'HTTP protocol version is not allowed by policy', severity:'2',id:'960034'"
|
||||
|
||||
# Restrict file extension
|
||||
#
|
||||
# TODO the list of file extensions below are virtually always considered unsafe
|
||||
# and not in use in any valid program. If your application uses one of
|
||||
# these extensions, please remove it from the list of blocked extensions.
|
||||
# You may need to use ModSecurity Core Rule Set Templates to do so, otherwise
|
||||
# comment the whole rule.
|
||||
#
|
||||
SecRule REQUEST_BASENAME "\.(?:c(?:o(?:nf(?:ig)?|m)|s(?:proj|r)?|dx|er|fg|md)|p(?:rinter|ass|db|ol|wd)|v(?:b(?:proj|s)?|sdisco)|a(?:s(?:ax?|cx)|xd)|s(?:html?|ql|tm|ys)|d(?:bf?|at|ll|os)|i(?:d[acq]|n[ci])|ba(?:[kt]|ckup)|res(?:ources|x)|l(?:icx|nk|og)|\w{,5}~|webinfo|ht[rw]|xs[dx]|exe|key|mdb|old)$" \
|
||||
"t:urlDecodeUni, t:lowercase, deny,log,auditlog,status:500,msg:'URL file extension is restricted by policy', severity:'2',id:'960035'"
|
||||
|
||||
|
||||
|
||||
# Restricted HTTP headers
|
||||
#
|
||||
# TODO the list of HTTP headers below are considered unsafe for your environment.
|
||||
# If your application uses one of these directories, please remove it from
|
||||
# the list of blocked extensions. You may need to use ModSecurity Core Rule
|
||||
# Set Templates to do so, otherwise comment the whole rule.
|
||||
#
|
||||
SecRule REQUEST_HEADERS_NAMES "\.(?:Lock-Token|Translate|If)$" \
|
||||
"deny,log,auditlog,status:500,msg:'HTTP header is restricted by policy',id:'960038',severity:'4'"
|
||||
|
||||
|
||||
## -- Apache Limits ----------------------------------------------------------
|
||||
|
||||
# These are Apache limit directives, but we are including them here because
|
||||
# they are often forgotten. If you already have these configured leave this
|
||||
# section entirely commented-out. Otherwise review the limits and uncomment
|
||||
# the directives.
|
||||
|
||||
# Maximum size of the request body.
|
||||
#
|
||||
# NOTE If your application allows file uploads the value below will
|
||||
# most likely be way to low.
|
||||
#
|
||||
#LimitRequestBody 64000
|
||||
|
||||
# Maximum number of request headers in a request.
|
||||
#
|
||||
#LimitRequestFields 32
|
||||
|
||||
# Maximum size of request header lines.
|
||||
#
|
||||
#LimitRequestFieldSize 8000
|
||||
|
||||
# Maximum size of the request line.
|
||||
#
|
||||
#LimitRequestLine 4000
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#%name 30 - HTTP policy enforcement
|
||||
#%desc The HTTP policy enforcement rule set sets limitations on the use of HTTP by clients.
|
||||
|
||||
# Few applications require the breadth and depth of the HTTP protocol. On the
|
||||
# other hand many attacks abuse valid but rare HTTP use patterns. Restricting
|
||||
# HTTP protocol usage is effective in therefore effective in blocking many
|
||||
# application layer attacks.
|
||||
#
|
||||
# TODO If you are using the ModSecurity Core Ruleset template system you can set
|
||||
# the policy limitations in the ruleset.config file. Otherwise edit this
|
||||
# file manually to set you policy limitations.
|
||||
#
|
||||
# TODO Many automation programs use non standard HTTP requests. While you may
|
||||
# want to allow some of those, try not to create exceptions only for the
|
||||
# automated program based on properties such as their source IP address or
|
||||
# the URL they access.
|
||||
#
|
||||
|
||||
SecDefaultAction "pass,log,status:400,phase:2"
|
||||
|
||||
# allow request methods
|
||||
#
|
||||
# TODO Most applications only use GET, HEAD, and POST request
|
||||
# methods, if so uncomment the line below. Otherwise you are advised
|
||||
# to edit the line before uncommenting it.
|
||||
#
|
||||
SecRule REQUEST_METHOD "!^((?:(?:POS|GE)T|OPTIONS|HEAD))$" \
|
||||
"phase:1,log,auditlog,status:501,msg:'Method is not allowed by policy', severity:'2',,id:'960032',"
|
||||
|
||||
|
||||
# Restrict which content-types we accept.
|
||||
#
|
||||
# TODO Most applications support only two types for request bodies
|
||||
# because that is all browsers know how to produce. If you are using
|
||||
# automated tools to talk to the application you may be using other
|
||||
# content types and would want to change the list of supported types.
|
||||
#
|
||||
# Note though that ModSecurity parses only three content types:
|
||||
# application/x-www-form-urlencoded, multipart/form-data request and
|
||||
# text/xml. The protection provided for any other type is inferior.
|
||||
#
|
||||
# TODO There are many applications that are not using multipart/form-data
|
||||
# types (typically only used for file uploads). This content type
|
||||
# can be disabled if not used.
|
||||
#
|
||||
# NOTE We allow any content type to be specified with GET or HEAD
|
||||
# because some tools incorrectly supply content type information
|
||||
# even when the body is not present. There is a rule further in
|
||||
# the file to prevent GET and HEAD requests to have bodies to we're
|
||||
# safe in that respect.
|
||||
#
|
||||
# NOTE Use of WebDAV requires "text/xml" content type.
|
||||
#
|
||||
# NOTE Philippe Bourcier (pbourcier AT citali DOT com) reports
|
||||
# applications running on the PocketPC and AvantGo platforms use
|
||||
# non-standard content types:
|
||||
#
|
||||
# M-Business iAnywhere application/x-mal-client-data
|
||||
# UltraLite iAnywhere application/octet-stream
|
||||
#
|
||||
SecRule REQUEST_METHOD "!^(?:get|head|propfind|options)$" \
|
||||
"chain, t:lowercase, deny,log,auditlog,status:501,msg:'Request content type is not allowed by policy',,id:'960010',severity:'4'"
|
||||
SecRule REQUEST_HEADERS:Content-Type "!(?:^(?:application\/x-www-form-urlencoded(?:;(?:\s?charset\s?=\s?[\w\d\-]{1,18})?)??$|multipart/form-data;)|text/xml)"
|
||||
|
||||
# Restrict protocol versions.
|
||||
#
|
||||
# TODO All modern browsers use HTTP version 1.1. For tight security, allow only
|
||||
# this version.
|
||||
#
|
||||
# NOTE Automation programs, both malicious and non malicious many times use
|
||||
# other HTTP versions. If you want to allow a specific automated program
|
||||
# to use your site, try to create a narrower expection and not allow any
|
||||
# client to send HTTP requests in a version lower than 1.1
|
||||
#
|
||||
SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.[01])$" \
|
||||
"t:none, deny,log,auditlog,status:505,msg:'HTTP protocol version is not allowed by policy', severity:'2',,id:'960034',"
|
||||
|
||||
# Restrict file extension
|
||||
#
|
||||
# TODO the list of file extensions below are virtually always considered unsafe
|
||||
# and not in use in any valid program. If your application uses one of
|
||||
# these extensions, please remove it from the list of blocked extensions.
|
||||
# You may need to use ModSecurity Core Rule Set Templates to do so, otherwise
|
||||
# comment the whole rule.
|
||||
#
|
||||
SecRule REQUEST_BASENAME "\.(?:c(?:o(?:nf(?:ig)?|m)|s(?:proj|r)?|dx|er|fg|md)|p(?:rinter|ass|db|ol|wd)|v(?:b(?:proj|s)?|sdisco)|a(?:s(?:ax?|cx)|xd)|d(?:bf?|at|ll|os)|i(?:d[acq]|n[ci])|ba(?:[kt]|ckup)|res(?:ources|x)|s(?:h?tm|ql|ys)|l(?:icx|nk|og)|\w{,5}~|webinfo|ht[rw]|xs[dx]|key|mdb|old)$" \
|
||||
"t:urlDecodeUni, t:lowercase, deny,log,auditlog,status:500,msg:'URL file extension is restricted by policy', severity:'2',,id:'960035',"
|
||||
|
||||
|
||||
|
||||
# Restricted HTTP headers
|
||||
#
|
||||
# TODO the list of HTTP headers below are considered unsafe for your environment.
|
||||
# If your application uses one of these directories, please remove it from
|
||||
# the list of blocked extensions. You may need to use ModSecurity Core Rule
|
||||
# Set Templates to do so, otherwise comment the whole rule.
|
||||
#
|
||||
SecRule REQUEST_HEADERS_NAMES "\.(?:Lock-Token|Translate|If)$" \
|
||||
"deny,log,auditlog,status:500,msg:'HTTP header is restricted by policy',,id:'960038',severity:'4'"
|
||||
|
||||
|
||||
# Restricted Content Encodings
|
||||
#
|
||||
# ModSecurity does not support compressed content. Therefore, the following
|
||||
# action will be taken:
|
||||
# - Inbound compressed content will be denied
|
||||
# - Outbound compressed content will be logged once, to alert the user
|
||||
# Deny inbound compressed content
|
||||
SecRule REQUEST_HEADERS:Content-Encoding "!^Identity$" \
|
||||
"phase:2,t:none,deny,log,auditlog,status:501,msg:'ModSecurity does not support content encodings',,id:'960902',severity:'3'"
|
||||
# Log outbound compressed content (once per location)
|
||||
SecRule RESPONSE_HEADERS:Content-Encoding "!^Identity$" \
|
||||
"phase:5,t:none,pass,log,auditlog,msg:'ModSecurity does not support content encodings',,id:'960903',severity:'4',chain"
|
||||
SecRule &RESOURCE:alerted_960903_compression "@eq 0" "setvar:resource.alerted_960903_compression"
|
||||
|
||||
|
||||
|
||||
## -- Apache Limits ----------------------------------------------------------
|
||||
|
||||
# These are Apache limit directives, but we are including them here because
|
||||
# they are often forgotten. If you already have these configured leave this
|
||||
# section entirely commented-out. Otherwise review the limits and uncomment
|
||||
# the directives.
|
||||
|
||||
# Maximum size of the request body.
|
||||
#
|
||||
# NOTE If your application allows file uploads the value below will
|
||||
# most likely be way to low.
|
||||
#
|
||||
#LimitRequestBody 64000
|
||||
|
||||
# Maximum number of request headers in a request.
|
||||
#
|
||||
#LimitRequestFields 32
|
||||
|
||||
# Maximum size of request header lines.
|
||||
#
|
||||
#LimitRequestFieldSize 8000
|
||||
|
||||
# Maximum size of the request line.
|
||||
#
|
||||
#LimitRequestLine 4000
|
||||
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# NOTE Bad robots detection is based on checking elements easily
|
||||
# controlled by the client. As such a determined attacked can bypass
|
||||
# those checks. Therefore bad robots detection should not be viewed as
|
||||
# a security mechanism against targeted attacks but rather as a nuisance
|
||||
# reduction, eliminating most of the random attacks against your web
|
||||
# site.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase"
|
||||
|
||||
SecRule HTTP_User-Agent "(?:\b(?:m(?:ozilla\/4\.0 \(compatible\)|etis)|webtrends security analyzer|pmafind)\b|n(?:-stealth|sauditor|essus|ikto)|b(?:lack ?widow|rutus|ilbo)|(?:jaascoi|paro)s|internet explorer|webinspect|\.nasl)" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',id:'990002',severity:'2'"
|
||||
SecRule REQUEST_HEADERS_NAMES "\bacunetix-product\b" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',id:'990901',severity:'2'"
|
||||
SecRule REQUEST_FILENAME "^/nessustest" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',id:'990902',severity:'2'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:m(?:ozilla\/(?:4\.0 \(compatible; advanced email extractor|2\.0 \(compatible; newt activex; win32\))|ailto:craftbot\@yahoo\.com)|e(?:mail(?:(?:collec|harves|magne)t|(?: extracto|reape)r|siphon|wolf)|(?:collecto|irgrabbe)r|xtractorpro|o browse)|a(?:t(?:tache|hens)|utoemailspider|dsarobot)|w(?:eb(?:emailextrac| by mail)|3mir)|f(?:astlwspider|loodgate)|p(?:cbrowser|ackrat|surf)|(?:digout4uagen|takeou)t|(?:chinacla|be)w|hhjhj@yahoo|rsync|shai|zeus)" \
|
||||
"deny,log,auditlog,status:404,msg:'Rogue web site crawler',id:'990012',severity:'2'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:\b(?:(?:indy librar|snoop)y|microsoft url control|lynx)\b|d(?:ownload demon|isco)|w(?:3mirror|get)|l(?:ibwww|wp)|p(?:avuk|erl)|cu(?:sto|rl)|big brother|autohttp|netants|eCatch)" \
|
||||
"chain,log,auditlog,msg:'Request Indicates an automated program explored the site',id:'990011',severity:'5'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "!^apache.*perl"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# NOTE Bad robots detection is based on checking elements easily
|
||||
# controlled by the client. As such a determined attacked can bypass
|
||||
# those checks. Therefore bad robots detection should not be viewed as
|
||||
# a security mechanism against targeted attacks but rather as a nuisance
|
||||
# reduction, eliminating most of the random attacks against your web
|
||||
# site.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:\b(?:m(?:ozilla\/4\.0 \(compatible\)|etis)|webtrends security analyzer|pmafind)\b|n(?:-stealth|sauditor|essus|ikto)|b(?:lack ?widow|rutus|ilbo)|(?:jaascoi|paro)s|internet explorer|webinspect|\.nasl)" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',,id:'990002',severity:'2'"
|
||||
SecRule REQUEST_HEADERS_NAMES "\bacunetix-product\b" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',,id:'990901',severity:'2'"
|
||||
SecRule REQUEST_FILENAME "^/nessustest" \
|
||||
"deny,log,auditlog,status:404,msg:'Request Indicates a Security Scanner Scanned the Site',,id:'990902',severity:'2'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:m(?:ozilla\/(?:4\.0 \(compatible; advanced email extractor|2\.0 \(compatible; newt activex; win32\))|ailto:craftbot\@yahoo\.com)|e(?:mail(?:(?:collec|harves|magne)t|(?: extracto|reape)r|siphon|wolf)|(?:collecto|irgrabbe)r|xtractorpro|o browse)|a(?:t(?:tache|hens)|utoemailspider|dsarobot)|w(?:eb(?:emailextrac| by mail)|3mir)|f(?:astlwspider|loodgate)|p(?:cbrowser|ackrat|surf)|(?:digout4uagen|takeou)t|(?:chinacla|be)w|hhjhj@yahoo|rsync|shai|zeus)" \
|
||||
"deny,log,auditlog,status:404,msg:'Rogue web site crawler',,id:'990012',severity:'2'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:\b(?:(?:indy librar|snoop)y|microsoft url control|lynx)\b|d(?:ownload demon|isco)|w(?:3mirror|get)|l(?:ibwww|wp)|p(?:avuk|erl)|cu(?:sto|rl)|big brother|autohttp|netants|eCatch)" \
|
||||
"chain,log,auditlog,msg:'Request Indicates an automated program explored the site',,id:'990011',severity:'5'"
|
||||
SecRule REQUEST_HEADERS:User-Agent "!^apache.*perl"
|
||||
|
||||
|
||||
@@ -1,83 +1,94 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO While some of the pattern groups such as command injection are usually
|
||||
# safe of false positives, other pattern groups such as SQL injection and
|
||||
# XSS may require setting exceptions and therefore are set to log only by
|
||||
# default.
|
||||
#
|
||||
# Start ModSecurity in monitoring only mode and check whether your
|
||||
# application requires exceptions for a specific URL, Pattern or source IP
|
||||
# before moving to blocking mode.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,status:500,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
|
||||
|
||||
# Session fixation
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\.cookie\b.*?;\W*?(?:expires|domain)\W*?=|\bhttp-equiv\W+set-cookie\b)" \
|
||||
"capture,ctl:auditLogParts=+E,log,auditlog,msg:'Session Fixation. Matched signature <%{TX.0}>',id:'950009',severity:'2'"
|
||||
|
||||
# Blind SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:ys\.(?:user_(?:(?:t(?:ab(?:_column|le)|rigger)|object|view)s|c(?:onstraints|atalog))|all_tables|tab)|elect\b.{0,40}\b(?:substring|ascii|user))|m(?:sys(?:(?:queri|ac)e|relationship|column|object)s|ysql.user)|c(?:onstraint_type|harindex)|attnotnull)\b|(?:locate|instr)\W+\()|\@\@spid\b)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950007',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:benchmark|encode)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950903',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:(?:s(?:ys(?:(?:(?:process|tabl)e|filegroup|object)s|c(?:o(?:nstraint|lumn)s|at)|dba|ibm)|ubstr(?:ing)?)|user_(?:(?:(?:constrain|objec)t|tab(?:_column|le)|ind_column|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|(?:dba|mb)_users|xtype\W+\bchar|rownum)\b|t(?:able_name\b|extpos\W+\())" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',id:'950904',severity:'2'"
|
||||
|
||||
# SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:elect\b(?:.{1,100}?\b(?:(?:length|count|top)\b.{1,100}?\bfrom|from\b.{1,100}?\bwhere)|.*?\b(?:d(?:ump\b.*\bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebtask)|ql_(?:longvarchar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|e(?:xecresultset|numdsn)|(?:terminat|dirtre)e|availablemedia|loginconfig|cmdshell|filelist|makecab|ntsec)|u(?:nion\b.{1,100}?\bselect|tl_(?:file|http))|group\b.*\bby\b.{1,100}?\bhaving|load\b\W*?\bdata\b.*\binfile|(?:n?varcha|tbcreato)r|autonomous_transaction|open(?:rowset|query)|dbms_java)\b|i(?:n(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)\b|(?:f(?:\b\W*?\(\W*?\bbenchmark|null\b)|snull\b)\W*?\()|(?:having|or|and)\b\s+?(?:\d{1,10}|'[^=]{1,10}')\s*?[=<>]+|(?:print\]\b\W*?\@|root)\@|c(?:ast\b\W*?\(|oalesce\b))|(?:;\W*?\b(?:shutdown|drop)|\@\@version)\b|'(?:s(?:qloledb|a)|msdasql|dbo)')" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950001',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:rel(?:(?:nam|typ)e|kind)|a(?:ttn(?:ame|um)|scii)|c(?:o(?:nver|un)t|ha?r)|s(?:hutdown|elect)|to_(?:numbe|cha)r|u(?:pdate|nion)|d(?:elete|rop)|group\b\W*\bby|having|insert|length|where)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950905',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "\b(?:user_(?:(?:object|table|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|substr(?:ing)?|table_name|mb_users|rownum)\b" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',id:'950906',severity:'2'"
|
||||
|
||||
# XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:on(?:(?:mo(?:use(?:o(?:ver|ut)|down|move|up)|ve)|key(?:press|down|up)|c(?:hange|lick)|s(?:elec|ubmi)t|(?:un)?load|dragdrop|resize|focus|blur)\b\W*?=|abort\b)|(?:l(?:owsrc\b\W*?\b(?:(?:java|vb)script|shell)|ivescript)|(?:href|url)\b\W*?\b(?:(?:java|vb)script|shell)|background-image|mocha):|type\b\W*?\b(?:text\b(?:\W*?\b(?:j(?:ava)?|ecma)script\b| [vbscript])|application\b\W*?\bx-(?:java|vb)script\b)|s(?:(?:tyle\b\W*=.*\bexpression\b\W*|ettimeout\b\W*?)\(|rc\b\W*?\b(?:(?:java|vb)script|shell|http):)|(?:c(?:opyparentfolder|reatetextrange)|get(?:special|parent)folder)\b|a(?:ctivexobject\b|lert\b\W*?\())|<(?:(?:body\b.*?\b(?:backgroun|onloa)d|input\b.*?\\btype\b\W*?\bimage)\b|!\[CDATA\[|script|meta)|(?:\.(?:(?:execscrip|addimpor)t|(?:fromcharcod|cooki)e|innerhtml)|\@import)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,log,auditlog,msg:'Cross-site Scripting (XSS) Attack. Matched signature <%{TX.0}>',id:'950004',severity:'2'"
|
||||
|
||||
# file injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:\.(?:ht(?:access|passwd|group)|www_?acl)|global\.asa|httpd\.conf|boot\.ini)\b|\/etc\/)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Remote File Access Attempt. Matched signature <%{TX.0}>',id:'950005',severity:'2'"
|
||||
|
||||
# Command access
|
||||
SecRule REQUEST_FILENAME "\b(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Access. Matched signature <%{TX.0}>',id:'950002',severity:'2'"
|
||||
|
||||
# Command injection
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:\b(?:(?:n(?:et(?:\b\W+?\blocalgroup|\.exe)|(?:map|c)\.exe)|t(?:racer(?:oute|t)|elnet\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\.exe|echo\b\W*?\by+)\b|c(?:md(?:(?:32)?\.exe\b|\b\W*?\/c)|d(?:\b\W*?[\\\/]|\W*?\.\.)|hmod.{0,40}?\+.{0,3}x))|[\;\|\`]\W*?\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\b|g(?:\+\+|cc\b))|\/(?:c(?:h(?:grp|mod|own|sh)|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|g(?:\+\+|cc)|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)(?:[\'\"\|\;\`\-\s]|$))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',id:'950006',severity:'2'"
|
||||
SecRule "ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent" \
|
||||
"\bwget\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',id:'950907',severity:'2'"
|
||||
|
||||
# Coldfusion injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "\bcf(?:usion_(?:d(?:bconnections_flush|ecrypt)|set(?:tings_refresh|odbcini)|getodbc(?:dsn|ini)|verifymail|encrypt)|_(?:(?:iscoldfusiondatasourc|getdatasourceusernam)e|setdatasource(?:password|username))|newinternal(?:adminsecurit|registr)y|admin_registry_(?:delete|set)|internaldebug)\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Injection of Undocumented ColdFusion Tags. Matched signature <%{TX.0}>',id:'950008',severity:'2'"
|
||||
|
||||
# LDAP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|!REQUEST_HEADERS:Referer "(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|])" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'LDAP Injection Attack. Matched signature <%{TX.0}>',id:'950010',severity:'2'"
|
||||
|
||||
# SSI injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "<!--\W*?#\W*?(?:e(?:cho|xec)|printenv|include|cmd)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SSI injection Attack. Matched signature <%{TX.0}>',id:'950011',severity:'2'"
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "(?:(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b|<\?(?!xml))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'PHP Injection Attack. Matched signature <%{TX.0}>',id:'950013',severity:'2'"
|
||||
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS "http:\/\/[\w\.]+?\/.*?\.pdf\b[^\x0d\x0a]*#" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Persistent Universal PDF XSS attack',id:'950018',severity:'2'"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# TODO While some of the pattern groups such as command injection are usually
|
||||
# safe of false positives, other pattern groups such as SQL injection and
|
||||
# XSS may require setting exceptions and therefore are set to log only by
|
||||
# default.
|
||||
#
|
||||
# Start ModSecurity in monitoring only mode and check whether your
|
||||
# application requires exceptions for a specific URL, Pattern or source IP
|
||||
# before moving to blocking mode.
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,status:500,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"
|
||||
|
||||
# Session fixation
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "(?:\.cookie\b.*?;\W*?(?:expires|domain)\W*?=|\bhttp-equiv\W+set-cookie\b)" \
|
||||
"capture,ctl:auditLogParts=+E,log,auditlog,msg:'Session Fixation. Matched signature <%{TX.0}>',,id:'950009',severity:'2'"
|
||||
|
||||
# Blind SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:ys\.(?:user_(?:(?:t(?:ab(?:_column|le)|rigger)|object|view)s|c(?:onstraints|atalog))|all_tables|tab)|elect\b.{0,40}\b(?:substring|ascii|user))|m(?:sys(?:(?:queri|ac)e|relationship|column|object)s|ysql.user)|c(?:onstraint_type|harindex)|attnotnull)\b|(?:locate|instr)\W+\()|\@\@spid\b)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950007',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\b(?:benchmark|encode)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950903',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\b(?:(?:s(?:ys(?:(?:(?:process|tabl)e|filegroup|object)s|c(?:o(?:nstraint|lumn)s|at)|dba|ibm)|ubstr(?:ing)?)|user_(?:(?:(?:constrain|objec)t|tab(?:_column|le)|ind_column|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|(?:dba|mb)_users|xtype\W+\bchar|rownum)\b|t(?:able_name\b|extpos\W+\())" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'Blind SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950904',severity:'2'"
|
||||
|
||||
# SQL injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "(?:\b(?:(?:s(?:elect\b(?:.{1,100}?\b(?:(?:length|count|top)\b.{1,100}?\bfrom|from\b.{1,100}?\bwhere)|.*?\b(?:d(?:ump\b.*\bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebtask)|ql_(?:longvarchar|variant))|xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|e(?:xecresultset|numdsn)|(?:terminat|dirtre)e|availablemedia|loginconfig|cmdshell|filelist|makecab|ntsec)|u(?:nion\b.{1,100}?\bselect|tl_(?:file|http))|group\b.*\bby\b.{1,100}?\bhaving|load\b\W*?\bdata\b.*\binfile|(?:n?varcha|tbcreato)r|autonomous_transaction|open(?:rowset|query)|1\s*=\s*1|dbms_java)\b|i(?:n(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)\b|(?:f(?:\b\W*?\(\W*?\bbenchmark|null\b)|snull\b)\W*?\()|(?:having|or|and)\b\s+(?:\d{1,10}|[\'\"][^=]{1,10}[\'\"])\s*[=<>]+|print\]\b\W*?\@\@|cast\b\W*?\()|(?:;\W*?\b(?:shutdown|drop)|\@\@version)\b|'(?:s(?:qloledb|a)|msdasql|dbo)')" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950001',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\b(?:rel(?:(?:nam|typ)e|kind)|a(?:ttn(?:ame|um)|scii)|c(?:o(?:nver|un)t|ha?r)|s(?:hutdown|elect)|to_(?:numbe|cha)r|u(?:pdate|nion)|d(?:elete|rop)|group\b\W*\bby|having|insert|length|where)\b" \
|
||||
# "chain,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950905',severity:'2'"
|
||||
#SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "[\\(\)\%#]\|--"
|
||||
SecRule REQUEST_FILENAME|ARGS|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "\b(?:user_(?:(?:object|table|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|substr(?:ing)?|table_name|mb_users|rownum)\b" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950906',severity:'2'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:via "\b(?:coalesce\b|root\@)" \
|
||||
"capture,t:replaceComments,ctl:auditLogParts=+E,log,auditlog,msg:'SQL Injection Attack. Matched signature <%{TX.0}>',,id:'950908',severity:'2'"
|
||||
|
||||
# XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "(?:\b(?:on(?:(?:mo(?:use(?:o(?:ver|ut)|down|move|up)|ve)|key(?:press|down|up)|c(?:hange|lick)|s(?:elec|ubmi)t|(?:un)?load|dragdrop|resize|focus|blur)\b\W*?=|abort\b)|(?:l(?:owsrc\b\W*?\b(?:(?:java|vb)script|shell)|ivescript)|(?:href|url)\b\W*?\b(?:(?:java|vb)script|shell)|background-image|mocha):|type\b\W*?\b(?:text\b(?:\W*?\b(?:j(?:ava)?|ecma)script\b| [vbscript])|application\b\W*?\bx-(?:java|vb)script\b)|s(?:(?:tyle\b\W*=.*\bexpression\b\W*|ettimeout\b\W*?)\(|rc\b\W*?\b(?:(?:java|vb)script|shell|http):)|(?:c(?:opyparentfolder|reatetextrange)|get(?:special|parent)folder)\b|a(?:ctivexobject\b|lert\b\W*?\())|<(?:(?:body\b.*?\b(?:backgroun|onloa)d|input\b.*?\\btype\b\W*?\bimage)\b|!\[CDATA\[|script|meta)|(?:\.(?:(?:execscrip|addimpor)t|(?:fromcharcod|cooki)e|innerhtml)|\@import)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,log,auditlog,msg:'Cross-site Scripting (XSS) Attack. Matched signature <%{TX.0}>',,id:'950004',severity:'2'"
|
||||
|
||||
# file injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "(?:\b(?:\.(?:ht(?:access|passwd|group)|www_?acl)|global\.asa|httpd\.conf|boot\.ini)\b|\/etc\/)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Remote File Access Attempt. Matched signature <%{TX.0}>',,id:'950005',severity:'2'"
|
||||
|
||||
# Command access
|
||||
SecRule REQUEST_FILENAME "\b(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Access. Matched signature <%{TX.0}>',,id:'950002',severity:'2'"
|
||||
|
||||
# Command injection
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:'/(Cookie|Referer|X-OS-Prefs)/'|REQUEST_COOKIES|REQUEST_COOKIES_NAMES "(?:\b(?:(?:n(?:et(?:\b\W+?\blocalgroup|\.exe)|(?:map|c)\.exe)|t(?:racer(?:oute|t)|elnet\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\.exe|echo\b\W*?\by+)\b|c(?:md(?:(?:32)?\.exe\b|\b\W*?\/c)|d(?:\b\W*?[\\\/]|\W*?\.\.)|hmod.{0,40}?\+.{0,3}x))|[\;\|\`]\W*?\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\b|g(?:\+\+|cc\b))|\/(?:c(?:h(?:grp|mod|own|sh)|pp|c)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|g(?:\+\+|cc)|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)(?:[\'\"\|\;\`\-\s]|$))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',,id:'950006',severity:'2'"
|
||||
SecRule "ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:User-Agent" \
|
||||
"\bwget\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'System Command Injection. Matched signature <%{TX.0}>',,id:'950907',severity:'2'"
|
||||
|
||||
# Coldfusion injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "\bcf(?:usion_(?:d(?:bconnections_flush|ecrypt)|set(?:tings_refresh|odbcini)|getodbc(?:dsn|ini)|verifymail|encrypt)|_(?:(?:iscoldfusiondatasourc|getdatasourceusernam)e|setdatasource(?:password|username))|newinternal(?:adminsecurit|registr)y|admin_registry_(?:delete|set)|internaldebug)\b" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Injection of Undocumented ColdFusion Tags. Matched signature <%{TX.0}>',,id:'950008',severity:'2'"
|
||||
|
||||
# LDAP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/*|!REQUEST_HEADERS:Referer "(?:\((?:\W*?(?:objectc(?:ategory|lass)|homedirectory|[gu]idnumber|cn)\b\W*?=|[^\w\x80-\xFF]*?[\!\&\|][^\w\x80-\xFF]*?\()|\)[^\w\x80-\xFF]*?\([^\w\x80-\xFF]*?[\!\&\|])" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'LDAP Injection Attack. Matched signature <%{TX.0}>',,id:'950010',severity:'2'"
|
||||
|
||||
# SSI injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "<!--\W*?#\W*?(?:e(?:cho|xec)|printenv|include|cmd)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'SSI injection Attack. Matched signature <%{TX.0}>',,id:'950011',severity:'2'"
|
||||
|
||||
# PHP injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "(?:(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b|<\?(?!xml))" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'PHP Injection Attack. Matched signature <%{TX.0}>',,id:'950013',severity:'2'"
|
||||
|
||||
# HTTP Response Splitting
|
||||
SecRule REQUEST_URI|REQUEST_HEADERS|REQUEST_HEADERS_NAMES "%0[ad]" \
|
||||
"t:none,t:lowercase,capture,ctl:auditLogParts=+E,deny,log,auditlog,status:400,msg:'HTTP Response Splitting Attack. Matched signature <%{TX.0}>',,id:'950910',severity:'1'"
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "(?:\bhttp.(?:0\.9|1\.[01])|<(?:html|meta)\b)" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:400,msg:'HTTP Response Splitting Attack. Matched signature <%{TX.0}>',,id:'950911',severity:'1'"
|
||||
|
||||
# UPDF XSS
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "http:\/\/[\w\.]+?\/.*?\.pdf\b[^\x0d\x0a]*#" \
|
||||
"capture,ctl:auditLogParts=+E,deny,log,auditlog,status:501,msg:'Persistent Universal PDF XSS attack',,id:'950018',severity:'2'"
|
||||
|
||||
# Email Injection
|
||||
SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES|REQUEST_HEADERS|XML:/* "[\n\r]\s*(?:to|bcc|cc)\s*:.*?\@" \
|
||||
"t:none,t:lowercase,t:urlDecode,capture,log,auditlog,msg:'Email Injection Attack. Matched signature <%{TX.0}>',,id:'950019',severity:'2'"
|
||||
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# The trojan access detection rules detects access to known Trojans already
|
||||
# installed on a server. Uploading of Trojans is part of the Anti-Virus rules
|
||||
# and uses external Anti Virus program when uploading files.
|
||||
#
|
||||
# Detection of Trojans access is especially important in a hosting environment
|
||||
# where the actual Trojan upload may be done through valid methods and not
|
||||
# through hacking.
|
||||
# --
|
||||
#
|
||||
# NOTE Trojans detection is based on checking elements controlled by the client.
|
||||
# A determined attacked can bypass those checks. We are working on
|
||||
# enchaining the checks so it would require a major change in the Trojan
|
||||
# to overcome.
|
||||
#
|
||||
# NOTE We found out that Trojan horses are not detected easily by Anti-Virus
|
||||
# software when uploading as the signature set of AV software is not tuned
|
||||
# for this purpose. We are working on adding signature tuned to detect
|
||||
# Trojans upload to file uploading inspection.
|
||||
#
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase,status:404"
|
||||
|
||||
SecRule REQUEST_HEADERS_NAMES "x_(?:key|file)\b" "ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',id:'950110',severity:'2'"
|
||||
SecRule REQUEST_FILENAME "root\.exe" \
|
||||
"t:urlDecodeUni,t:htmlEntityDecode,ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',id:'950921',severity:'2'"
|
||||
SecRule RESPONSE_BODY "(?:<title>[^<]*?(?:\b(?:(?:c(?:ehennemden|gi-telnet)|gamma web shell)\b|imhabirligi phpftp)|(?:r(?:emote explorer|57shell)|aventis klasvayv|zehir)\b|\.::(?:news remote php shell injection::\.| rhtools\b)|ph(?:p(?:(?: commander|-terminal)\b|remoteview)|vayv)|myshell)|\b(?:(?:(?:microsoft windows\b.{,10}\bversion\b.{,20}(c) copyright 1985-.{,10}\bmicrosoft corp|ntdaddy v1\.9 - obzerve \| fux0r inc)\.|(?:www\.sanalteror\.org - indexer and read|haxplor)er|php(?:konsole| shell)|c99shell)\b|aventgrup\.<br>|drwxr))" \
|
||||
"phase:4,ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',id:'950922',severity:'2'"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# The trojan access detection rules detects access to known Trojans already
|
||||
# installed on a server. Uploading of Trojans is part of the Anti-Virus rules
|
||||
# and uses external Anti Virus program when uploading files.
|
||||
#
|
||||
# Detection of Trojans access is especially important in a hosting environment
|
||||
# where the actual Trojan upload may be done through valid methods and not
|
||||
# through hacking.
|
||||
# --
|
||||
#
|
||||
# NOTE Trojans detection is based on checking elements controlled by the client.
|
||||
# A determined attacked can bypass those checks. We are working on
|
||||
# enchaining the checks so it would require a major change in the Trojan
|
||||
# to overcome.
|
||||
#
|
||||
# NOTE We found out that Trojan horses are not detected easily by Anti-Virus
|
||||
# software when uploading as the signature set of AV software is not tuned
|
||||
# for this purpose. We are working on adding signature tuned to detect
|
||||
# Trojans upload to file uploading inspection.
|
||||
#
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase,status:404"
|
||||
|
||||
SecRule REQUEST_HEADERS_NAMES "x_(?:key|file)\b" "ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',,id:'950110',severity:'2'"
|
||||
SecRule REQUEST_FILENAME "root\.exe" \
|
||||
"t:urlDecodeUni,t:htmlEntityDecode,ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',,id:'950921',severity:'2'"
|
||||
SecRule RESPONSE_BODY "(?:<title>[^<]*?(?:\b(?:(?:c(?:ehennemden|gi-telnet)|gamma web shell)\b|imhabirligi phpftp)|(?:r(?:emote explorer|57shell)|aventis klasvayv|zehir)\b|\.::(?:news remote php shell injection::\.| rhtools\b)|ph(?:p(?:(?: commander|-terminal)\b|remoteview)|vayv)|myshell)|\b(?:(?:(?:microsoft windows\b.{,10}?\bversion\b.{,20}?(c) copyright 1985-.{,10}?\bmicrosoft corp|ntdaddy v1\.9 - obzerve \| fux0r inc)\.|(?:www\.sanalteror\.org - indexer and read|haxplor)er|php(?:konsole| shell)|c99shell)\b|aventgrup\.<br>|drwxr))" \
|
||||
"phase:4,ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Backdoor access',,id:'950922',severity:'2'"
|
||||
|
||||
@@ -1,68 +1,73 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# NOTE By default the status code sent is 501, which implies that the web
|
||||
# server does not support the required operation. This is a non standard
|
||||
# of this status code which normally refers to unsupported HTTP methods.
|
||||
# It is used in order to confuse automated clients and scanners.
|
||||
|
||||
SecDefaultAction "log,pass,status:501,phase:4"
|
||||
|
||||
SecRule RESPONSE_BODY "\b(?:th(?:is (?:(?:analysis was produced by .{0,100} ana|report was generated by web)log|summary was generated by .{0,100} wwwstat)|ese statistics were produced by (?:getstats|pelab))|generated by webalizer)\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Statistics Information Leakage',id:'970002',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b(?:(?:s(?:(?:elect list because it is not contained in (?:an aggregate function and there is no|either an aggregate function or the) group by claus|yntax error converting the \w+ value .*? to a column of data typ)e|upplied argument is not a valid (?:(?:m(?:s |y)|postgre)sql|o(?:racle|dbc)))|(?:you have an error in your sql|incorrect) syntax near|SQL Server does not exist or access denied)\b|c(?:ould not find server '\w+' in sysservers\. execute sp_addlinkedserver\b|annot take a \w+ data type as an argument\.)|e(?:ither bof or eof is true, or the current record has been deleted\. requested\b|rror '800a01b8')|un(?:closed quotation mark before the character string\b|able to connect to postgresql server:)|microsoft (?:ole db provider for .{0,30} error '|jet database engine error '8)|(?:warning: mysql_connect\(\)|postgresql query failed):|(?:\[microsoft\]\[odbc|ora-\d{5}:) )" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'SQL Information Leakage',id:'970003',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:adodb\.command\b.{0,100}\b(?:application uses a value of the wrong type for the current operation\b|error')|microsoft vbscript (?:compilation|runtime) (?:\(0x8|error)\b|object required: '|error '800)|(?:\/errormessage\.aspx\?error|>error 'asp)\b)" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'IIS Information Leakage',id:'970004',severity:'4'"
|
||||
SecRule RESPONSE_BODY "\bserver error in.{0,50}\bapplication\b" \
|
||||
"chain,ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'IIS Information Leakage',id:'970904',severity:'4'"
|
||||
SecRule RESPONSE_STATUS "!^404$"
|
||||
|
||||
SecRule RESPONSE_BODY "\ban error was encountered while publishing this resource\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'Zope Information Leakage',id:'970007',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\bthe error occurred in\b.{0,100}\: line\b.{0,1000}\bcoldfusion\b.*?\bstack trace \(click to expand\)\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'Cold Fusion Information Leakage',id:'970008',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\<b\>warning\<\/b\>\:\b\W*?\bon line\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'PHP Information Leakage',id:'970009',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b403 forbidden\b\W*?\binternet security and acceleration server\b" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'ISA server existence revealed',id:'970010',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b<o:documentproperties>\b" \
|
||||
"log,auditlog,msg:'Microsoft Word document properties leakage',id:'970012',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:>\[to parent directory\]<\/a><br>|<title>index of.*?<h1>index of)" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:403,msg:'Directory Listing',id:'970013',severity:'4'"
|
||||
|
||||
#SecRule RESPONSE_BODY "\b[a-z]\:\\." "chain,ctl:auditLogParts=+E,log,auditlog,msg:'File or Directory Names Leakage',id:'970011',severity:'4'"
|
||||
#SecRule RESPONSE_BODY "!program files\\microsoft office\\(?:office|templates)"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:(?:s(?:erver\.(?:(?:(?:htm|ur)lencod|execut)e|createobject|mappath)|cripting\.filesystemobject)|(?:response\.(?:binary)?writ|vbscript\.encod)e|wscript\.(?:network|shell))\b|javax\.servlet|<jsp:)|\.(?:(?:(?:createtex|ge)t|loadfrom)file|addheader)\b)" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'ASP/JSP source code leakage',id:'970014',severity:'4'"
|
||||
SecRule RESPONSE_BODY "\<\%" "chain,ctl:auditLogParts=+E,log,auditlog,msg:'ASP/JSP source code leakage',id:'970903',severity:'4'"
|
||||
SecRule RESPONSE_BODY "!(?:\b(?:(?:i(?:nterplay|hdr|d3)|m(?:ovi|thd)|(?:ex|jf)if|f(?:lv|ws)|varg|cws)\b|r(?:iff\b|ar!B)|gif)|B(?:%pdf|\.ra)\b)"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'PHP source code leakage',id:'970015',severity:'4'"
|
||||
SecRule RESPONSE_BODY "<\?(?!xml)" \
|
||||
"chain,ctl:auditLogParts=+E,log,auditlog,msg:'PHP source code leakage',id:'970902',severity:'4'"
|
||||
SecRule RESPONSE_BODY "!(?:\b(?:(?:i(?:nterplay|hdr|d3)|m(?:ovi|thd)|(?:ex|jf)if|f(?:lv|ws)|varg|cws)\b|r(?:iff\b|ar!B)|gif)|B(?:%pdf|\.ra)\b)"
|
||||
|
||||
SecRule RESPONSE_BODY "\b<cf" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'Cold Fusion source code leakage',id:'970016',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_STATUS "^503$" "ctl:auditLogParts=+E,log,auditlog,msg:'The application is not available',id:'970901',severity:'5'"
|
||||
SecRule RESPONSE_BODY "(?:(?:<h1>internal server error<\/h1>.*?<h2>part of the server has crashed or it has a configuration error\.<\/h2|microsoft ole db provider for sql server \(0x80040e31\)<br>timeout expired<br)>|cannot connect to the server: timed out)" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'The application is not available',id:'970118',severity:'5'"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# NOTE By default the status code sent is 501, which implies that the web
|
||||
# server does not support the required operation. This is a non standard
|
||||
# of this status code which normally refers to unsupported HTTP methods.
|
||||
# It is used in order to confuse automated clients and scanners.
|
||||
|
||||
SecDefaultAction "log,pass,status:501,phase:4"
|
||||
|
||||
SecRule RESPONSE_BODY "\b(?:th(?:is (?:(?:analysis was produced by .{0,100}? ana|report was generated by web)log|summary was generated by .{0,100}? wwwstat)|ese statistics were produced by (?:getstats|pelab))|generated by webalizer)\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:404,msg:'Statistics Information Leakage',,id:'970002',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b(?:(?:s(?:(?:elect list because it is not contained in (?:an aggregate function and there is no|either an aggregate function or the) group by claus|yntax error converting the \w+ value .*? to a column of data typ)e|upplied argument is not a valid (?:(?:m(?:s |y)|postgre)sql|o(?:racle|dbc)))|(?:you have an error in your sql|incorrect) syntax near|SQL Server does not exist or access denied)\b|c(?:ould not find server '\w+' in sysservers\. execute sp_addlinkedserver\b|annot take a \w+ data type as an argument\.)|e(?:ither bof or eof is true, or the current record has been deleted\. requested\b|rror '800a01b8')|un(?:closed quotation mark before the character string\b|able to connect to postgresql server:)|microsoft (?:ole db provider for .{0,30} error '|jet database engine error '8)|(?:warning: mysql_connect\(\)|postgresql query failed):|(?:\[microsoft\]\[odbc|ora-\d{5}:) )" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'SQL Information Leakage',,id:'970003',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:adodb\.command\b.{0,100}?\b(?:application uses a value of the wrong type for the current operation\b|error')|microsoft vbscript (?:compilation|runtime) (?:\(0x8|error)\b|object required: '|error '800)|(?:\/errormessage\.aspx\?error|>error 'asp)\b)" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'IIS Information Leakage',,id:'970004',severity:'4'"
|
||||
SecRule RESPONSE_BODY "\bserver error in.{0,50}\bapplication\b" \
|
||||
"chain,ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'IIS Information Leakage',,id:'970904',severity:'4'"
|
||||
SecRule RESPONSE_STATUS "!^404$"
|
||||
|
||||
SecRule RESPONSE_BODY "\ban error was encountered while publishing this resource\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'Zope Information Leakage',,id:'970007',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\bthe error occurred in\b.{0,100}\: line\b.{0,1000}\bcoldfusion\b.*?\bstack trace \(click to expand\)\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'Cold Fusion Information Leakage',,id:'970008',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\<b\>warning\<\/b\>\:\b\W*?\bon line\b" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:500,msg:'PHP Information Leakage',,id:'970009',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b403 forbidden\b\W*?\binternet security and acceleration server\b" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'ISA server existence revealed',,id:'970010',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "\b<o:documentproperties>\b" \
|
||||
"log,auditlog,msg:'Microsoft Word document properties leakage',,id:'970012',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:>\[to parent directory\]<\/a><br>|<title>index of.*?<h1>index of)" \
|
||||
"ctl:auditLogParts=+E,deny,log,auditlog,status:403,msg:'Directory Listing',,id:'970013',severity:'4'"
|
||||
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:(?:s(?:erver\.(?:(?:(?:htm|ur)lencod|execut)e|createobject|mappath)|cripting\.filesystemobject)|(?:response\.(?:binary)?writ|vbscript\.encod)e|wscript\.(?:network|shell))\b|javax\.servlet|<jsp:)|\.(?:(?:(?:createtex|ge)t|loadfrom)file|addheader)\b)" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'ASP/JSP source code leakage',,id:'970014',severity:'4'"
|
||||
SecRule RESPONSE_BODY "\<\%" "chain,ctl:auditLogParts=+E,log,auditlog,msg:'ASP/JSP source code leakage',,id:'970903',severity:'4'"
|
||||
SecRule RESPONSE_BODY "!(?:\b(?:(?:i(?:nterplay|hdr|d3)|m(?:ovi|thd)|(?:ex|jf)if|f(?:lv|ws)|varg|cws)\b|r(?:iff\b|ar!B)|gif)|B(?:%pdf|\.ra)\b)"
|
||||
|
||||
SecRule RESPONSE_BODY "(?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open)|\$_(?:(?:pos|ge)t|session))\b" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'PHP source code leakage',,id:'970015',severity:'4'"
|
||||
SecRule RESPONSE_BODY "<\?(?!xml)" \
|
||||
"chain,ctl:auditLogParts=+E,log,auditlog,msg:'PHP source code leakage',,id:'970902',severity:'4'"
|
||||
SecRule RESPONSE_BODY "!(?:\b(?:(?:i(?:nterplay|hdr|d3)|m(?:ovi|thd)|(?:ex|jf)if|f(?:lv|ws)|varg|cws)\b|r(?:iff\b|ar!B)|gif)|B(?:%pdf|\.ra)\b)"
|
||||
|
||||
SecRule RESPONSE_BODY "\b<cf" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'Cold Fusion source code leakage',,id:'970016',severity:'4'"
|
||||
|
||||
SecRule RESPONSE_BODY "[a-z]:\\\\inetpub\b" \
|
||||
"t:none,t:lowercase,ctl:auditLogParts=+E,log,auditlog,msg:'IIS installed in default location',,id:'970018',severity:'5',chain"
|
||||
SecRule &RESOURCE:alerted_970018_iisDefLoc "@eq 0" "setvar:resource.alerted_970018_iisDefLoc"
|
||||
|
||||
SecRule RESPONSE_STATUS "^503$" "ctl:auditLogParts=+E,log,auditlog,msg:'The application is not available',,id:'970901',severity:'5'"
|
||||
SecRule RESPONSE_BODY "(?:(?:<h1>internal server error<\/h1>.*?<h2>part of the server has crashed or it has a configuration error\.<\/h2|microsoft ole db provider for sql server \(0x80040e31\)<br>timeout expired<br)>|cannot connect to the server: timed out)" \
|
||||
"ctl:auditLogParts=+E,log,auditlog,msg:'The application is not available',,id:'970118',severity:'5'"
|
||||
|
||||
SecRule RESPONSE_STATUS "^500$" "chain,ctl:auditLogParts=+E,log,auditlog,msg:'WebLogic information disclosure',,id:'970021',severity:'4'"
|
||||
SecRule RESPONSE_BODY "<title>JSP compile error</title>" t:none
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# These rules do not have a security importance, but shows other benefits of
|
||||
# monitoring and logging HTTP transactions.
|
||||
# --
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase"
|
||||
|
||||
SecRule HTTP_User-Agent "msn(?:bot|ptc)" \
|
||||
"log,auditlog,msg:'MSN robot activity',id:'910008',severity:'5'"
|
||||
|
||||
SecRule HTTP_User-Agent "\byahoo(?:-(?:mmcrawler|blogs)|! slurp)\b" \
|
||||
"log,auditlog,msg:'Yahoo robot activity',id:'910007',severity:'5'"
|
||||
|
||||
SecRule HTTP_User-Agent "\b(?:google(?:-sitemaps|bot)|mediapartners-google)\b" \
|
||||
"log,auditlog,msg:'Google robot activity',id:'910006',severity:'5'"
|
||||
# ---------------------------------------------------------------
|
||||
# Core ModSecurity Rule Set
|
||||
# Copyright (C) 2006 Breach Security Inc. All rights reserved.
|
||||
#
|
||||
# The ModSecuirty Core Rule Set is distributed under GPL version 2
|
||||
# Please see the enclosed LICENCE file for full details.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# These rules do not have a security importance, but shows other benefits of
|
||||
# monitoring and logging HTTP transactions.
|
||||
# --
|
||||
|
||||
SecDefaultAction "log,pass,phase:2,t:lowercase"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "msn(?:bot|ptc)" \
|
||||
"log,auditlog,msg:'MSN robot activity',,id:'910008',severity:'5'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "\byahoo(?:-(?:mmcrawler|blogs)|! slurp)\b" \
|
||||
"log,auditlog,msg:'Yahoo robot activity',,id:'910007',severity:'5'"
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "(?:(?:gsa-crawler \(enterprise; s4-e9lj2b82fjjaa; me\@mycompany\.com|adsbot-google \(\+http:\/\/www\.google\.com\/adsbot\.html)\)|\b(?:google(?:-sitemaps|bot)|mediapartners-google)\b)" \
|
||||
"log,auditlog,msg:'Google robot activity',,id:'910006',severity:'5'"
|
||||
|
||||
Reference in New Issue
Block a user