diff --git a/.cdtproject b/.cdtproject
deleted file mode 100644
index 93d4fd4b..00000000
--- a/.cdtproject
+++ /dev/null
@@ -1,1192 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- make
-
- all
- false
- true
-
-
- make
-
- test
- false
- true
-
-
- gksudo
- make
- install
- false
- false
-
-
- make
-
- clean
- false
- true
-
-
- make
-
- dist-clean
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.jupiter b/.jupiter
deleted file mode 100644
index 4bd771a5..00000000
--- a/.jupiter
+++ /dev/null
@@ -1,200 +0,0 @@
-
-
-
- property.default.description
-
- 1970-01-01 :: 00:00:00:000 GMT-10:00
- review
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Pre 2.5 Review
- brian
- 2008-01-04 :: 10:09:23:000 GMT-08:00
- review
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.project b/.project
deleted file mode 100644
index 6f0bc9dc..00000000
--- a/.project
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
- ModSecurity
-
-
-
-
-
- org.eclipse.cdt.make.core.makeBuilder
- clean,full,incremental,
-
-
- org.eclipse.cdt.make.core.append_environment
- true
-
-
- org.eclipse.cdt.make.core.enableCleanBuild
- true
-
-
- org.eclipse.cdt.make.core.build.command
- make
-
-
- org.eclipse.cdt.make.core.useDefaultBuildCmd
- true
-
-
- org.eclipse.cdt.make.core.build.target.auto
- all
-
-
- org.eclipse.cdt.make.core.stopOnError
- false
-
-
- org.eclipse.cdt.make.core.build.location
-
-
-
- org.eclipse.cdt.make.core.build.target.inc
- all
-
-
- org.eclipse.cdt.make.core.build.arguments
-
-
-
- org.eclipse.cdt.core.errorOutputParser
- org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser;
-
-
- org.eclipse.cdt.make.core.enableAutoBuild
- false
-
-
- org.eclipse.cdt.make.core.environment
-
-
-
- org.eclipse.cdt.make.core.enabledIncrementalBuild
- true
-
-
- org.eclipse.cdt.make.core.build.target.clean
- clean
-
-
- org.eclipse.cdt.make.core.enableFullBuild
- true
-
-
-
-
- org.eclipse.cdt.make.core.ScannerConfigBuilder
-
-
-
-
-
- org.eclipse.cdt.core.cnature
- org.eclipse.cdt.make.core.makeNature
- org.eclipse.cdt.make.core.ScannerConfigNature
-
-
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
deleted file mode 100644
index 2222ff26..00000000
--- a/.settings/org.eclipse.cdt.core.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Fri Jan 04 09:57:26 GMT-08:00 2008
-eclipse.preferences.version=1
-indexerId=org.eclipse.cdt.core.fastIndexer
diff --git a/CHANGES b/CHANGES
index cda4a90c..ea8a1e9b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,12 +1,13 @@
-07 Oct 2008 - trunk
+21 Nov 2008 - 2.5.8
-------------------
+ * Fixed PDF XSS issue where a non-GET request for a PDF file would crash the
+ Apache httpd process. Discovered by Steve Grubb at Red Hat.
+
* Removed an invalid "Internal error: Issuing "%s" for unspecified error."
message that was logged when denying with nolog/noauditlog set and
causing the request to be audited.
- * Persistent counter updates are now atomic.
-
24 Sep 2008 - 2.5.7
-------------------
diff --git a/apache2/apache2_util.c b/apache2/apache2_util.c
index 353c76f4..34fa0c3f 100644
--- a/apache2/apache2_util.c
+++ b/apache2/apache2_util.c
@@ -240,7 +240,7 @@ void internal_log(request_rec *r, directory_config *dcfg, modsec_rec *msr,
char str1[1024] = "";
char str2[1256] = "";
- /* Find the logging FD and look up the logging level in the configuration. */
+ /* Find the logging FD and determine the logging level from configuration. */
if (dcfg != NULL) {
if ((dcfg->debuglog_fd != NULL)&&(dcfg->debuglog_fd != NOT_SET_P)) {
debuglog_fd = dcfg->debuglog_fd;
diff --git a/apache2/mlogc-src/mlogc-batch-load.pl.in b/apache2/mlogc-src/mlogc-batch-load.pl.in
index a32f57fa..75d43ba5 100755
--- a/apache2/mlogc-src/mlogc-batch-load.pl.in
+++ b/apache2/mlogc-src/mlogc-batch-load.pl.in
@@ -1,7 +1,7 @@
#!@PERL@
#
# ModSecurity for Apache 2.x, http://www.modsecurity.org/
-# Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
+# Copyright (c) 2004-2008 Breach Security, Inc. (http://www.breach.com/)
#
# This product is released under the terms of the General Public Licence,
# version 2 (GPLv2). Please refer to the file LICENSE (included with this
diff --git a/apache2/pdf_protect.c b/apache2/pdf_protect.c
index d5c26482..0c708955 100644
--- a/apache2/pdf_protect.c
+++ b/apache2/pdf_protect.c
@@ -365,7 +365,6 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
*/
int pdfp_check(modsec_rec *msr) {
const char *token = NULL;
- directory_config *cfg = NULL;
char *uri = NULL;
char *p = NULL;
@@ -426,10 +425,12 @@ int pdfp_check(modsec_rec *msr) {
/* Ignore request methods other than GET and HEAD if
* configured to do so.
+ *
+ * TODO: Code here is only GET, not GET|HEAD as comment states
*/
- if ((msr->r->method_number != M_GET)&&(cfg->pdfp_only_get != 0)) {
+ if ((msr->r->method_number != M_GET)&&(msr->txcfg->pdfp_only_get != 0)) {
if (msr->txcfg->debuglog_level >= 4) {
- msr_log(msr, 4, "PdfProtect: Not intercepting a GET/HEAD request "
+ msr_log(msr, 4, "PdfProtect: Not intercepting request "
"(method=%s/%d).", log_escape_nq(msr->mp, msr->r->method), msr->r->method_number);
}
diff --git a/apache2/t/action/.empty b/apache2/t/action/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/apache2/t/regression/server_root/data/.empty b/apache2/t/regression/server_root/data/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/apache2/t/regression/server_root/htdocs/test.pdf b/apache2/t/regression/server_root/htdocs/test.pdf
new file mode 100644
index 00000000..a6ec2d04
Binary files /dev/null and b/apache2/t/regression/server_root/htdocs/test.pdf differ
diff --git a/apache2/t/regression/server_root/logs/audit/.empty b/apache2/t/regression/server_root/logs/audit/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/apache2/t/regression/server_root/logs/subdir/.empty b/apache2/t/regression/server_root/logs/subdir/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/apache2/t/regression/server_root/tmp/.empty b/apache2/t/regression/server_root/tmp/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/apache2/t/regression/server_root/upload/.empty b/apache2/t/regression/server_root/upload/.empty
new file mode 100644
index 00000000..e69de29b
diff --git a/doc/modsecurity2-apache-reference.xml b/doc/modsecurity2-apache-reference.xml
index 76cda13a..a3bf4940 100644
--- a/doc/modsecurity2-apache-reference.xml
+++ b/doc/modsecurity2-apache-reference.xml
@@ -2,845 +2,1338 @@
- ModSecurity Reference Manual
+ ModSecurity Reference
+ Manual
+
- Version 2.6.0-trunk (September 5, 2008)
+ Version 2.6.0-trunk (March 5, 2009)
+
2004-2008
- Breach Security, Inc. (http://www.breach.com)
+
+ Breach Security, Inc. (http://www.breach.com)
+
Introduction
- ModSecurity is a web application firewall (WAF). With over 70% of attacks now carried out
- over the web application level, organisations need all the help they can get in making their
- systems secure. WAFs are deployed to establish an increased external security layer to detect
- and/or prevent attacks before they reach web applications. ModSecurity provides protection
- from a range of attacks against web applications and allows for HTTP traffic monitoring and
- real-time analysis with little or no changes to existing infrastructure.
+
+ ModSecurity is a web application firewall (WAF). With over 70% of
+ attacks now carried out over the web application level, organisations need
+ all the help they can get in making their systems secure. WAFs are
+ deployed to establish an increased external security layer to detect
+ and/or prevent attacks before they reach web applications. ModSecurity
+ provides protection from a range of attacks against web applications and
+ allows for HTTP traffic monitoring and real-time analysis with little or
+ no changes to existing infrastructure.
+
HTTP Traffic Logging
- Web servers are typically well-equipped to log traffic in a form useful for marketing
- analyses, but fall short logging traffic to web applications. In particular, most are not
- capable of logging the request bodies. Your adversaries know this, and that is why most
- attacks are now carried out via POST requests, rendering your systems blind. ModSecurity
- makes full HTTP transaction logging possible, allowing complete requests and responses to be
- logged. Its logging facilities also allow fine-grained decisions to be made about exactly
- what is logged and when, ensuring only the relevant data is recorded. As some of the request
- and/or response may contain sensitive data in certain fields, ModSecurity can be configured
- to mask these fields before they are written to the audit log.
+
+ Web servers are typically well-equipped to log traffic in a form
+ useful for marketing analyses, but fall short logging traffic to web
+ applications. In particular, most are not capable of logging the request
+ bodies. Your adversaries know this, and that is why most attacks are now
+ carried out via POST requests, rendering your systems blind. ModSecurity
+ makes full HTTP transaction logging possible, allowing complete requests
+ and responses to be logged. Its logging facilities also allow
+ fine-grained decisions to be made about exactly what is logged and when,
+ ensuring only the relevant data is recorded. As some of the request
+ and/or response may contain sensitive data in certain fields,
+ ModSecurity can be configured to mask these fields before they are
+ written to the audit log.
+
Real-Time Monitoring and Attack Detection
- In addition to providing logging facilities, ModSecurity can monitor the HTTP traffic in
- real time in order to detect attacks. In this case, ModSecurity operates as a web intrusion
- detection tool, allowing you to react to suspicious events that take place at your web
- systems.
+
+ In addition to providing logging facilities, ModSecurity can
+ monitor the HTTP traffic in real time in order to detect attacks. In
+ this case, ModSecurity operates as a web intrusion detection tool,
+ allowing you to react to suspicious events that take place at your web
+ systems.
+
Attack Prevention and Just-in-time Patching
- ModSecurity can also act immediately to prevent attacks from reaching your web
- applications. There are three commonly used approaches:
+
+ ModSecurity can also act immediately to prevent attacks from
+ reaching your web applications. There are three commonly used
+ approaches:
+
- Negative security model. A negative security model monitors requests for anomalies,
- unusual behaviour, and common web application attacks. It keeps anomaly scores for each
- request, IP addresses, application sessions, and user accounts. Requests with high
- anomaly scores are either logged or rejected altogether.
+ Negative security model. A negative security model monitors
+ requests for anomalies, unusual behaviour, and common web
+ application attacks. It keeps anomaly scores for each request, IP
+ addresses, application sessions, and user accounts. Requests with
+ high anomaly scores are either logged or rejected altogether.
+
- Positive security model. When a positive security model is deployed, only requests
- that are known to be valid are accepted, with everything else rejected. This model
- requires knownledge of the web applications you are protecting. Therefore a positive
- security model works best with applications that are heavily used but rarely updated so
- that maintenance of the model is minimized.
+ Positive security model. When a positive security model is
+ deployed, only requests that are known to be valid are accepted,
+ with everything else rejected. This model requires knownledge of the
+ web applications you are protecting. Therefore a positive security
+ model works best with applications that are heavily used but rarely
+ updated so that maintenance of the model is minimized.
+
- Known weaknesses and vulnerabilities. Its rule language makes ModSecurity an ideal
- external patching tool. External patching (sometimes referred to as Virtual Patching) is
- about reducing the window of opportunity. Time needed to patch application
- vulnerabilities often runs to weeks in many organisations. With ModSecurity,
- applications can be patched from the outside, without touching the application source
- code (and even without any access to it), making your systems secure until a proper
- patch is applied to the application.
+ Known weaknesses and vulnerabilities. Its rule language makes
+ ModSecurity an ideal external patching tool. External patching
+ (sometimes referred to as Virtual Patching) is about reducing the
+ window of opportunity. Time needed to patch application
+ vulnerabilities often runs to weeks in many organisations. With
+ ModSecurity, applications can be patched from the outside, without
+ touching the application source code (and even without any access to
+ it), making your systems secure until a proper patch is applied to
+ the application.
+
Flexible Rule Engine
- A flexible rule engine sits in the heart of ModSecurity. It implements the ModSecurity
- Rule Language, which is a specialised programming language designed to work with HTTP
- transaction data. The ModSecurity Rule Language is designed to be easy to use, yet flexible:
- common operations are simple while complex operations are possible. Certified ModSecurity
- Rules, included with ModSecurity, contain a comprehensive set of rules that implement
- general-purpose hardening, protocol validation and detection of common web application
- security issues. Heavily commented, these rules can be used as a learning tool.
+
+ A flexible rule engine sits in the heart of ModSecurity. It
+ implements the ModSecurity Rule Language, which is a specialised
+ programming language designed to work with HTTP transaction data. The
+ ModSecurity Rule Language is designed to be easy to use, yet flexible:
+ common operations are simple while complex operations are possible.
+ Certified ModSecurity Rules, included with ModSecurity, contain a
+ comprehensive set of rules that implement general-purpose hardening,
+ protocol validation and detection of common web application security
+ issues. Heavily commented, these rules can be used as a learning
+ tool.
+
Embedded-mode Deployment
- ModSecurity is an embeddable web application firewall, which means it can be deployed as
- part of your existing web server infrastructure provided your web servers are Apache-based.
- This deployment method has certain advantages:
+
+ ModSecurity is an embeddable web application firewall, which means
+ it can be deployed as part of your existing web server infrastructure
+ provided your web servers are Apache-based. This deployment method has
+ certain advantages:
+
- No changes to existing network. It only takes a few minutes to add ModSecurity to
- your existing web servers. And because it was designed to be completely passive by
- default, you are free to deploy it incrementally and only use the features you need. It
- is equally easy to remove or deactivate it if required.
+ No changes to existing network. It only takes a few minutes to
+ add ModSecurity to your existing web servers. And because it was
+ designed to be completely passive by default, you are free to deploy
+ it incrementally and only use the features you need. It is equally
+ easy to remove or deactivate it if required.
+
- No single point of failure. Unlike with network-based deployments, you will not be
- introducing a new point of failure to your system.
+ No single point of failure. Unlike with network-based
+ deployments, you will not be introducing a new point of failure to
+ your system.
+
- Implicit load balancing and scaling. Because it works embedded in web servers,
- ModSecurity will automatically take advantage of the additional load balancing and
- scalability features. You will not need to think of load balancing and scaling unless
- your existing system needs them.
+ Implicit load balancing and scaling. Because it works embedded
+ in web servers, ModSecurity will automatically take advantage of the
+ additional load balancing and scalability features. You will not
+ need to think of load balancing and scaling unless your existing
+ system needs them.
+
- Minimal overhead. Because it works from inside the web server process there is no
- overhead for network communication and minimal overhead in parsing and data
- exchange.
+ Minimal overhead. Because it works from inside the web server
+ process there is no overhead for network communication and minimal
+ overhead in parsing and data exchange.
+
- No problem with encrypted or compressed content. Many IDS systems have difficulties
- analysing SSL traffic. This is not a problem for ModSecurity because it is positioned to
- work when the traffic is decrypted and decompressed.
+ No problem with encrypted or compressed content. Many IDS
+ systems have difficulties analysing SSL traffic. This is not a
+ problem for ModSecurity because it is positioned to work when the
+ traffic is decrypted and decompressed.
+
Network-based Deployment
- ModSecurity works equally well when deployed as part of an Apache-based reverse proxy
- server, and many of our customers choose to do so. In this scenario, one installation of
- ModSecurity can protect any number of web servers (even the non-Apache ones).
+
+ ModSecurity works equally well when deployed as part of an
+ Apache-based reverse proxy server, and many of our customers choose to
+ do so. In this scenario, one installation of ModSecurity can protect any
+ number of web servers (even the non-Apache ones).
+
Portability
- ModSecurity is known to work well on a wide range of operating systems. Our customers
- are successfully running it on Linux, Windows, Solaris, FreeBSD, OpenBSD, NetBSD, AIX, Mac
- OS X, and HP-UX.
+
+ ModSecurity is known to work well on a wide range of operating
+ systems. Our customers are successfully running it on Linux, Windows,
+ Solaris, FreeBSD, OpenBSD, NetBSD, AIX, Mac OS X, and HP-UX.
+
Licensing
- ModSecurity is available under two licenses. Users can choose to use the software under
- the terms of the GNU General Public License version 2 (licence text is included with the
- distribution), as an Open Source / Free Software product. A range of commercial licenses is
- also available, together with a range of commercial support contracts. For more information
- on commercial licensing please contact Breach Security.
+
+ ModSecurity is available under two licenses. Users can choose to
+ use the software under the terms of the GNU General Public License
+ version 2 (licence text is included with the distribution), as an Open
+ Source / Free Software product. A range of commercial licenses is also
+ available, together with a range of commercial support contracts. For
+ more information on commercial licensing please contact Breach
+ Security.
+
- ModSecurity, mod_security, ModSecurity Pro, and ModSecurity Core Rules are trademarks
- or registered trademarks of Breach Security, Inc.
+ ModSecurity, mod_security, ModSecurity Pro, and ModSecurity Core
+ Rules are trademarks or registered trademarks of Breach Security,
+ Inc.
+
ModSecurity Core Rules
+
Overview
- ModSecurity is a web application firewall engine that provides very little protection on
- its own. In order to become useful, ModSecurity must be configured with rules. In order to
- enable users to take full advantage of ModSecurity out of the box, Breach Security, Inc. is
- providing a free certified rule set for ModSecurity 2.x. Unlike intrusion detection and
- prevention systems, which rely on signatures specific to known vulnerabilities, the Core
- Rules provide generic protection from unknown vulnerabilities often found in web
- applications, which are in most cases custom coded. The Core Rules are heavily commented to
- allow it to be used as a step-by-step deployment guide for ModSecurity. The latest Core
- Rules can be found at the ModSecurity website - http://www.modsecurity.org/projects/rules/.
+
+ ModSecurity is a web application firewall engine that provides
+ very little protection on its own. In order to become useful,
+ ModSecurity must be configured with rules. In order to enable users to
+ take full advantage of ModSecurity out of the box, Breach Security, Inc.
+ is providing a free certified rule set for ModSecurity 2.x. Unlike
+ intrusion detection and prevention systems, which rely on signatures
+ specific to known vulnerabilities, the Core Rules provide generic
+ protection from unknown vulnerabilities often found in web applications,
+ which are in most cases custom coded. The Core Rules are heavily
+ commented to allow it to be used as a step-by-step deployment guide for
+ ModSecurity. The latest Core Rules can be found at the ModSecurity
+ website - http://www.modsecurity.org/projects/rules/.
+
Core Rules Content
- In order to provide generic web applications protection, the Core Rules use the
- following techniques:
+
+ In order to provide generic web applications protection, the Core
+ Rules use the following techniques:
+
- HTTP protection - detecting violations of the HTTP protocol and a locally defined
- usage policy.
+ HTTP protection - detecting violations of the HTTP protocol
+ and a locally defined usage policy.
+
- Common Web Attacks Protection - detecting common web application security
- attack.
+ Common Web Attacks Protection - detecting common web
+ application security attack.
+
- Automation detection - Detecting bots, crawlers, scanners and other surface
- malicious activity.
+ Automation detection - Detecting bots, crawlers, scanners and
+ other surface malicious activity.
+
Trojan Protection - Detecting access to Trojans horses.
+
- Error Hiding - Disguising error messages sent by the server.
+ Error Hiding - Disguising error messages sent by the
+ server.
+
Installation
+
ModSecurity installation consists of the following steps:
+
ModSecurity 2.x works with Apache 2.0.x or better.
+
- Make sure you have mod_unique_id installed.
+ Make sure you have mod_unique_id installed.
+
mod_unique_id is packaged with Apache httpd.
+
- Install the latest version of libxml2, if it isn't already installed on the
- server.
- http://xmlsoft.org/downloads.html
+ Install the latest version of libxml2, if it isn't already
+ installed on the server.
+
+ http://xmlsoft.org/downloads.html
+
- Optionally install the latest version of Lua in the 5.1.x branch, if it isn't already
- installed on the server and you will be using the new Lua engine.
- http://www.lua.org/download.html
- Note that ModSecurity requires the dynamic libraries. These are not built by default
- in the source distribution, so the binary distribution is recommended.
+ Optionally install the latest version of Lua in the 5.1.x
+ branch, if it isn't already installed on the server and you will be
+ using the new Lua engine.
+
+ http://www.lua.org/download.html
+
+ Note that ModSecurity requires the dynamic libraries. These are
+ not built by default in the source distribution, so the binary
+ distribution is recommended.
+
Stop Apache httpd
+
Unpack the ModSecurity archive
+
- Building differs for UNIX (or UNIX-like) operating systems and Windows.
+ Building differs for UNIX (or UNIX-like) operating systems and
+ Windows.
+
UNIX
+
- Run the configure script to generate a Makefile. Typically no options are
- needed.
+ Run the configure script to generate a Makefile.
+ Typically no options are needed.
+
./configure
- Options are available for more customization (use ./configure
- --help for a full list), but typically you will only need to specify
- the location of the apxs command installed by Apache httpd with
- the --with-apxs option.
+
+ Options are available for more customization (use
+ ./configure --help for a full list), but
+ typically you will only need to specify the location of the
+ apxs command installed by Apache httpd with
+ the --with-apxs option.
+
./configure
- --with-apxs=/path/to/httpd-2.x.y/bin/apxs
+ --with-apxs=/path/to/httpd-2.x.y/bin/apxs
+
- There are certain configure options that are meant for debugging an other
- development use. If enabled, these options can substantially impact performance.
- These options include all --debug-* options as well as the
- --enable-performance-measurements options.
+ There are certain configure options that are meant for
+ debugging an other development use. If enabled, these
+ options can substantially impact performance. These options
+ include all --debug-* options as well as
+ the --enable-performance-measurements
+ options.
+
Compile with: make
+
- Optionally test with: make test
+ Optionally test with: make
+ test
+
- This is step is still a bit experimental. If you have problems, please send
- the full output and error from the build to the support list. Most common issues
- are related to not finding the required headers and/or libraries.
+ This is step is still a bit experimental. If you have
+ problems, please send the full output and error from the
+ build to the support list. Most common issues are related to
+ not finding the required headers and/or libraries.
+
- Optionally build the ModSecurity Log Collector with: make
- mlogc
+ Optionally build the ModSecurity Log Collector with:
+ make mlogc
+
- Optionally install mlogc: Review the INSTALL file included in the apache2/mlogc-src directory in the
- distribution.
+ Optionally install mlogc: Review the
+ INSTALL file included in the
+ apache2/mlogc-src directory in the distribution.
+
- Install the ModSecurity module with: make install
+ Install the ModSecurity module with: make
+ install
+
Windows (MS VC++ 8)
+
- Edit Makefile.win to configure the Apache base and library
- paths.
+ Edit Makefile.win to configure the
+ Apache base and library paths.
+
- Compile with: nmake -f Makefile.win
+ Compile with: nmake -f
+ Makefile.win
+
- Install the ModSecurity module with: nmake -f Makefile.win
- install
+ Install the ModSecurity module with: nmake -f
+ Makefile.win install
+
- Copy the libxml2.dll and lua5.1.dll to
- the Apache bin directory. Alternatively you can follow the step
- below for using LoadFile to load these libraries.
+ Copy the libxml2.dll and
+ lua5.1.dll to the Apache
+ bin directory. Alternatively you can follow
+ the step below for using LoadFile to load these
+ libraries.
+
- Edit the main Apache httpd config file (usually httpd.conf)
- On UNIX (and Windows if you did not copy the DLLs as stated above) you must load
- libxml2 and lua5.1 before ModSecurity with something like this:
-
- LoadFile /usr/lib/libxml2.so
-LoadFile /usr/lib/liblua5.1.so
-
- Load the ModSecurity module
- with:LoadModule security2_module modules/mod_security2.so
+ Edit the main Apache httpd config file (usually
+ httpd.conf)
+
+ On UNIX (and Windows if you did not copy the DLLs as stated
+ above) you must load libxml2 and lua5.1 before ModSecurity with
+ something like this:
+
+ LoadFile /usr/lib/libxml2.so
+LoadFile /usr/lib/liblua5.1.so
+
+ Load the ModSecurity module with:LoadModule security2_module modules/mod_security2.so
+
Configure ModSecurity
+
Start Apache httpd
+
You should now have ModSecurity 2.x up and running.
+
- If you have compiled Apache yourself you might experience problems compiling ModSecurity
- against PCRE. This is because Apache bundles PCRE but this library is also typically
- provided by the operating system. I would expect most (all) vendor-packaged Apache
- distributions to be configured to use an external PCRE library (so this should not be a
- problem).
- You want to avoid Apache using the bundled PCRE library and ModSecurity linking against
- the one provided by the operating system. The easiest way to do this is to compile Apache
- against the PCRE library provided by the operating system (or you can compile it against the
- latest PCRE version you downloaded from the main PCRE distribution site). You can do this at
- configure time using the --with-pcre switch. If you are
- not in a position to recompile Apache, then, to compile ModSecurity successfully, you'd
- still need to have access to the bundled PCRE headers (they are available only in the Apache
- source code) and change the include path for ModSecurity (as you did in step 7 above) to
- point to them (via the --with-pcre ModSecurity configure option).
- Do note that if your Apache is using an external PCRE library you can compile
- ModSecurity with WITH_PCRE_STUDY defined,which would
- possibly give you a slight performance edge in regular expression processing.
+ If you have compiled Apache yourself you might experience problems
+ compiling ModSecurity against PCRE. This is because Apache bundles PCRE
+ but this library is also typically provided by the operating system. I
+ would expect most (all) vendor-packaged Apache distributions to be
+ configured to use an external PCRE library (so this should not be a
+ problem).
+
+ You want to avoid Apache using the bundled PCRE library and
+ ModSecurity linking against the one provided by the operating system.
+ The easiest way to do this is to compile Apache against the PCRE library
+ provided by the operating system (or you can compile it against the
+ latest PCRE version you downloaded from the main PCRE distribution
+ site). You can do this at configure time using the --with-pcre switch. If you are not in a
+ position to recompile Apache, then, to compile ModSecurity successfully,
+ you'd still need to have access to the bundled PCRE headers (they are
+ available only in the Apache source code) and change the include path
+ for ModSecurity (as you did in step 7 above) to point to them (via the
+ --with-pcre ModSecurity configure option).
+
+ Do note that if your Apache is using an external PCRE library you
+ can compile ModSecurity with WITH_PCRE_STUDY defined,which would possibly
+ give you a slight performance edge in regular expression
+ processing.
+
Configuration Directives
- The following section outlines all of the ModSecurity directives. Most of the ModSecurity
- directives can be used inside the various Apache Scope Directives such as VirtualHost, Location, LocationMatch,
- Directory, etc... There are others, however, that can only be used once
- in the main configuration file. This information is specified in the Scope sections below. The
- first version to use a given directive is given in the Version sections below.
- These rules, along with the Core rules files, should be contained is files outside of the
- httpd.conf file and called up with Apache "Include" directives. This allows for easier
- updating/migration of the rules. If you create your own custom rules that you would like to
- use with the Core rules, you should create a file called - modsecurity_crs_15_customrules.conf and place it in the same directory as the
- Core rules files. By using this file name, your custom rules will be called up after the
- standard ModSecurity Core rules configuration file but before the other Core rules. This
- allows your rules to be evaluated first which can be useful if you need to implement specific
- "allow" rules or to correct any false positives in the Core rules as they are applied to your
- site.
+
+ The following section outlines all of the ModSecurity directives.
+ Most of the ModSecurity directives can be used inside the various Apache
+ Scope Directives such as VirtualHost,
+ Location, LocationMatch,
+ Directory, etc... There are others, however, that can
+ only be used once in the main configuration file. This information is
+ specified in the Scope sections below. The first version to use a given
+ directive is given in the Version sections below.
+
+ These rules, along with the Core rules files, should be contained is
+ files outside of the httpd.conf file and called up with Apache "Include"
+ directives. This allows for easier updating/migration of the rules. If you
+ create your own custom rules that you would like to use with the Core
+ rules, you should create a file called -
+ modsecurity_crs_15_customrules.conf and place it in
+ the same directory as the Core rules files. By using this file name, your
+ custom rules will be called up after the standard ModSecurity Core rules
+ configuration file but before the other Core rules. This allows your rules
+ to be evaluated first which can be useful if you need to implement
+ specific "allow" rules or to correct any false positives in the Core rules
+ as they are applied to your site.
+
- It is highly encouraged that you do not edit the Core rules files themselves but rather
- place all changes (such as SecRuleRemoveByID, etc...) in your custom
- rules file. This will allow for easier upgrading as newer Core rules are released by Breach
- Security on the ModSecurity website.
+ It is highly encouraged that you do not edit the Core rules files
+ themselves but rather place all changes (such as
+ SecRuleRemoveByID, etc...) in your custom rules file.
+ This will allow for easier upgrading as newer Core rules are released by
+ Breach Security on the ModSecurity website.
+
SecAction
- Description: Unconditionally processes the action list it receives
- as the first and only parameter. It accepts one parameter, the syntax of which is identical
- to the third parameter of SecRule.
- Syntax:
- SecAction action1,action2,action3
- Example Usage:
- SecAction
- nolog,initcol:RESOURCE=%{REQUEST_FILENAME}
+
+ Description: Unconditionally processes the
+ action list it receives as the first and only parameter. It accepts one
+ parameter, the syntax of which is identical to the third parameter
+ of SecRule.
+
+ Syntax: SecAction
+ action1,action2,action3
+
+ Example Usage: SecAction
+ nolog,initcol:RESOURCE=%{REQUEST_FILENAME}
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
- SecAction is best used when you unconditionally execute an action. This is explicit
- triggering whereas the normal Actions are conditional based on data inspection of the
- request/response. This is a useful directive when you want to run certain actions such as
- initcol to initialize collections.
+
+ SecAction is best used when you unconditionally execute an action.
+ This is explicit triggering whereas the normal Actions are conditional
+ based on data inspection of the request/response. This is a useful
+ directive when you want to run certain actions such as
+ initcol to initialize collections.
+
SecArgumentSeparator
- Description: 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 (;).
- Syntax:
- SecArgumentSeparator character
- Example Usage:
- SecArgumentSeparator ;
+
+ Description: 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 (;).
+
+ Syntax: SecArgumentSeparator character
+
+ Example Usage: SecArgumentSeparator ;
+
Processing Phase: Any
+
Scope: Main
+
Version: 2.0.0
+
Dependencies/Notes: None
- This directive is needed if a backend web application is using a non-standard argument
- separator. If this directive is not set properly for each web application, then ModSecurity
- will not be able to parse the arguments appropriately and the effectiveness of the rule
- matching will be significantly decreased.
+
+ This directive is needed if a backend web application is using a
+ non-standard argument separator. If this directive is not set properly
+ for each web application, then ModSecurity will not be able to parse the
+ arguments appropriately and the effectiveness of the rule matching will
+ be significantly decreased.
+
SecAuditEngine
- Description: Configures the audit logging engine.
- Syntax:
- SecAuditEngine On|Off|RelevantOnly
- Example Usage:
- SecAuditEngine On
+
+ Description: Configures the audit logging
+ engine.
+
+ Syntax: SecAuditEngine On|Off|RelevantOnly
+
+ Example Usage: SecAuditEngine On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Can be set/changed with the "ctl" action for the current transaction.
- Example: The following example shows the various audit directives used together.
+
+ Dependencies/Notes: Can be set/changed with
+ the "ctl" action for the current transaction.
+
+ Example: The following example shows the various audit directives
+ used together.
+
SecAuditEngine RelevantOnly
SecAuditLog logs/audit/audit.log
SecAuditLogParts ABCFHZ
SecAuditLogType concurrent
SecAuditLogStorageDir logs/audit
SecAuditLogRelevantStatus ^(?:5|4\d[^4])
+
Possible values are:
+
- On - log all transactions by default.
+ On - log all transactions
+ by default.
+
- Off - do not log transactions by default.
+ Off - do not log
+ transactions by default.
+
- RelevantOnly - by default only log transactions
- that have triggered a warning or an error, or have a status code that is considered to
- be relevant (see SecAuditLogRelevantStatus).
+ RelevantOnly - by default
+ only log transactions that have triggered a warning or an error, or
+ have a status code that is considered to be relevant (see SecAuditLogRelevantStatus).
+
SecAuditLog
- Description: Defines the path to the main audit log file.
- Syntax:
- SecAuditLog /path/to/auditlog
- Example Usage:
- SecAuditLog /usr/local/apache/logs/audit.log
+
+ Description: Defines the path to the main
+ audit log file.
+
+ Syntax: SecAuditLog
+ /path/to/auditlog
+
+ Example Usage: SecAuditLog
+ /usr/local/apache/logs/audit.log
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This file is open on startup when the server
- typically still runs as root. You should not allow non-root users to
- have write privileges for this file or for the directory it is stored in..
- This file will be used to store the audit log entries if serial audit logging format is
- used. If concurrent audit logging format is used this file will be used as an index, and
- contain a record of all audit log files created. If you are planning to use Concurrent audit
- logging and sending your audit log data off to a remote Console host or commercial
- ModSecurity Management Appliance, then you will need to configure and use the ModSecurity
- Log Collector (mlogc) and use the following format for the audit log:
-
- SecAuditLog "|/path/to/mlogc /path/to/mlogc.conf"
-
+
+ Dependencies/Notes: This file is open on
+ startup when the server typically still runs as
+ root. You should not allow non-root users to have write
+ privileges for this file or for the directory it is stored in..
+
+ This file will be used to store the audit log entries if serial
+ audit logging format is used. If concurrent audit logging format is used
+ this file will be used as an index, and contain a record of all audit
+ log files created. If you are planning to use Concurrent audit logging
+ and sending your audit log data off to a remote Console host or
+ commercial ModSecurity Management Appliance, then you will need to
+ configure and use the ModSecurity Log Collector (mlogc) and use the
+ following format for the audit log:
+
+ SecAuditLog "|/path/to/mlogc /path/to/mlogc.conf"
+
SecAuditLog2
- Description: Defines the path to the secondary audit log index file
- when concurrent logging is enabled. See SecAuditLog2 for
- more details.
- Syntax:
- SecAuditLog2 /path/to/auditlog2
- Example Usage:
- SecAuditLog2 /usr/local/apache/logs/audit2.log
+
+ Description: Defines the path to the
+ secondary audit log index file when concurrent logging is enabled. See
+ SecAuditLog2 for more details.
+
+ Syntax: SecAuditLog2
+ /path/to/auditlog2
+
+ Example Usage: SecAuditLog2
+ /usr/local/apache/logs/audit2.log
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.1.2
- Dependencies/Notes: A main audit log must be defined via SecAuditLog before this directive may be used. Additionally,
- this log is only used for replicating the main audit log index file when concurrent audit
- logging is used. It will not be used for non-concurrent audit
- logging.
+
+ Dependencies/Notes: A main audit log must be
+ defined via SecAuditLog before this
+ directive may be used. Additionally, this log is only used for
+ replicating the main audit log index file when concurrent audit logging
+ is used. It will not be used for non-concurrent
+ audit logging.
+
SecAuditLogParts
- Description: Defines which part of each transaction are going to be
- recorded in audit log. Each part is assigned a single letter. If a letter appears in the
- list then the equivalent part of each transactions will be recorded. See below for the list
- of all parts.
- Syntax:
- SecAuditLogParts PARTS
- Example Usage:
- SecAuditLogParts ABCFHZ
+
+ Description: Defines which part of each
+ transaction are going to be recorded in audit log. Each part is assigned
+ a single letter. If a letter appears in the list then the equivalent
+ part of each transactions will be recorded. See below for the list of
+ all parts.
+
+ Syntax: SecAuditLogParts PARTS
+
+ Example Usage: SecAuditLogParts ABCFHZ
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
+
+ Dependencies/Notes: At this time ModSecurity
+ does not log response bodies of stock Apache responses (e.g. 404), or the Server and Date response headers.
+
Default: ABCFHZ.
- Please refer to the ModSecurity Data Formats document for a detailed description of
- every available part.
+
+
+ Please refer to the ModSecurity Data Formats document for a
+ detailed description of every available part.
+
+
+ Available audit log parts:
+
+
+
+ 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)
+
+
+
+ D - RESERVED for
+ intermediary response headers, not implemented yet.
+
+
+
+ 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).
+
+
+
+ G - RESERVED for the actual
+ response body, not implemented yet.
+
+
+
+ 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.
+
+
+
+ J - RESERVED. This part,
+ when implemented, will contain information about the files uploaded
+ using multipart/form-data encoding.
+
+
+
+ K - This part contains a
+ full list of every rule that matched (one per line) in the order
+ they were matched. The rules are fully qualified and will thus show
+ inherited actions and default operators. Supported as of
+ v2.5.0
+
+
+
+ Z - final boundary,
+ signifies the end of the entry (mandatory)
+
+
+
SecAuditLogRelevantStatus
- Description: Configures which response status code is to be
- considered relevant for the purpose of audit logging.
- Syntax:
- SecAuditLogRelevantStatus REGEX
- Example Usage:
- SecAuditLogRelevantStatus ^(?:5|4\d[^4])
+
+ Description: Configures which response status
+ code is to be considered relevant for the purpose of audit
+ logging.
+
+ Syntax: SecAuditLogRelevantStatus REGEX
+
+ Example Usage: SecAuditLogRelevantStatus
+ ^(?:5|4\d[^4])
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Must have the SecAuditEngine
- set to RelevantOnly. The parameter is a regular expression.
- The main purpose of this directive is to allow you to configure audit logging for only
- transactions that generate the specified HTTP Response Status Code. This directive is often
- used to the decrease the total size of the audit log file. Keep in mind that if this
- parameter is used, then successful attacks that result in a 200 OK status code will not be
- logged.
+
+ Dependencies/Notes: Must have the
+ SecAuditEngine set to
+ RelevantOnly. The parameter is a regular
+ expression.
+
+ The main purpose of this directive is to allow you to configure
+ audit logging for only transactions that generate the specified HTTP
+ Response Status Code. This directive is often used to the decrease the
+ total size of the audit log file. Keep in mind that if this parameter is
+ used, then successful attacks that result in a 200 OK status code will
+ not be logged.
+
SecAuditLogStorageDir
- Description: Configures the storage directory where concurrent
- audit log entries are to be stored.
- Syntax:
- SecAuditLogStorageDir /path/to/storage/dir
- Example Usage:
- SecAuditLogStorageDir /usr/local/apache/logs/audit
+
+ Description: Configures the storage directory
+ where concurrent audit log entries are to be stored.
+
+ Syntax: SecAuditLogStorageDir
+ /path/to/storage/dir
+
+ Example Usage: SecAuditLogStorageDir
+ /usr/local/apache/logs/audit
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: SecAuditLogType must be set to Concurrent. The
- directory must already be created before starting Apache and it must be writable by the web
- server user as new files are generated at runtime.
- As with all logging mechanisms, ensure that you specify a file system location that has
- adequate disk space and is not on the root partition.
+
+ Dependencies/Notes: SecAuditLogType must be
+ set to Concurrent. The directory must already be created before starting
+ Apache and it must be writable by the web server user as new files are
+ generated at runtime.
+
+ As with all logging mechanisms, ensure that you specify a file
+ system location that has adequate disk space and is not on the root
+ partition.
+
SecAuditLogType
- Description: Configures the type of audit logging mechanism to be
- used.
- Syntax:
- SecAuditLogType Serial|Concurrent
- Example Usage:
- SecAuditLogType Serial
+
+ Description: Configures the type of audit
+ logging mechanism to be used.
+
+ Syntax: SecAuditLogType Serial|Concurrent
+
+ Example Usage: SecAuditLogType Serial
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Must specify SecAuditLogStorageDir if you use concurrent logging.
+
+ Dependencies/Notes: Must specify
+ SecAuditLogStorageDir if you use concurrent
+ logging.
+
Possible values are:
+
- Serial - all audit log entries will be stored in
- the main audit logging file. This is more convenient for casual use but it is slower as
- only one audit log entry can be written to the file at any one file.
+ Serial - all audit log
+ entries will be stored in the main audit logging file. This is more
+ convenient for casual use but it is slower as only one audit log
+ entry can be written to the file at any one file.
+
- Concurrent - audit log entries will be stored in
- separate files, one for each transaction. Concurrent logging is the mode to use if you
- are going to send the audit log data off to a remote ModSecurity Console host.
+ Concurrent - audit log
+ entries will be stored in separate files, one for each transaction.
+ Concurrent logging is the mode to use if you are going to send the
+ audit log data off to a remote ModSecurity Console host.
+
- SecCacheTransformations (Deprecated/Experimental)
- Description: Controls caching of transformations. Caching is off by
- default starting with 2.5.6, when it was deprecated and downgraded back to
- experimental.
- Syntax:
- SecCacheTransformations On|Off [options]
- Example Usage:
- SecCacheTransformations On "minlen:64,maxlen:0"
+ SecCacheTransformations
+ (Deprecated/Experimental)
+
+ Description: Controls caching of
+ transformations. Caching is off by default starting with 2.5.6, when it
+ was deprecated and downgraded back to experimental.
+
+ Syntax: SecCacheTransformations On|Off
+ [options]
+
+ Example Usage: SecCacheTransformations On
+ "minlen:64,maxlen:0"
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: N/A
+
First parameter:
+
- On - cache transformations (per transaction, per
- phase) allowing identical transformations to be performed only once. (default)
+ On - cache transformations
+ (per transaction, per phase) allowing identical transformations to
+ be performed only once. (default)
+
- Off - do not cache any transformations, forcing
- all transformations to be performed for each rule executed.
+ Off - do not cache any
+ transformations, forcing all transformations to be performed for
+ each rule executed.
+
The following options are allowed (comma separated):
+
- incremental:on|off - enabling this option will
- cache every transformation instead of just the final transformation. (default:
- off)
+ incremental:on|off -
+ enabling this option will cache every transformation instead of just
+ the final transformation. (default: off)
+
- maxitems:N - do not allow more than N
- transformations to be cached. The cache will then be disabled. A zero value is
- interpreted as "unlimited". This option may be useful to limit caching for a form with a
- large number of ARGS. (default: 512)
+ maxitems:N - do not allow
+ more than N transformations to be cached. The cache will then be
+ disabled. A zero value is interpreted as "unlimited". This option
+ may be useful to limit caching for a form with a large number of
+ ARGS. (default: 512)
+
- minlen:N - do not cache the transformation if the
- value's length is less than N bytes. (default: 32)
+ minlen:N - do not cache the
+ transformation if the value's length is less than N bytes. (default:
+ 32)
+
- maxlen:N - do not cache the transformation if the
- value's length is more than N bytes. A zero value is interpreted as "unlimited".
- (default: 1024)
+ maxlen:N - do not cache the
+ transformation if the value's length is more than N bytes. A zero
+ value is interpreted as "unlimited". (default: 1024)
+
SecChrootDir
- Description: Configures the directory path that will be used to
- jail the web server process.
- Syntax:
- SecChrootDir /path/to/chroot/dir
- Example Usage:
- SecChrootDir /chroot
+
+ Description: Configures the directory path
+ that will be used to jail the web server process.
+
+ Syntax: SecChrootDir
+ /path/to/chroot/dir
+
+ Example Usage: SecChrootDir /chroot
+
Processing Phase: N/A
+
Scope: Main
+
Version: 2.0.0
- Dependencies/Notes: This feature is not available on Windows
- builds. The internal chroot functionality provided by ModSecurity works great for simple
- setups. One example of a simple setup is Apache serving static files only, or running
- scripts using modules.builds. Some problems you might encounter with more complex
- setups:
+
+ Dependencies/Notes: This feature is not
+ available on Windows builds. The internal chroot functionality provided
+ by ModSecurity works great for simple setups. One example of a simple
+ setup is Apache serving static files only, or running scripts using
+ modules.builds. Some problems you might encounter with more complex
+ setups:
+
- DNS lookups do not work (this is because this feature requires a shared library that
- is loaded on demand, after chroot takes place).
+ DNS lookups do not work (this is because this feature requires
+ a shared library that is loaded on demand, after chroot takes
+ place).
+
- You cannot send email from PHP because it uses sendmail and sendmail is outside the
- jail.
+ You cannot send email from PHP because it uses sendmail and
+ sendmail is outside the jail.
+
In some cases Apache graceful (reload) no longer works.
- You should be aware that the internal chroot feature might not be 100% reliable. Due to
- the large number of default and third-party modules available for the Apache web server, it
- is not possible to verify the internal chroot works reliably with all of them. A module,
- working from within Apache, can do things that make it easy to break out of the jail. In
- particular, if you are using any of the modules that fork in the module initialisation phase
- (e.g. mod_fastcgi, mod_fcgid, mod_cgid), you are advised to examine each Apache process and observe its
- current working directory, process root, and the list of open files. Consider what your
- options are and make your own decision.
+
+ You should be aware that the internal chroot feature might not be
+ 100% reliable. Due to the large number of default and third-party
+ modules available for the Apache web server, it is not possible to
+ verify the internal chroot works reliably with all of them. A module,
+ working from within Apache, can do things that make it easy to break out
+ of the jail. In particular, if you are using any of the modules that
+ fork in the module initialisation phase (e.g.
+ mod_fastcgi, mod_fcgid,
+ mod_cgid), you are advised to examine each Apache
+ process and observe its current working directory, process root, and the
+ list of open files. Consider what your options are and make your own
+ decision.
+
SecComponentSignature
- Description: Appends component signature to the ModSecurity
- signature.
- Syntax: SecComponentSignature "COMPONENT_NAME/X.Y.Z
- (COMMENT)"
- Example usage: SecComponentSignature "Core
- Rules/1.2.3"
+
+ Description: Appends component signature to
+ the ModSecurity signature.
+
+ Syntax: SecComponentSignature
+ "COMPONENT_NAME/X.Y.Z (COMMENT)"
+
+ Example usage: SecComponentSignature
+ "Core Rules/1.2.3"
+
Processing Phase: N/A
+
Scope: Main
+
Version: 2.5.0
- Dependencies/Notes: This directive should be used to make the
- presence of significant ModSecurity components known. The entire signature will be recorded
- in transaction audit log. It should be used by ModSecurity module and rule set writers to
- make debugging easier.
+
+ Dependencies/Notes: This directive should be
+ used to make the presence of significant ModSecurity components known.
+ The entire signature will be recorded in transaction audit log. It
+ should be used by ModSecurity module and rule set writers to make
+ debugging easier.
+
SecContentInjection
- Description: Enables content injection using actions append and prepend.
- Syntax:
- SecContentInjection (On|Off)
- Example Usage:
- SecContentInjection On
+
+ Description: Enables content injection using
+ actions append and prepend.
+
+ Syntax: SecContentInjection
+ (On|Off)
+
+ Example Usage: SecContentInjection
+ On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: N/A
+
SecCookieFormat
- Description: Selects the cookie format that will be used in the
- current configuration context.
- Syntax:
- SecCookieFormat 0|1
- Example Usage:
- SecCookieFormat 0
+
+ Description: Selects the cookie format that
+ will be used in the current configuration context.
+
+ Syntax: SecCookieFormat 0|1
+
+ Example Usage: SecCookieFormat 0
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
+
Possible values are:
+
- 0 - use version 0 (Netscape) cookies. This is
- what most applications use. It is the default value.
+ 0 - use version 0
+ (Netscape) cookies. This is what most applications use. It is the
+ default value.
+
- 1 - use version 1 cookies.
+ 1 - use version 1
+ cookies.
+
SecDataDir
- Description: Path where persistent data (e.g. IP address data,
- session data, etc) is to be stored.
- Syntax:
- SecDataDir /path/to/dir
- Example Usage:
- SecDataDir /usr/local/apache/logs/data
+
+ Description: Path where persistent data (e.g.
+ IP address data, session data, etc) is to be stored.
+
+ Syntax: SecDataDir
+ /path/to/dir
+
+ Example Usage: SecDataDir /usr/local/apache/logs/data
+
Processing Phase: N/A
+
Scope: Main
- Dependencies/Notes: This directive is needed when initcol, setsid
- an setuid are used. Must be writable by the web server user.
+
+ Dependencies/Notes: This directive is needed
+ when initcol, setsid an setuid are used. Must be writable by the web
+ server user.
+
SecDebugLog
- Description: Path to the ModSecurity debug log file.
- Syntax:
- SecDebugLog /path/to/modsec-debug.log
- Example Usage:
- SecDebugLog
- /usr/local/apache/logs/modsec-debug.log
+
+ Description: Path to the ModSecurity debug
+ log file.
+
+ Syntax: SecDebugLog
+ /path/to/modsec-debug.log
+
+ Example Usage: SecDebugLog
+ /usr/local/apache/logs/modsec-debug.log
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
+
SecDebugLogLevel
- Description: Configures the verboseness of the debug log
- data.
- Syntax:
- SecDebugLogLevel 0|1|2|3|4|5|6|7|8|9
- Example Usage:
- SecDebugLogLevel 4
+
+ Description: Configures the verboseness of
+ the debug log data.
+
+ Syntax: SecDebugLogLevel 0|1|2|3|4|5|6|7|8|9
+
+ Example Usage: SecDebugLogLevel 4
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Levels 1 - 3
- are always sent to the Apache error log. Therefore you can always use level 0 as the default logging level in production. Level 5 is useful when debugging. It is not advisable to use higher
- logging levels in production as excessive logging can slow down server significantly.
+
+ Dependencies/Notes: Levels 1 - 3 are always sent to the Apache error log.
+ Therefore you can always use level 0
+ as the default logging level in production. Level 5 is useful when debugging. It is not
+ advisable to use higher logging levels in production as excessive
+ logging can slow down server significantly.
+
Possible values are:
+
0 - no logging.
+
- 1 - errors (intercepted requests) only.
+ 1 - errors (intercepted
+ requests) only.
+
2 - warnings.
+
3 - notices.
+
- 4 - details of how transactions are
- handled.
+ 4 - details of how
+ transactions are handled.
+
- 5 - as above, but including information about
- each piece of information handled.
+ 5 - as above, but including
+ information about each piece of information handled.
+
- 9 - log everything, including very detailed
- debugging information.
+ 9 - log everything,
+ including very detailed debugging information.
+
SecDefaultAction
- Description: Defines the default action to take on a rule
- match.
- Syntax:
- SecDefaultAction action1,action2,action3
- Example Usage:
- SecDefaultAction
- log,auditlog,deny,status:403,phase:2
+
+ Description: Defines the default action to
+ take on a rule match.
+
+ Syntax: SecDefaultAction
+ action1,action2,action3
+
+ Example Usage: SecDefaultAction
+ log,auditlog,deny,status:403,phase:2
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Rules following a SecDefaultAction directive will inherit this setting unless a specific action
- is specified for an individual rule or until another SecDefaultAction is
- specified. Take special note that in the logging disruptive actions are not allowed, but
- this can inadvertently be inherited using a disruptive action in SecDefaultAction.
- The default value is minimal (differing from previous versions):
+
+ Dependencies/Notes: Rules following a
+ SecDefaultAction directive will inherit this setting
+ unless a specific action is specified for an individual rule or until
+ another SecDefaultAction is specified. Take special
+ note that in the logging disruptive actions are not allowed, but this
+ can inadvertently be inherited using a disruptive action in
+ SecDefaultAction.
+
+ The default value is minimal (differing from previous
+ versions):
+
SecDefaultAction phase:2,log,auditlog,pass
+
- SecDefaultAction must specify a disruptive action and a processing
- phase and cannot contain metadata actions.
+ SecDefaultAction must specify a disruptive
+ action and a processing phase and cannot contain metadata
+ actions.
+
- SecDefaultAction is not inherited across
- configuration contexts. (For an example of why this may be a problem for you, read the
- following ModSecurity Blog entry http://blog.modsecurity.org/2008/07/modsecurity-tri.html).
+ SecDefaultAction is not
+ inherited across configuration contexts. (For an example of why this
+ may be a problem for you, read the following ModSecurity Blog entry
+ http://blog.modsecurity.org/2008/07/modsecurity-tri.html).
+
SecGeoLookupDb
- Description: Defines the path to the geographical database
- file.
- Syntax:
- SecGeoLookupDb /path/to/db
- Example Usage:
- SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat
+
+ Description: Defines the path to the
+ geographical database file.
+
+ Syntax: SecGeoLookupDb /path/to/db
+
+ Example Usage: SecGeoLookupDb
+ /usr/local/geo/data/GeoLiteCity.dat
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
- Dependencies/Notes: Check out maxmind.com for
- free database files.
+
+ Dependencies/Notes: Check out
+ maxmind.com for free database files.
+
SecGuardianLog
- Description: Configuration directive to use the httpd-guardian
- script to monitor for Denial of Service (DoS) attacks.
- Syntax:
- SecGuardianLog |/path/to/httpd-guardian
- Example Usage:
- SecGuardianLog
- |/usr/local/apache/bin/httpd-guardian
+
+ Description: Configuration directive to use
+ the httpd-guardian script to monitor for Denial of Service (DoS)
+ attacks.
+
+ Syntax: SecGuardianLog |/path/to/httpd-guardian
+
+ Example Usage: SecGuardianLog
+ |/usr/local/apache/bin/httpd-guardian
+
Processing Phase: N/A
+
Scope: Main
+
Version: 2.0.0
- Dependencies/Notes: By default httpd-guardian will defend against
- clients that send more than 120 requests in a minute, or more than 360 requests in five
- minutes.
- Since 1.9, ModSecurity supports a new directive, SecGuardianLog, that is designed to
- send all access data to another program using the piped logging feature. Since Apache is
- typically deployed in a multi-process fashion, making information sharing difficult, the
- idea is to deploy a single external process to observe all requests in a stateful manner,
- providing additional protection.
- Development of a state of the art external protection tool will be a focus of subsequent
- ModSecurity releases. However, a fully functional tool is already available as part of the
- Apache httpd tools
- project. The tool is called httpd-guardian and can be used to defend against
- Denial of Service attacks. It uses the blacklist tool (from the same project) to interact
- with an iptables-based (Linux) or pf-based (*BSD) firewall, dynamically blacklisting the
- offending IP addresses. It can also interact with SnortSam (http://www.snortsam.net).
- Assuming httpd-guardian is already configured (look into the source code for the detailed
- instructions) you only need to add one line to your Apache configuration to deploy
- it:
+
+ Dependencies/Notes: By default httpd-guardian
+ will defend against clients that send more than 120 requests in a
+ minute, or more than 360 requests in five minutes.
+
+ Since 1.9, ModSecurity supports a new directive, SecGuardianLog,
+ that is designed to send all access data to another program using the
+ piped logging feature. Since Apache is typically deployed in a
+ multi-process fashion, making information sharing difficult, the idea is
+ to deploy a single external process to observe all requests in a
+ stateful manner, providing additional protection.
+
+ Development of a state of the art external protection tool will be
+ a focus of subsequent ModSecurity releases. However, a fully functional
+ tool is already available as part of the Apache httpd tools
+ project. The tool is called httpd-guardian and can be used to
+ defend against Denial of Service attacks. It uses the blacklist tool
+ (from the same project) to interact with an iptables-based (Linux) or
+ pf-based (*BSD) firewall, dynamically blacklisting the offending IP
+ addresses. It can also interact with SnortSam (http://www.snortsam.net).
+ Assuming httpd-guardian is already configured (look into the source code
+ for the detailed instructions) you only need to add one line to your
+ Apache configuration to deploy it:
+
SecGuardianLog |/path/to/httpd-guardian
+
SecMarker
- Description: Adds a fixed rule marker in the ruleset to be used as
- a target in a skipAfter action. A SecMarker directive
- essentially creates a rule that does nothing and whose only purpose it to carry the given
- ID.
- Syntax:
- SecMarker ID
- Example Usage:
- SecMarker 9999
+
+ Description: Adds a fixed rule marker in the
+ ruleset to be used as a target in a skipAfter action.
+ A SecMarker directive essentially creates a rule that
+ does nothing and whose only purpose it to carry the given ID.
+
+ Syntax: SecMarker
+ ID
+
+ Example Usage: SecMarker 9999
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
-
- SecRule REQUEST_URI "^/$" \
+
+ SecRule REQUEST_URI "^/$" \
"chain,t:none,t:urlDecode,t:lowercase,t:normalisePath,skipAfter:99"
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"
SecRule REQUEST_HEADERS:User-Agent \
@@ -850,432 +1343,662 @@ SecRule &REQUEST_HEADERS:Host "@eq 0" \
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
"log,deny,log,status:400,id:15,msg:'Request Missing an Accept Header'"
-SecMarker 99
-
+SecMarker 99
+
SecPdfProtect
- Description: Enables the PDF XSS protection functionality. Once
- enabled access to PDF files is tracked. Direct access attempts are redirected to links that
- contain one-time tokens. Requests with valid tokens are allowed through unmodified. Requests
- with invalid tokens are also allowed through but with forced download of the PDF files. This
- implementation uses response headers to detect PDF files and thus can be used with
- dynamically generated PDF files that do not have the .pdf extension in
- the request URI.
- Syntax:
- SecPdfProtect On|Off
- Example Usage:
- SecPdfProtect On
+
+ Description: Enables the PDF XSS protection
+ functionality. Once enabled access to PDF files is tracked. Direct
+ access attempts are redirected to links that contain one-time tokens.
+ Requests with valid tokens are allowed through unmodified. Requests with
+ invalid tokens are also allowed through but with forced download of the
+ PDF files. This implementation uses response headers to detect PDF files
+ and thus can be used with dynamically generated PDF files that do not
+ have the .pdf extension in the request URI.
+
+ Syntax: SecPdfProtect On|Off
+
+ Example Usage: SecPdfProtect On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
+
SecPdfProtectMethod
- Description: Configure desired protection method to be used when
- requests for PDF files are detected. Possible values are TokenRedirection
- and ForcedDownload. 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!").
- Syntax:
- SecPdfProtectMethod method
- Example Usage:
- SecPdfProtectMethod TokenRedirection
+
+ Description: Configure desired protection
+ method to be used when requests for PDF files are detected. Possible
+ values are TokenRedirection and
+ ForcedDownload. 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!").
+
+ Syntax: SecPdfProtectMethod method
+
+ Example Usage: SecPdfProtectMethod TokenRedirection
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
+
Default:
- TokenRedirection
+ TokenRedirection
+
SecPdfProtectSecret
- Description: Defines the secret that will be used to construct
- one-time tokens. You should use a reasonably long value for the secret (e.g. 16 characters
- is good). Once selected the secret should not be changed as it will break the tokens that
- were sent prior to change. But it's not a big deal even if you change it. It will just force
- download of PDF files with tokens that were issued in the last few seconds.
- Syntax:
- SecPdfProtectSecret secret
- Example Usage:
- SecPdfProtectSecret MyRandomSecretString
+
+ Description: Defines the secret that will be
+ used to construct one-time tokens. You should use a reasonably long
+ value for the secret (e.g. 16 characters is good). Once selected the
+ secret should not be changed as it will break the tokens that were sent
+ prior to change. But it's not a big deal even if you change it. It will
+ just force download of PDF files with tokens that were issued in the
+ last few seconds.
+
+ Syntax: SecPdfProtectSecret secret
+
+ Example Usage: SecPdfProtectSecret
+ MyRandomSecretString
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
+
SecPdfProtectTimeout
- Description: Defines the token timeout. After token expires it can
- no longer be used to allow access to PDF file. Request will be allowed through but the PDF
- will be delivered as attachment.
- Syntax:
- SecPdfProtectTimeout timeout
- Example Usage:
- SecPdfProtectTimeout 10
+
+ Description: Defines the token timeout. After
+ token expires it can no longer be used to allow access to PDF file.
+ Request will be allowed through but the PDF will be delivered as
+ attachment.
+
+ Syntax: SecPdfProtectTimeout timeout
+
+ Example Usage: SecPdfProtectTimeout 10
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
- Default:
- 10
+
+ Default: 10
+
SecPdfProtectTokenName
- Description: Defines the name of the token. The only reason you
- would want to change the name of the token is if you wanted to hide the fact you are running
- ModSecurity. It's a good reason but it won't really help as the adversary can look into the
- algorithm used for PDF protection and figure it out anyway. It does raise the bar slightly
- so go ahead if you want to.
- Syntax:
- SecPdfProtectTokenName name
- Example Usage:
- SecPdfProtectTokenName PDFTOKEN
+
+ Description: Defines the name of the token.
+ The only reason you would want to change the name of the token is if you
+ wanted to hide the fact you are running ModSecurity. It's a good reason
+ but it won't really help as the adversary can look into the algorithm
+ used for PDF protection and figure it out anyway. It does raise the bar
+ slightly so go ahead if you want to.
+
+ Syntax: SecPdfProtectTokenName name
+
+ Example Usage: SecPdfProtectTokenName PDFTOKEN
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
- Default:
- PDFTOKEN
+
+ Default: PDFTOKEN
+
SecRequestBodyAccess
- Description: Configures whether request bodies will be buffered and
- processed by ModSecurity by default.
- Syntax:
- SecRequestBodyAccess On|Off
- Example Usage:
- SecRequestBodyAccess On
+
+ Description: Configures whether request
+ bodies will be buffered and processed by ModSecurity by default.
+
+ Syntax: SecRequestBodyAccess On|Off
+
+ Example Usage: SecRequestBodyAccess On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive is required if you plan to
- inspect POST_PAYLOAD. This directive must be used along with the
- "phase:2" processing phase action and REQUEST_BODY variable/location. If
- any of these 3 parts are not configured, you will not be able to inspect the request
- bodies.
+
+ Dependencies/Notes: This directive is
+ required if you plan to inspect POST_PAYLOAD. This
+ directive must be used along with the "phase:2" processing phase action
+ and REQUEST_BODY variable/location. If any of these 3
+ parts are not configured, you will not be able to inspect the request
+ bodies.
+
Possible values are:
+
- On - access request bodies.
+ On - access request
+ bodies.
+
- Off - do not attempt to access request
- bodies.
+ Off - do not attempt to
+ access request bodies.
+
SecRequestBodyLimit
- Description: Configures the maximum request body size ModSecurity
- will accept for buffering.
- Syntax:
- SecRequestBodyLimit NUMBER_IN_BYTES
- Example Usage:
- SecRequestBodyLimit 134217728
+
+ Description: Configures the maximum request
+ body size ModSecurity will accept for buffering.
+
+ Syntax: SecRequestBodyLimit NUMBER_IN_BYTES
+
+ Example Usage: SecRequestBodyLimit 134217728
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: 131072 KB (134217728 bytes) is the default
- setting. Anything over this limit will be rejected with status code 413 Request Entity Too
- Large. There is a hard limit of 1 GB.
+
+ Dependencies/Notes: 131072 KB (134217728
+ bytes) is the default setting. Anything over this limit will be rejected
+ with status code 413 Request Entity Too Large. There is a hard limit of
+ 1 GB.
+
SecRequestBodyNoFilesLimit
- Description: Configures the maximum request body size ModSecurity
- will accept for buffering, excluding the size of files being transported in the request.
- This directive comes handy to further reduce susceptibility to DoS attacks when someone is
- sending request bodies of very large sizes. Web applications that require file uploads must
- configure SecRequestBodyLimit to a high value. Since large files are
- streamed to disk file uploads will not increase memory consumption. However, it's still
- possible for someone to take advantage of a large request body limit and send non-upload
- requests with large body sizes. This directive eliminates that loophole.
- Syntax:
- SecRequestBodyNoFilesLimit NUMBER_IN_BYTES
- Example Usage:
- SecRequestBodyLimit 131072
+
+ Description: Configures the maximum request
+ body size ModSecurity will accept for buffering, excluding the size of
+ files being transported in the request. This directive comes handy to
+ further reduce susceptibility to DoS attacks when someone is sending
+ request bodies of very large sizes. Web applications that require file
+ uploads must configure SecRequestBodyLimit to a high
+ value. Since large files are streamed to disk file uploads will not
+ increase memory consumption. However, it's still possible for someone to
+ take advantage of a large request body limit and send non-upload
+ requests with large body sizes. This directive eliminates that
+ loophole.
+
+ Syntax: SecRequestBodyNoFilesLimit
+ NUMBER_IN_BYTES
+
+ Example Usage: SecRequestBodyLimit 131072
+
Scope: Any
+
Version: 2.5.0
- Dependencies/Notes: 1 MB (1048576 bytes) is the default setting.
- This value is very conservative. For most applications you should be able to reduce it down
- to 128 KB or lower. Anything over the limit will be rejected with status code 413
- Request Entity Too Large. There is a hard limit of 1 GB.
+
+ Dependencies/Notes: 1 MB (1048576 bytes) is
+ the default setting. This value is very conservative. For most
+ applications you should be able to reduce it down to 128 KB or lower.
+ Anything over the limit will be rejected with status code 413
+ Request Entity Too Large. There is a hard limit of 1
+ GB.
+
SecRequestBodyInMemoryLimit
- Description: Configures the maximum request body size ModSecurity
- will store in memory.
- Syntax:
- SecRequestBodyInMemoryLimit NUMBER_IN_BYTES
- Example Usage:
- SecRequestBodyInMemoryLimit 131072
+
+ Description: Configures the maximum request
+ body size ModSecurity will store in memory.
+
+ Syntax: SecRequestBodyInMemoryLimit
+ NUMBER_IN_BYTES
+
+ Example Usage: SecRequestBodyInMemoryLimit 131072
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
+
By default the limit is 128 KB:
+
# Store up to 128 KB in memory
SecRequestBodyInMemoryLimit 131072
+
SecResponseBodyLimit
- Description: Configures the maximum response body size that will be
- accepted for buffering.
- Syntax:
- SecResponseBodyLimit NUMBER_IN_BYTES
- Example Usage:
- SecResponseBodyLimit 524228
+
+ Description: Configures the maximum response
+ body size that will be accepted for buffering.
+
+ Syntax: SecResponseBodyLimit NUMBER_IN_BYTES
+
+ Example Usage: SecResponseBodyLimit 524228
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Anything over this limit will be rejected with
- status code 500 Internal Server Error. This setting will not affect the responses with MIME
- types that are not marked for buffering. There is a hard limit of 1 GB.
+
+ Dependencies/Notes: Anything over this limit
+ will be rejected with status code 500 Internal Server Error. This
+ setting will not affect the responses with MIME types that are not
+ marked for buffering. There is a hard limit of 1 GB.
+
By default this limit is configured to 512 KB:
+
# Buffer response bodies of up to 512 KB in length
SecResponseBodyLimit 524288
+
SecResponseBodyLimitAction
- Description: Controls what happens once a response body limit,
- configured with SecResponseBodyLimit, is encountered. By default
- ModSecurity will reject a response body that is longer than specified. Some web sites,
- however, will produce very long responses making it difficult to come up with a reasonable
- limit. Such sites would have to raise the limit significantly to function properly defying
- the purpose of having the limit in the first place (to control memory consumption). With the
- ability to choose what happens once a limit is reached site administrators can choose to
- inspect only the first part of the response, the part that can fit into the desired limit,
- and let the rest through. Some could argue that allowing parts of responses to go
- uninspected is a weakness. This is true in theory but only applies to cases where the
- attacker controls the output (e.g. can make it arbitrary long). In such cases, however, it
- is not possible to prevent leakage anyway. The attacker could compress, obfuscate, or even
- encrypt data before it is sent back, and therefore bypass any monitoring device.
+
+ Description: Controls what happens once a
+ response body limit, configured with
+ SecResponseBodyLimit, is encountered. By default
+ ModSecurity will reject a response body that is longer than specified.
+ Some web sites, however, will produce very long responses making it
+ difficult to come up with a reasonable limit. Such sites would have to
+ raise the limit significantly to function properly defying the purpose
+ of having the limit in the first place (to control memory consumption).
+ With the ability to choose what happens once a limit is reached site
+ administrators can choose to inspect only the first part of the
+ response, the part that can fit into the desired limit, and let the rest
+ through. Some could argue that allowing parts of responses to go
+ uninspected is a weakness. This is true in theory but only applies to
+ cases where the attacker controls the output (e.g. can make it arbitrary
+ long). In such cases, however, it is not possible to prevent leakage
+ anyway. The attacker could compress, obfuscate, or even encrypt data
+ before it is sent back, and therefore bypass any monitoring
+ device.
+
Syntax: SecResponseBodyLimitAction
- Reject|ProcessPartial
- Example Usage: SecResponseBodyLimitAction
- ProcessPartial
+ Reject|ProcessPartial
+
+ Example Usage:
+ SecResponseBodyLimitAction ProcessPartial
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
+
SecResponseBodyMimeType
- Description: Configures which
- MIME types are to be considered for response body buffering.
- Syntax:
- SecResponseBodyMimeType mime/type
- Example Usage:
- SecResponseBodyMimeType text/plain text/html
+
+ Description: Configures which MIME types are to be considered for response
+ body buffering.
+
+ Syntax: SecResponseBodyMimeType mime/type
+
+ Example Usage: SecResponseBodyMimeType text/plain
+ text/html
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Multiple
- SecResponseBodyMimeType directives can be used to add
- MIME types.
- The default value is text/plaintext/html:
+
+ Dependencies/Notes: Multiple SecResponseBodyMimeType directives can be
+ used to add MIME types.
+
+ The default value is text/plaintext/html:
+
SecResponseBodyMimeType text/plain text/html
+
SecResponseBodyMimeTypesClear
- Description: Clears the list of MIME types considered for response body buffering, allowing you to start
- populating the list from scratch.
- Syntax:
- SecResponseBodyMimeTypesClear
- Example Usage:
- SecResponseBodyMimeTypesClear
+
+ Description: Clears the list of MIME types considered for response body
+ buffering, allowing you to start populating the list from
+ scratch.
+
+ Syntax: SecResponseBodyMimeTypesClear
+
+ Example Usage: SecResponseBodyMimeTypesClear
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
+
SecResponseBodyAccess
- Description: Configures whether response bodies are to be buffer
- and analysed or not.
- Syntax:
- SecResponseBodyAccess On|Off
- Example Usage:
- SecResponseBodyAccess On
+
+ Description: Configures whether response
+ bodies are to be buffer and analysed or not.
+
+ Syntax: SecResponseBodyAccess On|Off
+
+ Example Usage: SecResponseBodyAccess On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive is required if you plan to
- inspect HTML responses. This directive must be used along with the "phase:4" processing
- phase action and RESPONSE_BODY variable/location. If any of these 3 parts are not
- configured, you will not be able to inspect the response bodies.
+
+ Dependencies/Notes: This directive is
+ required if you plan to inspect HTML responses. This directive must be
+ used along with the "phase:4" processing phase action and RESPONSE_BODY
+ variable/location. If any of these 3 parts are not configured, you will
+ not be able to inspect the response bodies.
+
Possible values are:
+
- On - access response bodies (but only if the MIME
- type matches, see above).
+ On - access response bodies
+ (but only if the MIME type matches, see above).
+
- Off - do not attempt to access response
- bodies.
+ Off - do not attempt to
+ access response bodies.
+
SecRule
- Description:
- SecRule is the main ModSecurity directive. It is used to
- analyse data and perform actions based on the results.
- Syntax:
- SecRule VARIABLES OPERATOR [ACTIONS]
- Example Usage:
- SecRule REQUEST_URI "attack" \
- "phase:1,t:none,t:urlDecode,t:lowercase,t:normalisePath"
+
+ Description: SecRule is the main ModSecurity directive. It
+ is used to analyse data and perform actions based on the results.
+
+ Syntax: SecRule
+ VARIABLES OPERATOR [ACTIONS]
+
+ Example Usage: SecRule REQUEST_URI "attack" \
+
+
+ "phase:1,t:none,t:urlDecode,t:lowercase,t:normalisePath"
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
+
Dependencies/Notes: None
+
In general, the format of this rule is as follows:
+
SecRule VARIABLES OPERATOR [ACTIONS]
- The second part, OPERATOR, specifies how they are
- going to be checked. The third (optional) part, ACTIONS,
- specifies what to do whenever the operator used performs a successful match against a
- variable.
+
+ The second part, OPERATOR,
+ specifies how they are going to be checked. The third (optional) part,
+ ACTIONS, specifies what to do
+ whenever the operator used performs a successful match against a
+ variable.
+
Variables in rules
- The first part, VARIABLES, specifies which
- variables are to be checked. For example, the following rule will reject a transaction
- that has the word dirty in the URI:
+
+ The first part, VARIABLES,
+ specifies which variables are to be checked. For example, the
+ following rule will reject a transaction that has the word
+ dirty in the URI:
+
SecRule ARGS dirty
+
Each rule can specify one or more variables:
+
SecRule ARGS|REQUEST_HEADERS:User-Agent dirty
- There is a third format supported by the selection operator - XPath expression. XPath
- expressions can only used against the special variable XML, which is available only of the
- request body was processed as XML.
+
+ There is a third format supported by the selection operator -
+ XPath expression. XPath expressions can only used against the special
+ variable XML, which is available only of the request body was
+ processed as XML.
+
SecRule XML:/xPath/Expression dirty
+
- Not all collections support all selection operator format types. You should refer to
- the documentation of each collection to determine what is and isn't supported.
+ Not all collections support all selection operator format
+ types. You should refer to the documentation of each collection to
+ determine what is and isn't supported.
+
Collections
- A variable can contain one or many pieces of data, depending on the nature of the
- variable and the way it is used. We've seen examples of both approaches in the previous
- section. When a variable can contain more than one value we refer to it as a
- collection.
- Collections are always expanded before a rule is run. For example, the following
- rule:
+
+ A variable can contain one or many pieces of data, depending on
+ the nature of the variable and the way it is used. We've seen examples
+ of both approaches in the previous section. When a variable can
+ contain more than one value we refer to it as a
+ collection.
+
+ Collections are always expanded before a rule is run. For
+ example, the following rule:
+
SecRule ARGS dirty
+
will be expanded to:
+
SecRule ARGS:p dirty
SecRule ARGS:q dirty
- in a requests that has only two parameters, named p and q.
+
+ in a requests that has only two parameters, named
+ p and q.
+
Collections come in several flavours:
+
Read-only
+
- Created at runtime using transaction data. For example: ARGS
- (contains a list of all request parameter values) and REQUEST_HEADERS (contains a list of all request header values).
+ Created at runtime using transaction data. For example:
+ ARGS (contains a list of all request
+ parameter values) and REQUEST_HEADERS
+ (contains a list of all request header values).
+
Transient Read/Write
+
- The TX collection is created (empty) for every transaction.
- Rules can read from it and write to it (using the setvar action,
- for example), but the information stored in this collection will not survive the end
- of transaction.
+ The TX collection is created (empty)
+ for every transaction. Rules can read from it and write to it
+ (using the setvar action, for example), but
+ the information stored in this collection will not survive the
+ end of transaction.
+
Persistent Read/Write
+
- There are several collections that can be written to, but which are persisted to
- the storage backend. These collections are used to track clients across
- transactions. Examples of collections that fall into this type are IP, SESSION and USER.
+ There are several collections that can be written to, but
+ which are persisted to the storage backend. These collections
+ are used to track clients across transactions. Examples of
+ collections that fall into this type are IP,
+ SESSION and USER.
+
Operators in rules
- In the simplest possible case you will use a regular expression pattern as the second
- rule parameter. This is what we've done in the examples above. If you do this ModSecurity
- assumes you want to use the rx (regular expression)
- operator. You can also explicitly specify the operator you want to use by using @, followed by the name of an operator, at the beginning of
- the second SecRule parameter:
+
+ In the simplest possible case you will use a regular expression
+ pattern as the second rule parameter. This is what we've done in the
+ examples above. If you do this ModSecurity assumes you want to use the
+ rx (regular expression) operator.
+ You can also explicitly specify the operator you want to use by using
+ @, followed by the name of an
+ operator, at the beginning of the second SecRule
+ parameter:
+
SecRule ARGS "@rx dirty"
- Note how we had to use double quotes to delimit the second rule parameter. This is
- because the second parameter now has whitespace in it. Any number of whitespace characters
- can follow the name of the operator. If there are any non-whitespace characters there,
- they will all be treated as a special parameter to the operator. In the case of the
- regular expression operator the special parameter is the pattern that will be used for
- comparison.
- The @ can be the second character if you are using negation to negate the result
- returned by the operator:
+
+ Note how we had to use double quotes to delimit the second rule
+ parameter. This is because the second parameter now has whitespace in
+ it. Any number of whitespace characters can follow the name of the
+ operator. If there are any non-whitespace characters there, they will
+ all be treated as a special parameter to the operator. In the case of
+ the regular expression operator the special parameter is the pattern
+ that will be used for comparison.
+
+ The @ can be the second character if you are using negation to
+ negate the result returned by the operator:
+
SecRule &ARGS "!@rx ^0$"
+
Operator negation
- Operator results can be negated by using an exclamation mark at the beginning of the
- second parameter. The following rule matches if the word dirty does
- not appear in the User-Agent request
- header:
+
+ Operator results can be negated by using an exclamation mark at
+ the beginning of the second parameter. The following rule matches if
+ the word dirty does not appear
+ in the User-Agent request header:
+
SecRule REQUEST_HEADERS:User-Agent !dirty
- You can use the exclamation mark in combination with any parameter. If you do, the
- exclamation mark needs to go first, followed by the explicit operator reference. The
- following rule has the same effect as the previous example:
+
+ You can use the exclamation mark in combination with any
+ parameter. If you do, the exclamation mark needs to go first, followed
+ by the explicit operator reference. The following rule has the same
+ effect as the previous example:
+
SecRule REQUEST_HEADERS:User-Agent "!@rx dirty"
- If you need to use negation in a rule that is going to be applied to several variables
- then it may not be immediately clear what will happen. Consider the following
- example:
+
+ If you need to use negation in a rule that is going to be
+ applied to several variables then it may not be immediately clear what
+ will happen. Consider the following example:
+
SecRule ARGS:p|ARGS:q !dirty
+
The above rule is identical to:
+
SecRule ARGS:p !dirty
SecRule ARGS:q !dirty
+
- Negation is applied to operations against individual operations, not agains the
- entire variable list.
+ Negation is applied to operations against individual
+ operations, not agains the entire variable list.
+
Actions in rules
- The third parameter, ACTIONS, can be omitted only
- because there is a helper feature that specifies the default action list. If the parameter
- isn't omitted the actions specified in the parameter will be merged with the default
- action list to create the actual list of actions that will be processed on a rule
- match.
+
+ The third parameter, ACTIONS,
+ can be omitted only because there is a helper feature that specifies
+ the default action list. If the parameter isn't omitted the actions
+ specified in the parameter will be merged with the default action list
+ to create the actual list of actions that will be processed on a rule
+ match.
+
SecRuleInheritance
- Description: Configures whether the current context will inherit
- rules from the parent context (configuration options are inherited in most cases - you
- should look up the documentation for every directive to determine if it is inherited or
- not).
- Syntax:
- SecRuleInheritance On|Off
- Example Usage:
- SecRuleInheritance Off
+
+ Description: Configures whether the current
+ context will inherit rules from the parent context (configuration
+ options are inherited in most cases - you should look up the
+ documentation for every directive to determine if it is inherited or
+ not).
+
+ Syntax: SecRuleInheritance On|Off
+
+ Example Usage: SecRuleInheritance Off
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Resource-specific contexts (e.g. Location, Directory, etc)
- cannot override phase1 rules configured in the main server or in the
- virtual server. This is because phase 1 is run early in the request processing process,
- before Apache maps request to resource. Virtual host context can override phase 1 rules
- configured in the main server.
- Example: The following example shows where ModSecurity may be enabled in the main Apache
- configuration scope, however you might want to configure your VirtualHosts differently. In
- the first example, the first VirtualHost is not inheriting the ModSecurity main config
- directives and in the second one it is.
- SecRuleEnine On
+
+ Dependencies/Notes: Resource-specific
+ contexts (e.g. Location, Directory, etc) cannot override
+ phase1 rules configured in the main server or in
+ the virtual server. This is because phase 1 is run early in the request
+ processing process, before Apache maps request to resource. Virtual host
+ context can override phase 1 rules configured in the main server.
+
+ Example: The following example shows where ModSecurity may be
+ enabled in the main Apache configuration scope, however you might want
+ to configure your VirtualHosts differently. In the first example, the
+ first VirtualHost is not inheriting the ModSecurity main config
+ directives and in the second one it is.
+
+ SecRuleEngine On
SecDefaultAction log,pass,phase:2
...
@@ -1293,104 +2016,161 @@ ServerAlias www.app2.com
SecRuleInheritance On SecRule ARGS "attack"
...
</VirtualHost>
+
Possible values are:
+
- On - inherit rules from the parent
- context.
+ On - inherit rules from the
+ parent context.
+
- Off - do not inherit rules from the parent
- context.
+ Off - do not inherit rules
+ from the parent context.
+
- Configuration contexts are an Apache concept. Directives <Directory>, <Files>, <Location> and <VirtualHost> are all used
- to create configuration contexts. For more information please go to the Apache
- documentation section Configuration Sections.
+ Configuration contexts are an Apache concept. Directives
+ <Directory>,
+ <Files>,
+ <Location> and
+ <VirtualHost> are all used to create
+ configuration contexts. For more information please go to the
+ Apache documentation section Configuration
+ Sections.
+
SecRuleEngine
- Description: Configures the rules engine.
- Syntax:
- SecRuleEngine On|Off|DetectionOnly
- Example Usage:
- SecRuleEngine On
+
+ Description: Configures the rules
+ engine.
+
+ Syntax: SecRuleEngine On|Off|DetectionOnly
+
+ Example Usage: SecRuleEngine On
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive can also be controlled by the
- ctl action (ctl:ruleEngine=off) for per rule processing.
+
+ Dependencies/Notes: This directive can also
+ be controlled by the ctl action (ctl:ruleEngine=off) for per rule
+ processing.
+
Possible values are:
+
On - process rules.
+
- Off - do not process rules.
+ Off - do not process
+ rules.
+
- DetectionOnly - process rules but never intercept
- transactions, even when rules are configured to do so.
+ DetectionOnly - process
+ rules but never intercept transactions, even when rules are
+ configured to do so.
+
SecRuleRemoveById
- Description: Removes matching rules from the parent
- contexts.
- Syntax:
- SecRuleUpdateActionById RULEID ACTIONLIST
- Example Usage:
- SecRuleRemoveByID 1 2 "9000-9010"
+
+ Description: Removes matching rules from the
+ parent contexts.
+
+ Syntax: SecRuleUpdateActionById RULEID
+ ACTIONLIST
+
+ Example Usage: SecRuleRemoveByID 1 2 "9000-9010"
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive supports multiple parameters,
- where each parameter can either be a rule ID, or a range. Parameters that contain spaces
- must be delimited using double quotes.
+
+ Dependencies/Notes: This directive supports
+ multiple parameters, where each parameter can either be a rule ID, or a
+ range. Parameters that contain spaces must be delimited using double
+ quotes.
+
SecRuleRemoveById 1 2 5 10-20 "400-556" 673
+
SecRuleRemoveByMsg
- Description: Removes matching rules from the parent
- contexts.
- Syntax:
- SecRuleRemoveByMsg REGEX
- Example Usage:
- SecRuleRemoveByMsg "FAIL"
+
+ Description: Removes matching rules from the
+ parent contexts.
+
+ Syntax: SecRuleRemoveByMsg REGEX
+
+ Example Usage: SecRuleRemoveByMsg "FAIL"
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive supports multiple parameters.
- Each parameter is a regular expression that will be applied to the message (specified using
- the msg action).
+
+ Dependencies/Notes: This directive supports
+ multiple parameters. Each parameter is a regular expression that will be
+ applied to the message (specified using the msg action).
+
SecRuleScript (Experimental)
- Description: This directive creates a special rule that executes a
- Lua script to decide whether to match or not. The main difference from SecRule is that there are no targets nor operators. The script can fetch any
- variable from the ModSecurity context and use any (Lua) operator to test them. The second
- optional parameter is the list of actions whose meaning is identical to that of SecRule.
- Syntax:
- SecRuleScript /path/to/script.lua [ACTIONS]
- Example Usage:
- SecRuleScript "/path/to/file.lua" "block"
+
+ Description: This directive creates a special
+ rule that executes a Lua script to decide whether to match or not. The
+ main difference from SecRule is that there are no
+ targets nor operators. The script can fetch any variable from the
+ ModSecurity context and use any (Lua) operator to test them. The second
+ optional parameter is the list of actions whose meaning is identical to
+ that of SecRule.
+
+ Syntax: SecRuleScript
+ /path/to/script.lua [ACTIONS]
+
+ Example Usage: SecRuleScript "/path/to/file.lua"
+ "block"
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.5.0
+
Dependencies/Notes: None
+
- All Lua scripts are compiled at configuration time and cached in memory. To reload
- scripts you must reload the entire ModSecurity configuration by restarting Apache.
+ All Lua scripts are compiled at configuration time and cached in
+ memory. To reload scripts you must reload the entire ModSecurity
+ configuration by restarting Apache.
+
Example script:
+
-- Your script must define the main entry
-- point, as below.
function main()
@@ -1420,11 +2200,15 @@ function main()
-- Otherwise, simply return nil.
return nil;
end
- In this first example we were only retrieving one variable at the time. In this case the
- name of the variable is known to you. In many cases, however, you will want to examine
- variables whose names you won't know in advance, for example script parameters.
- Example showing use of m.getvars() to retrieve many variables at
- once:
+
+ In this first example we were only retrieving one variable at the
+ time. In this case the name of the variable is known to you. In many
+ cases, however, you will want to examine variables whose names you won't
+ know in advance, for example script parameters.
+
+ Example showing use of m.getvars() to retrieve
+ many variables at once:
+
function main()
-- Retrieve script parameters.
local d = m.getvars("ARGS", { "lowercase", "htmlEntityDecode" } );
@@ -1442,162 +2226,233 @@ end
-- Nothing wrong found.
return nil;
end
+
- Go to http://www.lua.org/ to find more about
- the Lua programming language. The reference manual too is available online, at http://www.lua.org/manual/5.1/.
+ Go to http://www.lua.org/ to find more
+ about the Lua programming language. The reference manual too is
+ available online, at http://www.lua.org/manual/5.1/.
+
- Lua support is marked as experimental as the way the progamming
- interface may continue to evolve while we are working for the best implementation style.
- Any user input into the programming interface is appreciated.
+ Lua support is marked as experimental as
+ the way the progamming interface may continue to evolve while we are
+ working for the best implementation style. Any user input into the
+ programming interface is appreciated.
+
SecRuleUpdateActionById
- Description: Updates the action list of the specified rule.
- Syntax:
- SecRuleUpdateActionById RULEID ACTIONLIST
- Example Usage:
- SecRuleUpdateActionById 12345 deny,status:403
+
+ Description: Updates the action list of the
+ specified rule.
+
+ Syntax: SecRuleRemoveById RULEID ACTIONLIST
+
+ Example Usage: SecRuleUpdateActionById 12345
+ deny,status:403
+
Processing Phase: Any
+
Scope: Any
+
Version: 2.5.0
- Dependencies/Notes: This directive merges the specified action list
- with the rule's action list. There are two limitations. The rule ID cannot be changed, nor
- can the phase. Further note that actions that may be specified multiple times are appended
- to the original.
+
+ Dependencies/Notes: This directive merges the
+ specified action list with the rule's action list. There are two
+ limitations. The rule ID cannot be changed, nor can the phase. Further
+ note that actions that may be specified multiple times are appended to
+ the original.
+
SecAction \
"t:lowercase,phase:2,id:12345,pass,msg:'The Message',log,auditlog"
SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new message'
- The example above will cause the rule to be executed as if it was specified as
- follows:
+
+ The example above will cause the rule to be executed as if it was
+ specified as follows:
+
SecAction \
"t:lowercase,phase:2,id:12345,log,auditlog,t:compressWhitespace,deny,status:403,msg:'A new message'"
+
SecServerSignature
- Description: Instructs ModSecurity to change the data presented in
- the Server response header token.
- Syntax:
- SecServerSignature "WEB SERVER SOFTWARE"
- Example Usage:
- SecServerSignature "Netscape-Enterprise/6.0"
+
+ Description: Instructs ModSecurity to change
+ the data presented in the "Server:" response header token.
+
+ Syntax: SecServerSignature "WEB SERVER
+ SOFTWARE"
+
+ Example Usage: SecServerSignature
+ "Netscape-Enterprise/6.0"
+
Processing Phase: N/A
+
Scope: Main
+
Version: 2.0.0
- Dependencies/Notes: In order for this directive to work, you must
- set the Apache ServerTokens directive to Full. ModSecurity will overwrite the server
- signature data held in this memory space with the data set in this directive. If
- ServerTokens is not set to Full, then the memory space is most likely not large enough to
- hold the new data we are looking to insert.
-
-
- SecStreamInspection
- Description: Controls inspection of streams. Enabled by default.
- Example: SecStreamInspection Off
- Processing Phase: N/A
- Version: 3.0.0
-
-
- SecStreamInspect
- Description:
- Example: SecStreamInspect REQUEST_BODY "@pm this that"
- log,warn,t:none
- Processing Phase: N/A; streams are processed as they become available.
- Version: 3.0.0
+
+ Dependencies/Notes: In order for this
+ directive to work, you must set the Apache ServerTokens directive to
+ Full. ModSecurity will overwrite the server signature data held in this
+ memory space with the data set in this directive. If ServerTokens is not
+ set to Full, then the memory space is most likely not large enough to
+ hold the new data we are looking to insert.
+
SecTmpDir
- Description: Configures the directory where temporary files will be
- created.
- Syntax:
- SecTmpDir /path/to/dir
- Example Usage:
- SecTmpDir /tmp
+
+ Description: Configures the directory where
+ temporary files will be created.
+
+ Syntax: SecTmpDir
+ /path/to/dir
+
+ Example Usage: SecTmpDir /tmp
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Needs to be writable by the Apache user
- process. This is the directory location where Apache will swap data to disk if it runs out
- of memory (more data than what was specified in the SecRequestBodyInMemoryLimit directive)
- during inspection.
+
+ Dependencies/Notes: Needs to be writable by
+ the Apache user process. This is the directory location where Apache
+ will swap data to disk if it runs out of memory (more data than what was
+ specified in the SecRequestBodyInMemoryLimit directive) during
+ inspection.
+
SecUploadDir
- Description: Configures the directory where intercepted files will
- be stored.
- Syntax:
- SecUploadDir /path/to/dir
- Example Usage:
- SecUploadDir /tmp
+
+ Description: Configures the directory where
+ intercepted files will be stored.
+
+ Syntax: SecUploadDir
+ /path/to/dir
+
+ Example Usage: SecUploadDir /tmp
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directory must be on the same filesystem
- as the temporary directory defined with SecTmpDir. This
- directive is used with SecUploadKeepFiles.
+
+ Dependencies/Notes: This directory must be on
+ the same filesystem as the temporary directory defined with SecTmpDir. This directive is used with
+ SecUploadKeepFiles.
+
SecUploadFileMode
- Description: Configures the mode (permissions) of any uploaded
- files using an octal number (as used in chmod).
- Syntax:
- SecUploadFileMode octal_mode|"default"
- Example Usage:
- SecUploadFileMode 0640
+
+ Description: Configures the mode
+ (permissions) of any uploaded files using an octal number (as used in
+ chmod).
+
+ Syntax: SecUploadFileMode octal_mode|"default"
+
+ Example Usage: SecUploadFileMode 0640
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.1.6
- Dependencies/Notes: This feature is not available on operating
- systems not supporting octal file modes. The default mode (0600) only grants read/write
- access to the account writing the file. If access from another account is needed (using
- clamd is a good example), then this directive may be required. However, use this directive
- with caution to avoid exposing potentially sensitive data to unauthorized users. Using the
- value "default" will revert back to the default setting.
+
+ Dependencies/Notes: This feature is not
+ available on operating systems not supporting octal file modes. The
+ default mode (0600) only grants read/write access to the account writing
+ the file. If access from another account is needed (using clamd is a
+ good example), then this directive may be required. However, use this
+ directive with caution to avoid exposing potentially sensitive data to
+ unauthorized users. Using the value "default" will revert back to the
+ default setting.
+
SecUploadKeepFiles
- Description: Configures whether or not the intercepted files will
- be kept after transaction is processed.
- Syntax:
- SecUploadKeepFiles On|Off|RelevantOnly
- Example Usage:
- SecUploadKeepFiles On
+
+ Description: Configures whether or not the
+ intercepted files will be kept after transaction is processed.
+
+ Syntax: SecUploadKeepFiles On|Off|RelevantOnly
+
+ Example Usage: SecUploadKeepFiles On
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: This directive requires the storage directory
- to be defined (using SecUploadDir).
+
+ Dependencies/Notes: This directive requires
+ the storage directory to be defined (using SecUploadDir).
+
Possible values are:
+
- On - Keep uploaded files.
+ On - Keep uploaded
+ files.
+
- Off - Do not keep uploaded files.
+ Off - Do not keep uploaded
+ files.
+
- RelevantOnly - This will keep only those files
- that belong to requests that are deemed relevant.
+ RelevantOnly - This will
+ keep only those files that belong to requests that are deemed
+ relevant.
+
SecWebAppId
- Description: Creates a partition on the server that belongs to one
- web application.
- Syntax:
- SecWebAppId "NAME"
- Example Usage:
- SecWebAppId "WebApp1"
+
+ Description: Creates a partition on the
+ server that belongs to one web application.
+
+ Syntax: SecWebAppId
+ "NAME"
+
+ Example Usage: SecWebAppId "WebApp1"
+
Processing Phase: N/A
+
Scope: Any
+
Version: 2.0.0
- Dependencies/Notes: Partitions are used to avoid collisions between
- session IDs and user IDs. This directive must be used if there are multiple applications
- deployed on the same server. If it isn't used, a collision between session IDs might occur.
- The default value is default. Example:
+
+ Dependencies/Notes: Partitions are used to
+ avoid collisions between session IDs and user IDs. This directive must
+ be used if there are multiple applications deployed on the same server.
+ If it isn't used, a collision between session IDs might occur. The
+ default value is default.
+ Example:
+
<VirtualHost *:80>
ServerName app1.com
ServerAlias www.app1.com
@@ -1615,378 +2470,533 @@ SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass
SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}
...
</VirtualHost>
- In the two examples configurations shown, SecWebAppId is being used in conjunction with
- the Apache VirtualHost directives. What this achieves is to create more unique collection
- names when being hosted on one server. Normally, when setsid is used, ModSecurity will
- create a collection with the name "SESSION" and it will hold the value specified. With using
- SecWebAppId as shown in the examples, however, the name of the collection would become
- "App1_SESSION" and "App2_SESSION".
+
+ In the two examples configurations shown, SecWebAppId is being
+ used in conjunction with the Apache VirtualHost directives. What this
+ achieves is to create more unique collection names when being hosted on
+ one server. Normally, when setsid is used, ModSecurity will create a
+ collection with the name "SESSION" and it will hold the value specified.
+ With using SecWebAppId as shown in the examples, however, the name of
+ the collection would become "App1_SESSION" and "App2_SESSION".
+
SecWebAppId is relevant in two cases:
+
- You are logging transactions/alerts to the ModSecurity Console and you want to use
- the web application ID to search only the transactions belonging to that
- application.
+ You are logging transactions/alerts to the ModSecurity Console
+ and you want to use the web application ID to search only the
+ transactions belonging to that application.
+
- You are using the data persistence facility (collections SESSION and USER) and you
- need to avoid collisions between sessions and users belonging to different
- applications.
+ You are using the data persistence facility (collections
+ SESSION and USER) and you need to avoid collisions between sessions
+ and users belonging to different applications.
+
Processing Phases
- ModSecurity 2.x allows rules to be placed in one of the following five phases:
+
+ ModSecurity 2.x allows rules to be placed in one of the following
+ five phases:
+
Request headers (REQUEST_HEADERS)
+
Request body (REQUEST_BODY)
+
Response headers (RESPONSE_HEADERS)
+
Response body (RESPONSE_BODY)
+
Logging (LOGGING)
- Below is a diagram of the standard Apache Request Cycle. In the diagram, the 5 ModSecurity
- processing phases are shown.
-
-
-
- In order to select the phase a rule executes during, use the phase action either directly
- in the rule or in using the SecDefaultAction directive:
+
+ Below is a diagram of the standard Apache Request Cycle. In the
+ diagram, the 5 ModSecurity processing phases are shown.
+
+
+
+ In order to select the phase a rule executes during, use the phase
+ action either directly in the rule or in using the
+ SecDefaultAction directive:
+
SecDefaultAction "log,pass,phase:2"
SecRule REQUEST_HEADERS:Host "!^$" "deny,phase:1"
+
- Keep in mind that rules are executed according to phases, so even if two rules are
- adjacent in a configuration file, but are set to execute in different phases, they would not
- happen one after the other. The order of rules in the configuration file is important only
- within the rules of each phase. This is especially important when using the skip and skipAfter actions.
+ Keep in mind that rules are executed according to phases, so even
+ if two rules are adjacent in a configuration file, but are set to
+ execute in different phases, they would not happen one after the other.
+ The order of rules in the configuration file is important only within
+ the rules of each phase. This is especially important when using the
+ skip and skipAfter actions.
+
- The LOGGING phase is special. It is executed at the end of each
- transaction no matter what happened in the previous phases. This means it will be processed
- even if the request was intercepted or the allow action was used to pass
- the transaction through.
+ The LOGGING phase is special. It is executed at
+ the end of each transaction no matter what happened in the previous
+ phases. This means it will be processed even if the request was
+ intercepted or the allow action was used to pass the
+ transaction through.
+
Phase Request Headers
- Rules in this phase are processed immediately after Apache completes reading the request
- headers (post-read-request phase). At this point the request body has not been read yet,
- meaning not all request arguments are available. Rules should be placed in this phase if you
- need to have them run early (before Apache does something with the request), to do something
- before the request body has been read, determine whether or not the request body should be
- buffered, or decide how you want the request body to be processed (e.g. whether to parse it
- as XML or not).
+
+ Rules in this phase are processed immediately after Apache
+ completes reading the request headers (post-read-request phase). At this
+ point the request body has not been read yet, meaning not all request
+ arguments are available. Rules should be placed in this phase if you
+ need to have them run early (before Apache does something with the
+ request), to do something before the request body has been read,
+ determine whether or not the request body should be buffered, or decide
+ how you want the request body to be processed (e.g. whether to parse it
+ as XML or not).
+
Note
- Rules in this phase can not leverage Apache scope directives (Directory, Location,
- LocationMatch, etc...) as the post-read-request hook does not have this information yet. The
- exception here is the VirtualHost directive. If you want to use ModSecurity rules inside
- Apache locations, then they should run in Phase 2. Refer to the Apache Request
- Cycle/ModSecurity Processing Phases diagram.
+
+ Rules in this phase can not leverage Apache scope directives
+ (Directory, Location, LocationMatch, etc...) as the post-read-request
+ hook does not have this information yet. The exception here is the
+ VirtualHost directive. If you want to use ModSecurity rules inside
+ Apache locations, then they should run in Phase 2. Refer to the Apache
+ Request Cycle/ModSecurity Processing Phases diagram.
+
Phase Request Body
- This is the general-purpose input analysis phase. Most of the application-oriented rules
- should go here. In this phase you are guaranteed to have received the request arguments
- (provided the request body has been read). ModSecurity supports three encoding types for the
- request body phase:
+
+ This is the general-purpose input analysis phase. Most of the
+ application-oriented rules should go here. In this phase you are
+ guaranteed to have received the request arguments (provided the request
+ body has been read). ModSecurity supports three encoding types for the
+ request body phase:
+
- application/x-www-form-urlencoded - used to transfer form
- data
+ application/x-www-form-urlencoded - used to
+ transfer form data
+
- multipart/form-data - used for file transfers
+ multipart/form-data - used for file
+ transfers
+
text/xml - used for passing XML data
+
Other encodings are not used by most web applications.
+
Phase Response Headers
- This phase takes place just before response headers are sent back to the client. Run
- here if you want to observe the response before that happens, and if you want to use the
- response headers to determine if you want to buffer the response body. Note that some
- response status codes (such as 404) are handled earlier in the request cycle by Apache and
- my not be able to be triggered as expected. Additionally, there are some response headers
- that are added by Apache at a later hook (such as Date, Server and Connection) that we would
- not be able to trigger on or sanitize. This should work appropriately in a proxy setup or
- within phase:5 (logging).
+
+ This phase takes place just before response headers are sent back
+ to the client. Run here if you want to observe the response before that
+ happens, and if you want to use the response headers to determine if you
+ want to buffer the response body. Note that some response status codes
+ (such as 404) are handled earlier in the request cycle by Apache and my
+ not be able to be triggered as expected. Additionally, there are some
+ response headers that are added by Apache at a later hook (such as Date,
+ Server and Connection) that we would not be able to trigger on or
+ sanitize. This should work appropriately in a proxy setup or within
+ phase:5 (logging).
+
Phase Response Body
- This is the general-purpose output analysis phase. At this point you can run rules
- against the response body (provided it was buffered, of course). This is the phase where you
- would want to inspect the outbound HTML for information disclosure, error messages or failed
- authentication text.
+
+ This is the general-purpose output analysis phase. At this point
+ you can run rules against the response body (provided it was buffered,
+ of course). This is the phase where you would want to inspect the
+ outbound HTML for information disclosure, error messages or failed
+ authentication text.
+
Phase Logging
- This phase is run just before logging takes place. The rules placed into this phase can
- only affect how the logging is performed. This phase can be used to inspect the error
- messages logged by Apache. You cannot deny/block connections in this phase as it is too
- late. This phase also allows for inspection of other response headers that weren't available
- during phase:3 or phase:4. Note that you must be careful not to inherit a disruptive action
- into a rule in this phase as this is a configuration error in ModSecurity 2.5.0 and later
- versions.
+
+ This phase is run just before logging takes place. The rules
+ placed into this phase can only affect how the logging is performed.
+ This phase can be used to inspect the error messages logged by Apache.
+ You cannot deny/block connections in this phase as it is too late. This
+ phase also allows for inspection of other response headers that weren't
+ available during phase:3 or phase:4. Note that you must be careful not
+ to inherit a disruptive action into a rule in this phase as this is a
+ configuration error in ModSecurity 2.5.0 and later versions.
+
Variables
+
The following variables are supported in ModSecurity 2.x:
+
ARGS
- ARGS is a collection and can be used on its own (means all arguments
- including the POST Payload), with a static parameter (matches arguments with that name), or
- with a regular expression (matches all arguments with name that matches the regular
- expression). To look at only the query string or body arguments, see the ARGS_GET and ARGS_POST collections.
- Some variables are actually collections, which are expanded into more variables at
- runtime. The following example will examine all request
- arguments:SecRule ARGS dirty
- Sometimes, however, you will want to look only at parts of a collection. This can be
- achieved with the help of the selection operator(colon). The following
- example will only look at the arguments named p (do note
- that, in general, requests can contain multiple arguments with the same name):
- SecRule ARGS:p dirty It is also
- possible to specify exclusions. The following will examine all request arguments for the
- word dirty, except the ones named z (again, there can be zero or more arguments named
- z):
- SecRule ARGS|!ARGS:z dirty There is a
- special operator that allows you to count how many variables there are in a collection. The
- following rule will trigger if there is more than zero arguments in the request (ignore the
- second parameter for the time being):
- SecRule &ARGS !^0$ And sometimes
- you need to look at an array of parameters, each with a slightly different name. In this
- case you can specify a regular expression in the selection operator itself. The following
- rule will look into all arguments whose names begin with id_:
- SecRule ARGS:/^id_/ dirty
+
+ ARGS is a collection and can be used on its own
+ (means all arguments including the POST Payload), with a static
+ parameter (matches arguments with that name), or with a regular
+ expression (matches all arguments with name that matches the regular
+ expression). To look at only the query string or body arguments, see the
+ ARGS_GET and ARGS_POST
+ collections.
+
+ Some variables are actually collections, which are expanded into
+ more variables at runtime. The following example will examine all
+ request arguments:SecRule ARGS dirty
+ Sometimes, however, you will want to look only at parts of a collection.
+ This can be achieved with the help of the selection
+ operator(colon). The following example will only look at the
+ arguments named p (do note that, in
+ general, requests can contain multiple arguments with the same name):
+ SecRule ARGS:p dirty
+ It is also possible to specify exclusions. The following will examine
+ all request arguments for the word dirty, except
+ the ones named z (again, there can be
+ zero or more arguments named z):
+ SecRule ARGS|!ARGS:z dirty
+ There is a special operator that allows you to count how many variables
+ there are in a collection. The following rule will trigger if there is
+ more than zero arguments in the request (ignore the second parameter for
+ the time being): SecRule &ARGS !^0$
+ And sometimes you need to look at an array of parameters, each with a
+ slightly different name. In this case you can specify a regular
+ expression in the selection operator itself. The following rule will
+ look into all arguments whose names begin with id_: SecRule ARGS:/^id_/ dirty
+
- Using ARGS:p will not result in any invocations against the
- operator if argument p does not exist.
- In ModSecurity 1.X, the ARGS variable stood for QUERY_STRING + POST_PAYLOAD, whereas now it expands to
- individual variables.
+ Using ARGS:p will not result in any
+ invocations against the operator if argument p does not exist.
+
+ In ModSecurity 1.X, the ARGS variable stood
+ for QUERY_STRING + POST_PAYLOAD,
+ whereas now it expands to individual variables.
+
ARGS_COMBINED_SIZE
- This variable allows you to set more targeted evaluations on the total size of the
- Arguments as compared with normal Apache LimitRequest directives. For example, you could
- create a rule to ensure that the total size of the argument data is below a certain
- threshold (to help prevent buffer overflow issues). Example: Block request if the size of
- the arguments is above 25 characters.
+
+ This variable allows you to set more targeted evaluations on the
+ total size of the Arguments as compared with normal Apache LimitRequest
+ directives. For example, you could create a rule to ensure that the
+ total size of the argument data is below a certain threshold (to help
+ prevent buffer overflow issues). Example: Block request if the size of
+ the arguments is above 25 characters.
+
SecRule REQUEST_FILENAME "^/cgi-bin/login\.php" \
"chain,log,deny,phase:2,t:none,t:lowercase,t:normalisePath"
SecRule ARGS_COMBINED_SIZE "@gt 25"
+
ARGS_NAMES
- Is a collection of the argument names. You can search for specific argument names that
- you want to block. In a positive policy scenario, you can also whitelist (using an inverted
- rule with the ! character) only authorized argument names. Example: This example rule will
- only allow 2 argument names - p and a. If any other argument names are injected, it will be
- blocked.
+
+ Is a collection of the argument names. You can search for specific
+ argument names that you want to block. In a positive policy scenario,
+ you can also whitelist (using an inverted rule with the ! character)
+ only authorized argument names. Example: This example rule will only
+ allow 2 argument names - p and a. If any other argument names are
+ injected, it will be blocked.
+
SecRule REQUEST_FILENAME "/index.php" \
"chain,log,deny,status:403,phase:2,t:none,t:lowercase,t:normalisePath"
SecRule ARGS_NAMES "!^(p|a)$" "t:none,t:lowercase"
+
ARGS_GET
- ARGS_GET is similar to ARGS, but only contains
- arguments from the query string.
+
+ ARGS_GET is similar to ARGS,
+ but only contains arguments from the query string.
+
ARGS_GET_NAMES
- ARGS_GET_NAMES is similar to ARGS_NAMES, but only
- contains argument names from the query string.
+
+ ARGS_GET_NAMES is similar to
+ ARGS_NAMES, but only contains argument names from the
+ query string.
+
ARGS_POST
- ARGS_POST is similar to ARGS, but only contains
- arguments from the POST body.
+
+ ARGS_POST is similar to
+ ARGS, but only contains arguments from the POST
+ body.
+
ARGS_POST_NAMES
- ARGS_POST_NAMES is similar to ARGS_NAMES, but only
- contains argument names from the POST body.
+
+ ARGS_POST_NAMES is similar to
+ ARGS_NAMES, but only contains argument names from the
+ POST body.
+
AUTH_TYPE
- This variable holds the authentication method used to validate a user. Example:
+
+ This variable holds the authentication method used to validate a
+ user. Example:
+
SecRule AUTH_TYPE "basic" log,deny,status:403,phase:1,t:lowercase
+
Note
- This data will not be available in a proxy-mode deployment as the authentication is not
- local. In a proxy-mode deployment, you would need to inspect the REQUEST_HEADERS:Authorization header.
+
+ This data will not be available in a proxy-mode deployment as the
+ authentication is not local. In a proxy-mode deployment, you would need
+ to inspect the REQUEST_HEADERS:Authorization
+ header.
+
ENV
- Collection, requires a single parameter (after colon). The ENV
- variable is set with setenv and does not give access to the CGI environment variables.
- Example:
+
+ Collection, requires a single parameter (after colon). The
+ ENV variable is set with setenv and does not give
+ access to the CGI environment variables. Example:
+
SecRule REQUEST_FILENAME "printenv" pass,setenv:tag=suspicious
SecRule ENV:tag "suspicious"
+
FILES
- Collection. Contains a collection of original file names (as they were called on the
- remote user's file system). Note: only available if files were extracted from the request
- body. Example:
+
+ Collection. Contains a collection of original file names (as they
+ were called on the remote user's file system). Note: only available if
+ files were extracted from the request body. Example:
+
SecRule FILES "\.conf$" log,deny,status:403,phase:2
+
FILES_COMBINED_SIZE
- Single value. Total size of the uploaded files. Note: only available if files were
- extracted from the request body. Example:
+
+ Single value. Total size of the uploaded files. Note: only
+ available if files were extracted from the request body. Example:
+
SecRule FILES_COMBINED_SIZE "@gt 1000" log,deny,status:403,phase:2
+
FILES_NAMES
- Collection w/o parameter. Contains a list of form fields that were used for file upload.
- Note: only available if files were extracted from the request body. Example:
+
+ Collection w/o parameter. Contains a list of form fields that were
+ used for file upload. Note: only available if files were extracted from
+ the request body. Example:
+
SecRule FILES_NAMES "^upfile$" log,deny,status:403,phase:2
+
FILES_SIZES
- Collection. Contains a list of file sizes. Useful for implementing a size limitation on
- individual uploaded files. Note: only available if files were extracted from the request
- body. Example:
+
+ Collection. Contains a list of file sizes. Useful for implementing
+ a size limitation on individual uploaded files. Note: only available if
+ files were extracted from the request body. Example:
+
SecRule FILES_SIZES "@gt 100" log,deny,status:403,phase:2
+
FILES_TMPNAMES
- Collection. Contains a collection of temporary files' names on the disk. Useful when
- used together with @inspectFile. Note: only available if
- files were extracted from the request body. Example:
+
+ Collection. Contains a collection of temporary files' names on the
+ disk. Useful when used together with @inspectFile. Note: only available if files
+ were extracted from the request body. Example:
+
SecRule FILES_TMPNAMES "@inspectFile /path/to/inspect_script.pl"
+
GEO
- GEO is a collection populated by the @geoLookups operator. It can be used to match geographical fields looked up by
- an IP address or hostname.
+
+ GEO is a collection populated by the @geoLookups operator. It can be used to match
+ geographical fields looked up by an IP address or hostname.
+
Available since 2.2.0.
+
Fields:
+
- COUNTRY_CODE: Two character country code. EX: US, UK,
- etc.
+ COUNTRY_CODE: Two character country code.
+ EX: US, UK, etc.
+
- COUNTRY_CODE3: Up to three character country code.
+ COUNTRY_CODE3: Up to three character
+ country code.
+
- COUNTRY_NAME: The full country name.
+ COUNTRY_NAME: The full country
+ name.
+
- COUNTRY_CONTINENT: The two character continent that the country
- is located. EX: EU
+ COUNTRY_CONTINENT: The two character
+ continent that the country is located. EX: EU
+
- REGION: The two character region. For US, this is state. For
- Canada, providence, etc.
+ REGION: The two character region. For US,
+ this is state. For Canada, providence, etc.
+
CITY: The city name.
+
POSTAL_CODE: The postal code.
+
LATITUDE: The latitude.
+
LONGITUDE: The longitude.
+
- DMA_CODE: The metropolitan area code. (US only)
+ DMA_CODE: The metropolitan area code. (US
+ only)
+
- AREA_CODE: The phone system area code. (US only)
+ AREA_CODE: The phone system area code.
+ (US only)
+
Example:
+
SecRule REMOTE_ADDR "@geoLookup" "chain,drop,msg:'Non-UK IP address'"
SecRule GEO:COUNTRY_CODE "!@streq UK"
+
HIGHEST_SEVERITY
- This variable holds the highest severity of any rules that have matched so far.
- Severities are numeric values and thus can be used with comparison operators such as
- @lt, etc.
+
+ This variable holds the highest severity of any rules that have
+ matched so far. Severities are numeric values and thus can be used with
+ comparison operators such as @lt,
+ etc.
+
Higher severities have a lower numeric value.
+
A value of 255 indicates no severity has been set.
+
SecRule HIGHEST_SEVERITY "@le 2" "phase:2,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'"
+
MATCHED_VAR
- This variable holds the value of the variable that was matched against. It is similar to
- the TX:0, except it can be used for all operators and does not require that the capture action be specified.
+
+ This variable holds the value of the variable that was matched
+ against. It is similar to the TX:0, except it can be used for all
+ operators and does not require that the capture action be specified.
+
SecRule ARGS pattern chain,deny
...
SecRule MATCHED_VAR "further scrutiny"
+
MATCHED_VAR_NAME
- This variable holds the full name of the variable that was matched against.
+
+ This variable holds the full name of the variable that was matched
+ against.
+
SecRule ARGS pattern setvar:tx.mymatch=%{MATCHED_VAR_NAME}
...
SecRule TX:MYMATCH "@eq ARGS:param" deny
+
MODSEC_BUILD
- This variable holds the ModSecurity build number. This variable is intended to be used
- to check the build number prior to using a feature that is available only in a certain
- build. Example:
+
+ This variable holds the ModSecurity build number. This variable is
+ intended to be used to check the build number prior to using a feature
+ that is available only in a certain build. Example:
+
SecRule MODSEC_BUILD "!@ge 02050102" skipAfter:12345
SecRule ARGS "@pm some key words" id:12345,deny,status:500
+
MULTIPART_CRLF_LF_LINES
- This flag variable will be set to 1 whenever a multi-part request
- uses mixed line terminators. The multipart/form-data RFC requires
- CRLF sequence to be used to terminate lines. Since some client
- implementations use only LF to terminate lines you might want to allow
- them to proceed under certain circumstances (if you want to do this you will need to stop
- using MULTIPART_STRICT_ERROR and check each multi-part flag variable
- individually, avoiding MULTIPART_LF_LINE). However, mixing CRLF and LF line terminators is dangerous as it can allow
- for evasion. Therefore, in such cases, you will have to add a check for MULTIPART_CRLF_LF_LINES.
+
+ This flag variable will be set to 1 whenever a
+ multi-part request uses mixed line terminators. The
+ multipart/form-data RFC requires
+ CRLF sequence to be used to terminate lines. Since
+ some client implementations use only LF to terminate
+ lines you might want to allow them to proceed under certain
+ circumstances (if you want to do this you will need to stop using
+ MULTIPART_STRICT_ERROR and check each multi-part flag
+ variable individually, avoiding MULTIPART_LF_LINE).
+ However, mixing CRLF and LF line
+ terminators is dangerous as it can allow for evasion. Therefore, in such
+ cases, you will have to add a check for
+ MULTIPART_CRLF_LF_LINES.
+
MULTIPART_STRICT_ERROR
- MULTIPART_STRICT_ERROR will be set to 1 when any
- of the following variables is also set to 1: REQBODY_PROCESSOR_ERROR, MULTIPART_BOUNDARY_QUOTED, MULTIPART_BOUNDARY_WHITESPACE, MULTIPART_DATA_BEFORE,
- MULTIPART_DATA_AFTER, MULTIPART_HEADER_FOLDING,
- MULTIPART_LF_LINE, MULTIPART_SEMICOLON_MISSING. Each
- of these variables covers one unusual (although sometimes legal) aspect of the request body
- in multipart/form-data format. Your policies should
- always contain a rule to check either this variable (easier) or one
- or more individual variables (if you know exactly what you want to accomplish). Depending on
- the rate of false positives and your default policy you should decide whether to block or
- just warn when the rule is triggered.
- The best way to use this variable is as in the example below:
+
+ MULTIPART_STRICT_ERROR will be set to
+ 1 when any of the following variables is also set to
+ 1: REQBODY_PROCESSOR_ERROR,
+ MULTIPART_BOUNDARY_QUOTED,
+ MULTIPART_BOUNDARY_WHITESPACE,
+ MULTIPART_DATA_BEFORE,
+ MULTIPART_DATA_AFTER,
+ MULTIPART_HEADER_FOLDING,
+ MULTIPART_LF_LINE,
+ MULTIPART_SEMICOLON_MISSING. Each of these variables
+ covers one unusual (although sometimes legal) aspect of the request body
+ in multipart/form-data format. Your policies should
+ always contain a rule to check either this variable
+ (easier) or one or more individual variables (if you know exactly what
+ you want to accomplish). Depending on the rate of false positives and
+ your default policy you should decide whether to block or just warn when
+ the rule is triggered.
+
+ The best way to use this variable is as in the example
+ below:
+
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \
failed strict validation: \
@@ -1998,354 +3008,566 @@ DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}'"
- The multipart/form-data parser was upgraded in ModSecurity v2.1.3 to
- actively look for signs of evasion. Many variables (as listed above) were added to expose
- various facts discovered during the parsing process. The MULTIPART_STRICT_ERROR variable is handy to check on all abnormalities at once.
- The individual variables allow detection to be fine-tuned according to your circumstances in
- order to reduce the number of false positives. Detailed analysis of various evasion
- techniques covered will be released as a separated document at a later date.
+
+ The multipart/form-data parser was upgraded in
+ ModSecurity v2.1.3 to actively look for signs of evasion. Many variables
+ (as listed above) were added to expose various facts discovered during
+ the parsing process. The MULTIPART_STRICT_ERROR
+ variable is handy to check on all abnormalities at once. The individual
+ variables allow detection to be fine-tuned according to your
+ circumstances in order to reduce the number of false positives. Detailed
+ analysis of various evasion techniques covered will be released as a
+ separated document at a later date.
+
MULTIPART_UNMATCHED_BOUNDARY
- Set to 1 when, during the parsing phase of a multipart/request-body, ModSecurity encounters what feels like a boundary but
- it is not. Such an event may occur when evasion of ModSecurity is attempted.
- The best way to use this variable is as in the example below:
+
+ Set to 1 when, during the parsing phase of a
+ multipart/request-body, ModSecurity encounters what
+ feels like a boundary but it is not. Such an event may occur when
+ evasion of ModSecurity is attempted.
+
+ The best way to use this variable is as in the example
+ below:
+
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
- Change the rule from blocking to logging-only if many false positives are
- encountered.
+
+ Change the rule from blocking to logging-only if many false
+ positives are encountered.
+
PATH_INFO
- Besides passing query information to a script/handler, you can also pass additional
- data, known as extra path information, as part of the URL. Example:
+
+ Besides passing query information to a script/handler, you can
+ also pass additional data, known as extra path information, as part of
+ the URL. Example:
+
SecRule PATH_INFO "^/(bin|etc|sbin|opt|usr)"
+
QUERY_STRING
- This variable holds form data passed to the script/handler by appending data after a
- question mark. Warning: Not URL-decoded. Example:
+
+ This variable holds form data passed to the script/handler by
+ appending data after a question mark. Warning: Not URL-decoded.
+ Example:
+
SecRule QUERY_STRING "attack"
+
REMOTE_ADDR
- This variable holds the IP address of the remote client. Example:
+
+ This variable holds the IP address of the remote client.
+ Example:
+
SecRule REMOTE_ADDR "^192\.168\.1\.101$"
+
REMOTE_HOST
- If HostnameLookUps are set to On, then this variable will hold the DNS resolved remote
- host name. If it is set to Off, then it will hold the remote IP address. Possible uses for
- this variable would be to deny known bad client hosts or network blocks, or conversely, to
- allow in authorized hosts. Example:
+
+ If HostnameLookUps are set to On, then this variable will hold the
+ DNS resolved remote host name. If it is set to Off, then it will hold
+ the remote IP address. Possible uses for this variable would be to deny
+ known bad client hosts or network blocks, or conversely, to allow in
+ authorized hosts. Example:
+
SecRule REMOTE_HOST "\.evil\.network\org$"
+
REMOTE_PORT
- This variable holds information on the source port that the client used when initiating
- the connection to our web server. Example: in this example, we are evaluating to see if the
- REMOTE_PORT is less than 1024, which would indicate that the user is a
- privileged user (root).
+
+ This variable holds information on the source port that the client
+ used when initiating the connection to our web server. Example: in this
+ example, we are evaluating to see if the REMOTE_PORT
+ is less than 1024, which would indicate that the user is a privileged
+ user (root).
+
SecRule REMOTE_PORT "@lt 1024" phase:1,log,pass,setenv:remote_port=privileged
+
REMOTE_USER
- This variable holds the username of the authenticated user. If there are no password
- (basic|digest) access controls in place, then this variable will be empty. Example:
+
+ This variable holds the username of the authenticated user. If
+ there are no password (basic|digest) access controls in place, then this
+ variable will be empty. Example:
+
SecRule REMOTE_USER "admin"
+
Note
- This data will not be available in a proxy-mode deployment as the authentication is not
- local.
+
+ This data will not be available in a proxy-mode deployment as the
+ authentication is not local.
+
REQBODY_PROCESSOR
- Built-in processors are URLENCODED, MULTIPART, and XML.
- Example:
+
+ Built-in processors are URLENCODED,
+ MULTIPART, and XML.
+ Example:
+
SecRule REQBODY_PROCESSOR "^XML$ chain
SecRule XML "@validateDTD /opt/apache-frontend/conf/xml.dtd"
+
- REQBODY_PROCESSOR_ERROR
- Possible values are 0 (no error) or 1 (error). This variable will be set by request body
- processors (typically the multipart/request-data parser or the XML
- parser) when they fail to properly parse a request payload.
+ REQBODY_PROCESSOR_ERROR
+
+ Possible values are 0 (no error) or 1 (error). This variable will
+ be set by request body processors (typically the
+ multipart/request-data parser or the XML parser)
+ when they fail to properly parse a request payload.
+
Example:
+
SecRule REQBODY_PROCESSOR_ERROR "@eq 1" deny,phase:2
+
- Your policies must have a rule to check REQBODY_PROCESSOR_ERROR
- at the beginning of phase 2. Failure to do so will leave the door open for impedance
- mismatch attacks. It is possible, for example, that a payload that cannot be parsed by
- ModSecurity can be successfully parsed by more tolerant parser operating in the
- application. If your policy dictates blocking then you should reject the request if error
- is detected. When operating in detection-only mode your rule should alert with high
- severity when request body processing fails.
+ Your policies must have a rule to check
+ REQBODY_PROCESSOR_ERROR at the beginning of phase 2. Failure to do so
+ will leave the door open for impedance mismatch attacks. It is
+ possible, for example, that a payload that cannot be parsed by
+ ModSecurity can be successfully parsed by more tolerant parser
+ operating in the application. If your policy dictates blocking then
+ you should reject the request if error is detected. When operating in
+ detection-only mode your rule should alert with high severity when
+ request body processing fails.
+
- REQBODY_PROCESSOR_ERROR_MSG
- Empty, or contains the error message from the processor. Example:
+ REQBODY_PROCESSOR_ERROR_MSG
+
+ Empty, or contains the error message from the processor.
+ Example:
+
SecRule REQBODY_PROCESSOR_ERROR_MSG "failed to parse" t:lowercase
+
REQUEST_BASENAME
- This variable holds just the filename part of REQUEST_FILENAME (e.g.
- index.php).
+
+ This variable holds just the filename part of
+ REQUEST_FILENAME (e.g. index.php).
+
Example:
+
SecRule REQUEST_BASENAME "^login\.php$" phase:2,t:none,t:lowercase
+
- Please note that anti-evasion transformations are not applied to this variable by
- default. REQUEST_BASENAME will recognise both / and
- \ as path separators.
+ Please note that anti-evasion transformations are not applied to
+ this variable by default. REQUEST_BASENAME will
+ recognise both / and \ as path
+ separators.
+
REQUEST_BODY
- This variable holds the data in the request body (including POST_PAYLOAD data). REQUEST_BODY should be used if the
- original order of the arguments is important (ARGS should be used in all
- other cases). Example:
+
+ This variable holds the data in the request body (including
+ POST_PAYLOAD data). REQUEST_BODY
+ should be used if the original order of the arguments is important
+ (ARGS should be used in all other cases).
+ Example:
+
SecRule REQUEST_BODY "^username=\w{25,}\&password=\w{25,}\&Submit\=login$"
+
- This variable is only available if the URLENCODED request body
- processor parsed a request body. This will occur by default when an application/x-www-form-urlencoded is detected, or the URLENCODED request body parser is forced. As of 2.5.7 it is possible to force
- the presence of the REQUEST_BODY variable, but only when there is no
- request body processor defined, using the ctl:forceRequestBodyVariable
- option in the REQUEST_HEADERS phase.
+ This variable is only available if the
+ URLENCODED request body processor parsed a request
+ body. This will occur by default when an
+ application/x-www-form-urlencoded is detected, or
+ the URLENCODED request body parser is forced. As of
+ 2.5.7 it is possible to force the presence of the
+ REQUEST_BODY variable, but only when there is no
+ request body processor defined, using the
+ ctl:forceRequestBodyVariable option in the
+ REQUEST_HEADERS phase.
+
REQUEST_COOKIES
- This variable is a collection of all of the cookie data. Example: the following example
- is using the Ampersand special operator to count how many variables are in the collection.
- In this rule, it would trigger if the request does not include any Cookie headers.
+
+ This variable is a collection of all of the cookie data. Example:
+ the following example is using the Ampersand special operator to count
+ how many variables are in the collection. In this rule, it would trigger
+ if the request does not include any Cookie headers.
+
SecRule &REQUEST_COOKIES "@eq 0"
+
REQUEST_COOKIES_NAMES
- This variable is a collection of the cookie names in the request headers. Example: the
- following rule will trigger if the JSESSIONID cookie is not present.
+
+ This variable is a collection of the cookie names in the request
+ headers. Example: the following rule will trigger if the JSESSIONID
+ cookie is not present.
+
SecRule &REQUEST_COOKIES_NAMES:JSESSIONID "@eq 0"
+
REQUEST_FILENAME
- This variable holds the relative REQUEST_URI minus the QUERY_STRING part (e.g. /index.php). Example:
+
+ This variable holds the relative REQUEST_URI
+ minus the QUERY_STRING part (e.g. /index.php).
+ Example:
+
SecRule REQUEST_FILENAME "^/cgi-bin/login\.php$" phase:2,t:none,t:normalisePath
+
- Please note that anti-evasion transformations are not used on REQUEST_FILENAME by default.
+ Please note that anti-evasion transformations are not used on
+ REQUEST_FILENAME by default.
+
REQUEST_HEADERS
- This variable can be used as either a collection of all of the request headers or can be
- used to specify individual headers (by using
- REQUEST_HEADERS:Header-Name). Example: the first example uses
- REQUEST_HEADERS as a collection and is applying the validateUrlEncoding operator against all headers.
+
+ This variable can be used as either a collection of all of the
+ request headers or can be used to specify individual headers (by using
+ REQUEST_HEADERS:Header-Name). Example: the first
+ example uses REQUEST_HEADERS as a collection and is
+ applying the validateUrlEncoding operator against all
+ headers.
+
SecRule REQUEST_HEADERS "@validateUrlEncoding"
- Example: the second example is targeting only the Host header.
+
+ Example: the second example is targeting only the
+ Host header.
+
SecRule REQUEST_HEADERS:Host "^[\d\.]+$" \
"deny,log,status:400,msg:'Host header is a numeric IP address'"
+
REQUEST_HEADERS_NAMES
- This variable is a collection of the names of all of the request headers.
- Example:
+
+ This variable is a collection of the names of all of the request
+ headers. Example:
+
SecRule REQUEST_HEADERS_NAMES "^x-forwarded-for" \
"log,deny,status:403,t:lowercase,msg:'Proxy Server Used'"
+
REQUEST_LINE
- This variable holds the complete request line sent to the server (including the
- REQUEST_METHOD and HTTP version data). Example: this example rule will trigger if the
- request method is something other than GET, HEAD, POST or if the HTTP is something other
- than HTTP/0.9, 1.0 or 1.1.
+
+ This variable holds the complete request line sent to the server
+ (including the REQUEST_METHOD and HTTP version data). Example: this
+ example rule will trigger if the request method is something other than
+ GET, HEAD, POST or if the HTTP is something other than HTTP/0.9, 1.0 or
+ 1.1.
+
SecRule REQUEST_LINE "!(^((?:(?:pos|ge)t|head))|http/(0\.9|1\.0|1\.1)$)" t:none,t:lowercase
+
REQUEST_METHOD
+
This variable holds the request method used by the client.
- The following example will trigger if the request method is either CONNECT or TRACE.
+
+ The following example will trigger if the request method is either
+ CONNECT or TRACE.
+
SecRule REQUEST_METHOD "^((?:connect|trace))$" t:none,t:lowercase
+
REQUEST_PROTOCOL
- This variable holds the request protocol version information. Example:
+
+ This variable holds the request protocol version information.
+ Example:
+
SecRule REQUEST_PROTOCOL "!^http/(0\.9|1\.0|1\.1)$" t:none,t:lowercase
+
REQUEST_URI
- This variable holds the full URL including the QUERY_STRING data
- (e.g. /index.php?p=X), however it will never contain a domain name, even if it was provided
- on the request line. It also does not include either the REQUEST_METHOD
- or the HTTP version info.
+
+ This variable holds the full URL including the
+ QUERY_STRING data (e.g. /index.php?p=X), however it
+ will never contain a domain name, even if it was provided on the request
+ line. It also does not include either the
+ REQUEST_METHOD or the HTTP version info.
+
Example:
+
SecRule REQUEST_URI "attack" phase:1,t:none,t:urlDecode,t:lowercase,t:normalisePath
+
- Please note that anti-evasion transformations are not used on REQUEST_URI by default.
+ Please note that anti-evasion transformations are not used on
+ REQUEST_URI by default.
+
REQUEST_URI_RAW
- Same as REQUEST_URI but will contain the domain name if it was
- provided on the request line (e.g. http://www.example.com/index.php?p=X).
+
+ Same as REQUEST_URI but will contain the domain
+ name if it was provided on the request line (e.g.
+ http://www.example.com/index.php?p=X).
+
Example:
+
SecRule REQUEST_URI_RAW "http:/" phase:1,t:none,t:urlDecode,t:lowercase,t:normalisePath
+
- Please note that anti-evasion transformations are not used on REQUEST_URI_RAW by default.
+ Please note that anti-evasion transformations are not used on
+ REQUEST_URI_RAW by default.
+
RESPONSE_BODY
+
This variable holds the data for the response payload.
+
Example:
+
SecRule RESPONSE_BODY "ODBC Error Code"
+
RESPONSE_CONTENT_LENGTH
- 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.) If the size is
- not known this variable will contain a zero. If RESPONSE_CONTENT_LENGTH
- contains a zero in phase 5 that means the actual size of the response body was 0.
- 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.
+
+ 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.) If the size is not known this variable
+ will contain a zero. If RESPONSE_CONTENT_LENGTH
+ contains a zero in phase 5 that means the actual size of the response
+ body was 0.
+
+ 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.
+
RESPONSE_CONTENT_TYPE
- Response content type. Only available starting with phase 3.
+
+ Response content type. Only available starting with phase
+ 3.
+
RESPONSE_HEADERS
- This variable is similar to the REQUEST_HEADERS variable and can be used in the same
- manner. Example:
+
+ This variable is similar to the REQUEST_HEADERS variable and can
+ be used in the same manner. Example:
+
SecRule RESPONSE_HEADERS:X-Cache "MISS"
+
Note
- This variable may not have access to some headers when running in embedded-mode. Headers
- such as Server, Date, Connection and Content-Type are added during a later Apache hook just
- prior to sending the data to the client. This data should be available, however, either
- during ModSecurity phase:5 (logging) or when running in proxy-mode.
+
+ This variable may not have access to some headers when running in
+ embedded-mode. Headers such as Server, Date, Connection and Content-Type
+ are added during a later Apache hook just prior to sending the data to
+ the client. This data should be available, however, either during
+ ModSecurity phase:5 (logging) or when running in proxy-mode.
+
RESPONSE_HEADERS_NAMES
- This variable is a collection of the response header names. Example:
+
+ This variable is a collection of the response header names.
+ Example:
+
SecRule RESPONSE_HEADERS_NAMES "Set-Cookie"
+
Note
- Same limitations as RESPONSE_HEADERS with regards to access to some headers in
- embedded-mode.
+
+ Same limitations as RESPONSE_HEADERS with regards to access to
+ some headers in embedded-mode.
+
RESPONSE_PROTOCOL
- This variable holds the HTTP response protocol information. Example:
+
+ This variable holds the HTTP response protocol information.
+ Example:
+
SecRule RESPONSE_PROTOCOL "^HTTP\/0\.9"
+
RESPONSE_STATUS
- This variable holds the HTTP response status code as generated by Apache.
- Example:
+
+ This variable holds the HTTP response status code as generated by
+ Apache. Example:
+
SecRule RESPONSE_STATUS "^[45]"
+
Note
- This directive may not work as expected in embedded-mode as Apache handles many of the
- stock response codes (404, 401, etc...) earlier in Phase 2. This variable should work as
- expected in a proxy-mode deployment.
+
+ This directive may not work as expected in embedded-mode as Apache
+ handles many of the stock response codes (404, 401, etc...) earlier in
+ Phase 2. This variable should work as expected in a proxy-mode
+ deployment.
+
RULE
- This variable provides access to the id, rev, severity, logdata, and msg fields of
- the rule that triggered the action. Only available for expansion in action strings
- (e.g.setvar:tx.varname=%{rule.id}). Example:
+
+ This variable provides access to the id, rev,
+ severity, logdata, and msg fields of the rule that triggered the
+ action. Only available for expansion in action strings (e.g.setvar:tx.varname=%{rule.id}). Example:
+
SecRule &REQUEST_HEADERS:Host "@eq 0" "log,deny,setvar:tx.varname=%{rule.id}"
+
SCRIPT_BASENAME
- This variable holds just the local filename part of SCRIPT_FILENAME. Example:
+
+ This variable holds just the local filename part of
+ SCRIPT_FILENAME. Example:
+
SecRule SCRIPT_BASENAME "^login\.php$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_FILENAME
- This variable holds the full path on the server to the requested script. (e.g.
- SCRIPT_NAME plus the server path). Example:
+
+ This variable holds the full path on the server to the requested
+ script. (e.g. SCRIPT_NAME plus the server path). Example:
+
SecRule SCRIPT_FILENAME "^/usr/local/apache/cgi-bin/login\.php$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_GID
- This variable holds the group id (numerical value) of the group owner of the script.
- Example:
+
+ This variable holds the group id (numerical value) of the group
+ owner of the script. Example:
+
SecRule SCRIPT_GID "!^46$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_GROUPNAME
- This variable holds the group name of the group owner of the script. Example:
+
+ This variable holds the group name of the group owner of the
+ script. Example:
+
SecRule SCRIPT_GROUPNAME "!^apache$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_MODE
- This variable holds the script's permissions mode data (numerical - 1=execute, 2=write,
- 4=read and 7=read/write/execute). Example: will trigger if the script has the WRITE
- permissions set.
+
+ This variable holds the script's permissions mode data (numerical
+ - 1=execute, 2=write, 4=read and 7=read/write/execute). Example: will
+ trigger if the script has the WRITE permissions set.
+
SecRule SCRIPT_MODE "^(2|3|6|7)$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_UID
- This variable holds the user id (numerical value) of the owner of the script. Example:
- the example rule below will trigger if the UID is not 46 (the Apache user).
+
+ This variable holds the user id (numerical value) of the owner of
+ the script. Example: the example rule below will trigger if the UID is
+ not 46 (the Apache user).
+
SecRule SCRIPT_UID "!^46$"
+
Note
+
This variable is not available in proxy mode.
+
SCRIPT_USERNAME
- This variable holds the username of the owner of the script. Example:
+
+ This variable holds the username of the owner of the script.
+ Example:
+
SecRule SCRIPT_USERNAME "!^apache$"
+
Note
+
This variable is not available in proxy mode.
+
SERVER_ADDR
- This variable contains the IP address of the server. Example:
+
+ This variable contains the IP address of the server.
+ Example:
+
SecRule SERVER_ADDR "^192\.168\.1\.100$"
+
SERVER_NAME
- This variable contains the server's hostname or IP address. Example:
+
+ This variable contains the server's hostname or IP address.
+ Example:
+
SecRule SERVER_NAME "hostname\.com$"
+
Note
- This data is taken from the Host header submitted in the client request.
+
+ This data is taken from the Host header submitted in the client
+ request.
+
SERVER_PORT
- This variable contains the local port that the web server is listening on.
- Example:
+
+ This variable contains the local port that the web server is
+ listening on. Example:
+
SecRule SERVER_PORT "^80$"
+
SESSION
- This variable is a collection, available only after setsid is executed. Example: the following example shows how to initialize a
- SESSION collection with setsid, how to use setvar to increase the session.score values, how
- to set the session.blocked variable and finally how to deny the connection based on the
- session:blocked value.
+
+ This variable is a collection, available only after setsid is executed. Example: the following
+ example shows how to initialize a SESSION collection with setsid, how to
+ use setvar to increase the session.score values, how to set the
+ session.blocked variable and finally how to deny the connection based on
+ the session:blocked value.
+
SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass
SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}
SecRule REQUEST_URI "^/cgi-bin/finger$" \
@@ -2353,115 +3575,174 @@ SecRule REQUEST_URI "^/cgi-bin/finger$" \
SecRule SESSION:SCORE "@gt 50" "pass,log,setvar:session.blocked=1"
SecRule SESSION:BLOCKED "@eq 1" "log,deny,status:403"
+
SESSIONID
- This variable is the value set with setsid.
- Example:
+
+ This variable is the value set with setsid. Example:
+
SecRule SESSIONID !^$ chain,nolog,pass
SecRule REQUEST_COOKIES:PHPSESSID !^$
SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}
+
TIME
- This variable holds a formatted string representing the time (hour:minute:second).
- Example:
+
+ This variable holds a formatted string representing the time
+ (hour:minute:second). Example:
+
SecRule TIME "^(([1](8|9))|([2](0|1|2|3))):\d{2}:\d{2}$"
+
TIME_DAY
- This variable holds the current date (1-31). Example: this rule would trigger anytime
- between the 10th and 20th days of the month.
+
+ This variable holds the current date (1-31). Example: this rule
+ would trigger anytime between the 10th and 20th days of the
+ month.
+
SecRule TIME_DAY "^(([1](0|1|2|3|4|5|6|7|8|9))|20)$"
+
TIME_EPOCH
- This variable holds the time in seconds since 1970. Example:
+
+ This variable holds the time in seconds since 1970.
+ Example:
+
SecRule TIME_EPOCH "@gt 1000"
+
TIME_HOUR
- This variable holds the current hour (0-23). Example: this rule would trigger during
- "off hours".
+
+ This variable holds the current hour (0-23). Example: this rule
+ would trigger during "off hours".
+
SecRule TIME_HOUR "^(0|1|2|3|4|5|6|[1](8|9)|[2](0|1|2|3))$"
+
TIME_MIN
- This variable holds the current minute (0-59). Example: this rule would trigger during
- the last half hour of every hour.
+
+ This variable holds the current minute (0-59). Example: this rule
+ would trigger during the last half hour of every hour.
+
SecRule TIME_MIN "^(3|4|5)"
+
TIME_MON
- This variable holds the current month (0-11). Example: this rule would match if the
- month was either November (10) or December (11).
+
+ This variable holds the current month (0-11). Example: this rule
+ would match if the month was either November (10) or December
+ (11).
+
SecRule TIME_MON "^1"
+
TIME_SEC
- This variable holds the current second count (0-59). Example:
+
+ This variable holds the current second count (0-59).
+ Example:
+
SecRule TIME_SEC "@gt 30"
+
TIME_WDAY
- This variable holds the current weekday (0-6). Example: this rule would trigger only on
- week-ends (Saturday and Sunday).
+
+ This variable holds the current weekday (0-6). Example: this rule
+ would trigger only on week-ends (Saturday and Sunday).
+
SecRule TIME_WDAY "^(0|6)$"
+
TIME_YEAR
- This variable holds the current four-digit year data. Example:
+
+ This variable holds the current four-digit year data.
+ Example:
+
SecRule TIME_YEAR "^2006$"
+
TX
- Transaction Collection. This is used to store pieces of data, create a transaction
- anomaly score, and so on. Transaction variables are set for 1 request/response cycle. The
- scoring and evaluation will not last past the current request/response process. Example: In
- this example, we are using setvar to increase the tx.score value by 5 points. We then have a
- follow-up run that will evaluate the transactional score this request and then it will
- decided whether or not to allow/deny the request through.
- The following is a list of reserved names in the TX collection:
+
+ Transaction Collection. This is used to store pieces of data,
+ create a transaction anomaly score, and so on. Transaction variables are
+ set for 1 request/response cycle. The scoring and evaluation will not
+ last past the current request/response process. Example: In this
+ example, we are using setvar to increase the tx.score value by 5 points.
+ We then have a follow-up run that will evaluate the transactional score
+ this request and then it will decided whether or not to allow/deny the
+ request through.
+
+ The following is a list of reserved names in the TX
+ collection:
+
- TX:0 - The matching value when using the @rx or @pm operator with
- the capture action.
+ TX:0 - The matching value
+ when using the @rx or @pm operator with the capture action.
+
- TX:1-TX:9 - The captured subexpression value when
- using the @rx operator with capturing parens and the
- capture action.
+ TX:1-TX:9 - The captured
+ subexpression value when using the @rx operator with capturing parens and the
+ capture action.
+
SecRule WEBSERVER_ERROR_LOG "does not exist" "phase:5,pass,setvar:tx.score=+5"
SecRule TX:SCORE "@gt 20" deny,log
+
USERID
- This variable is the value set with setuid.
- Example:
+
+ This variable is the value set with setuid. Example:
+
SecAction setuid:%{REMOTE_USER},nolog
SecRule USERID "Admin"
+
WEBAPPID
- This variable is the value set with SecWebAppId.
- Example:
+
+ This variable is the value set with SecWebAppId. Example:
+
SecWebAppId "WebApp1"
SecRule WEBAPPID "WebApp1" "chain,log,deny,status:403"
SecRule REQUEST_HEADERS:Transfer-Encoding "!^$"
+
WEBSERVER_ERROR_LOG
- Contains zero or more error messages produced by the web server. Access to this variable
- is in phase:5 (logging). Example:
+
+ Contains zero or more error messages produced by the web server.
+ Access to this variable is in phase:5 (logging). Example:
+
SecRule WEBSERVER_ERROR_LOG "File does not exist" "phase:5,setvar:tx.score=+5"
+
XML
- Can be used standalone (as a target for validateDTD and validateSchema) or with an XPath expression parameter (which makes it a valid
- target for any function that accepts plain text). Example using XPath:
+
+ Can be used standalone (as a target for
+ validateDTD and validateSchema) or
+ with an XPath expression parameter (which makes it a valid target for
+ any function that accepts plain text). Example using XPath:
+
SecDefaultAction log,deny,status:403,phase:2
SecRule REQUEST_HEADERS:Content-Type ^text/xml$ \
phase:1,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML
@@ -2469,8 +3750,10 @@ SecRule REQBODY_PROCESSOR "!^XML$" skipAfter:12345
SecRule XML:/employees/employee/name/text() Fred
SecRule XML:/xq:employees/employee/name/text() Fred \
id:12345,xmlns:xq=http://www.example.com/employees
- The first XPath expression does not use namespaces. It would match against payload such
- as this one:
+
+ The first XPath expression does not use namespaces. It would match
+ against payload such as this one:
+
<employees>
<employee>
<name>Fred Jones</name>
@@ -2491,8 +3774,10 @@ SecRule XML:/xq:employees/employee/name/text() Fred \
<phone location="mobile">(206)555-4321</phone>
</employee>
</employees>
- The second XPath expression does use namespaces. It would match the following
- payload:
+
+ The second XPath expression does use namespaces. It would match
+ the following payload:
+
<xq:employees xmlns:xq="http://www.example.com/employees">
<employee>
<name>Fred Jones</name>
@@ -2513,361 +3798,525 @@ SecRule XML:/xq:employees/employee/name/text() Fred \
<phone location="mobile">(206)555-4321</phone>
</employee>
</xq:employees>
+
Note the different namespace used in the second example.
- To learn more about XPath we suggest the following resources:
+
+ To learn more about XPath we suggest the following
+ resources:
+
- XPath Standard
+ XPath
+ Standard
+
- XPath
- Tutorial
+ XPath
+ Tutorial
+
+
Actions
+
Each action belongs to one of five groups:
+
Disruptive actions
+
- Cause ModSecurity to do something. In many cases something means block transaction,
- but not in all. For example, the allow action is classified as a disruptive action, but
- it does the opposite of blocking. There can only be one disruptive action per rule (if
- there are multiple disruptive actions present, or inherited, only the last one will take
- effect), or rule chain (in a chain, a disruptive action can only appear in the first
- rule).
+ Cause ModSecurity to do something. In many cases something
+ means block transaction, but not in all. For example, the allow
+ action is classified as a disruptive action, but it does the
+ opposite of blocking. There can only be one disruptive action per
+ rule (if there are multiple disruptive actions present, or
+ inherited, only the last one will take effect), or rule chain (in a
+ chain, a disruptive action can only appear in the first
+ rule).
+
Non-disruptive actions
+
- Do something, but that something does not and cannot affect the rule processing
- flow. Setting a variable, or changing its value is an example of a non-disruptive
- action. Non-disruptive action can appear in any rule, including each rule belonging to a
- chain.
+ Do something, but that something does not and cannot affect
+ the rule processing flow. Setting a variable, or changing its value
+ is an example of a non-disruptive action. Non-disruptive action can
+ appear in any rule, including each rule belonging to a chain.
+
Flow actions
+
- These actions affect the rule flow (for example skip or skipAfter).
+ These actions affect the rule flow (for example
+ skip or skipAfter).
+
Meta-data actions
+
- Meta-data actions are used to provide more information about rules. Examples include
- id, rev, severity and
- msg.
+ Meta-data actions are used to provide more information about
+ rules. Examples include id,
+ rev, severity and
+ msg.
+
Data actions
+
- Not really actions, these are mere containers that hold data used by other actions.
- For example, the status action holds the status that will be used for
- blocking (if it takes place).
+ Not really actions, these are mere containers that hold data
+ used by other actions. For example, the status
+ action holds the status that will be used for blocking (if it takes
+ place).
+
allow
- Description: Stops rule processing on a successful match and allows
- the transaction to proceed.
+
+ Description: Stops rule processing on a
+ successful match and allows the transaction to proceed.
+
Action Group: Disruptive
+
Example:
+
SecRule REMOTE_ADDR "^192\.168\.1\.100$" nolog,phase:1,allow
- Prior to ModSecurity 2.5 the allow action would only affect the
- current phase. An allow in phase 1 would skip processing the remaining
- rules in phase 1 but the rules from phase 2 would execute. Starting with v2.5.0 allow was enhanced to allow for fine-grained control of what is done. The
- following rules now apply:
+
+ Prior to ModSecurity 2.5 the allow action would
+ only affect the current phase. An allow in phase 1
+ would skip processing the remaining rules in phase 1 but the rules from
+ phase 2 would execute. Starting with v2.5.0 allow was
+ enhanced to allow for fine-grained control of what is done. The
+ following rules now apply:
+
- If used one its own, like in the example above, allow will affect
- the entire transaction, stopping processing of the current phase but also skipping over
- all other phases apart from the logging phase. (The logging phase is special; it is
- designed to always execute.)
+ If used one its own, like in the example above,
+ allow will affect the entire transaction,
+ stopping processing of the current phase but also skipping over all
+ other phases apart from the logging phase. (The logging phase is
+ special; it is designed to always execute.)
+
- If used with parameter "phase", allow will cause the engine to
- stop processing the current phase. Other phases will continue as normal.
+ If used with parameter "phase", allow will
+ cause the engine to stop processing the current phase. Other phases
+ will continue as normal.
+
- If used with parameter "request", allow will cause the engine to
- stop processing the current phase. The next phase to be processed will be phase RESPONSE_HEADERS.
+ If used with parameter "request", allow
+ will cause the engine to stop processing the current phase. The next
+ phase to be processed will be phase
+ RESPONSE_HEADERS.
+
Examples:
+
# Do not process request but process response.
SecAction phase:1,allow:request
# Do not process transaction (request and response).
SecAction phase:1,allow
- If you want to allow a response through, put a rule in phase RESPONSE_HEADERS and simply use allow on its own:
+
+ If you want to allow a response through, put a rule in phase
+ RESPONSE_HEADERS and simply use
+ allow on its own:
+
# Allow response through.
SecAction phase:3,allow
+
append
- Description: Appends text given as parameter to the end of response
- body. For this action to work content injection must be enabled by setting SecContentInjection to On. Also make sure you check the
- content type of the response before you make changes to it (e.g. you don't want to inject
- stuff into images).
+
+ Description: Appends text given as parameter
+ to the end of response body. For this action to work content injection
+ must be enabled by setting SecContentInjection to
+ On. Also make sure you check the content type of the
+ response before you make changes to it (e.g. you don't want to inject
+ stuff into images).
+
Action Group: Non-disruptive
+
Processing Phases: 3 and 4.
+
Example:
+
SecRule RESPONSE_CONTENT_TYPE "^text/html" "nolog,pass,append:'<hr>Footer'"
+
auditlog
- Description: Marks the transaction for logging in the audit
- log.
+
+ Description: Marks the transaction for
+ logging in the audit log.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REMOTE_ADDR "^192\.168\.1\.100$" auditlog,phase:1,allow
+
Note
- The auditlog action is now explicit if log is already specified.
+
+ The auditlog action is now explicit if log is already
+ specified.
+
block
- Description: Performs the default disruptive action.
+
+ Description: Performs the default disruptive
+ action.
+
Action Group: Disruptive
- It is intended to be used by ruleset writers to signify that the rule was intended to
- block and leaves the "how" up to the administrator. This action is currently a placeholder
- which will just be replaced by the action from the last SecDefaultAction
- in the same context. Using the block action with the SecRuleUpdateActionById directive allows a rule to be reverted back to the
- previous SecDefaultAction disruptive action.
- In future versions of ModSecurity, more control and functionality will be added to
- define "how" to block.
+
+ It is intended to be used by ruleset writers to signify that the
+ rule was intended to block and leaves the "how" up to the administrator.
+ This action is currently a placeholder which will just be replaced by
+ the action from the last SecDefaultAction in the same
+ context. Using the block action with the
+ SecRuleUpdateActionById directive allows a rule to be
+ reverted back to the previous SecDefaultAction
+ disruptive action.
+
+ In future versions of ModSecurity, more control and functionality
+ will be added to define "how" to block.
+
Examples:
- In the following example, the second rule will "deny" because of the SecDefaultAction
- disruptive action. The intent being that the administrator could easily change this to
- another disruptive action without editing the actual rules.
+
+ In the following example, the second rule will "deny" because of
+ the SecDefaultAction disruptive action. The intent being that the
+ administrator could easily change this to another disruptive action
+ without editing the actual rules.
+
### Administrator defines "how" to block (deny,status:403)...
SecDefaultAction phase:2,deny,status:403,log,auditlog
@@ -2876,11 +4325,14 @@ SecDefaultAction phase:2,deny,status:403,log,auditlog
SecRule REQUEST_HEADERS:User-Agent "perl" "phase:2,pass,msg:'Perl based user agent identified'"
# Intent is to block for this User Agent, "how" described in SecDefaultAction
SecRule REQUEST_HEADERS:User-Agent "nikto" "phase:2,block,msg:'Nikto Scanners Identified'"
- In the following example, The rule is reverted back to the pass
- action defined in the SecDefaultAction directive by using the SecRuleUpdateActionById directive in conjuction with the block action. This allows an administrator to override an action in a 3rd party
- rule without modifying the rule itself.
+
+ In the following example, The rule is reverted back to the
+ pass action defined in the SecDefaultAction directive
+ by using the SecRuleUpdateActionById directive in
+ conjuction with the block action. This allows an
+ administrator to override an action in a 3rd party rule without
+ modifying the rule itself.
+
### Administrator defines "how" to block (deny,status:403)...
SecDefaultAction phase:2,pass,log,auditlog
@@ -2890,158 +4342,238 @@ SecRule REQUEST_HEADERS:User-Agent "nikto" "id:1,phase:2,denyblock"
+
capture
- Description: When used together with the regular expression
- operator, capture action will create copies of regular expression captures and place them
- into the transaction variable collection. Up to ten captures will be copied on a successful
- pattern match, each with a name consisting of a digit from 0 to 9.
+
+ Description: When used together with the
+ regular expression operator, capture action will create copies of
+ regular expression captures and place them into the transaction variable
+ collection. Up to ten captures will be copied on a successful pattern
+ match, each with a name consisting of a digit from 0 to 9.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REQUEST_BODY "^username=(\w{25,})" phase:2,capture,t:none,chain
SecRule TX:1 "(?:(?:a(dmin|nonymous)))"
+
Note
- The 0 data captures the entire REGEX match and 1 captures the data in the first parens,
- etc...
+
+ The 0 data captures the entire REGEX match and 1 captures the data
+ in the first parens, etc...
+
chain
- Description: Chains the rule where the action is placed with the
- rule that immediately follows it. The result is called a rule chain.
- Chained rules allow for more complex rule matches where you want to use a number of
- different VARIABLES to create a better rule and to help prevent false positives.
+
+ Description: Chains the rule where the action
+ is placed with the rule that immediately follows it. The result is
+ called a rule chain. Chained rules allow for more
+ complex rule matches where you want to use a number of different
+ VARIABLES to create a better rule and to help prevent false
+ positives.
+
Action Group: Flow
+
Example:
+
# Refuse to accept POST requests that do
# not specify request body length. Do note that
# this rule should be preceeded by a rule that verifies
# only valid request methods (e.g. GET, HEAD and POST) are used.
SecRule REQUEST_METHOD ^POST$ chain,t:none
SecRule REQUEST_HEADER:Content-Length ^$ t:none
+
- In programming language concepts, think of chained rules somewhat similar to AND
- conditional statements. The actions specified in the first portion of the chained rule
- will only be triggered if all of the variable checks return positive hits. If one aspect
- of the chained rule is negative, then the entire rule chain is negative. Also note that
- disruptive actions, execution phases, metadata actions (id, rev, msg), skip and skipAfter
- actions can only be specified on by the chain starter rule.
+ In programming language concepts, think of chained rules
+ somewhat similar to AND conditional statements. The actions specified
+ in the first portion of the chained rule will only be triggered if all
+ of the variable checks return positive hits. If one aspect of the
+ chained rule is negative, then the entire rule chain is negative. Also
+ note that disruptive actions, execution phases, metadata actions (id,
+ rev, msg), skip and skipAfter actions can only be specified on by the
+ chain starter rule.
+
ctl
- Description: The ctl action allows configuration options to be
- updated for the transaction.
+
+ Description: The ctl action allows
+ configuration options to be updated for the transaction.
+
Action Group: Non-disruptive
+
Example:
+
# Parse requests with Content-Type "text/xml" as XML
SecRule REQUEST_CONTENT_TYPE ^text/xml nolog,pass,ctl:requestBodyProcessor=XML
+
Note
+
The following configuration options are supported:
+
auditEngine
+
auditLogParts
+
debugLogLevel
+
- ruleRemoveById (single rule ID, or a single rule
- ID range accepted as parameter)
+ ruleRemoveById (single rule
+ ID, or a single rule ID range accepted as parameter)
+
requestBodyAccess
+
- forceRequestBodyVariable
+ forceRequestBodyVariable
+
requestBodyLimit
+
requestBodyProcessor
+
responseBodyAccess
+
responseBodyLimit
+
ruleEngine
- With the exception of requestBodyProcessor and
- forceRequestBodyVariable, each configuration option
- corresponds to one configuration directive and the usage is identical.
- The requestBodyProcessor option allows you to configure the request
- body processor. By default ModSecurity will use the URLENCODED and MULTIPART processors to
- process an application/x-www-form-urlencoded and a
- multipart/form-data bodies, respectively. A third
- processor, XML, is also supported, but it is never used implicitly.
- Instead you must tell ModSecurity to use it by placing a few rules in the REQUEST_HEADERS processing phase. After the request body was
- processed as XML you will be able to use the XML-related features to inspect it.
- Request body processors will not interrupt a transaction if an error occurs during
- parsing. Instead they will set variables
- REQBODY_PROCESSOR_ERROR and
- REQBODY_PROCESSOR_ERROR_MSG. These variables should be inspected in the REQUEST_BODY phase and an appropriate action taken.
- The forceRequestBodyVariable option allows you to configure the
- REQUEST_BODY variable to be set when there is no request body processor
- configured. This allows for inspection of request bodies of unknown types.
+
+ With the exception of
+ requestBodyProcessor and
+ forceRequestBodyVariable, each configuration option
+ corresponds to one configuration directive and the usage is
+ identical.
+
+ The requestBodyProcessor option allows you to
+ configure the request body processor. By default ModSecurity will use
+ the URLENCODED and MULTIPART processors to process an application/x-www-form-urlencoded and a
+ multipart/form-data bodies,
+ respectively. A third processor, XML, is also
+ supported, but it is never used implicitly. Instead you must tell
+ ModSecurity to use it by placing a few rules in the REQUEST_HEADERS processing phase. After the
+ request body was processed as XML you will be able to use the
+ XML-related features to inspect it.
+
+ Request body processors will not interrupt a transaction if an
+ error occurs during parsing. Instead they will set variables REQBODY_PROCESSOR_ERROR and REQBODY_PROCESSOR_ERROR_MSG. These variables
+ should be inspected in the REQUEST_BODY phase and an appropriate action
+ taken.
+
+ The forceRequestBodyVariable option allows you
+ to configure the REQUEST_BODY variable to be set when
+ there is no request body processor configured. This allows for
+ inspection of request bodies of unknown types.
+
deny
- Description: Stops rule processing and intercepts
- transaction.
+
+ Description: Stops rule processing and
+ intercepts transaction.
+
Action Group: Disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "nikto" "log,deny,msg:'Nikto Scanners Identified'"
+
deprecatevar
- Description: Decrement counter based on its age.
+
+ Description: Decrement counter based on its
+ age.
+
Action Group: Non-Disruptive
- Example: The following example will decrement the counter by 60 every 300
- seconds.
+
+ Example: The following example will decrement the counter by 60
+ every 300 seconds.
+
SecAction deprecatevar:session.score=60/300
+
Note
- Counter values are always positive, meaning the value will never go below zero.
+
+ Counter values are always positive, meaning the value will never
+ go below zero.
+
drop
- Description: Immediately initiate a "connection close" action to
- tear down the TCP connection by sending a FIN packet.
+
+ Description: Immediately initiate a
+ "connection close" action to tear down the TCP connection by sending a
+ FIN packet.
+
Action Group: Disruptive
- Example: The following example initiates an IP collection for tracking Basic
- Authentication attempts. If the client goes over the threshold of more than 25 attempts in 2
- minutes, it will DROP subsequent connections.
+
+ Example: The following example initiates an IP collection for
+ tracking Basic Authentication attempts. If the client goes over the
+ threshold of more than 25 attempts in 2 minutes, it will DROP subsequent
+ connections.
+
SecAction initcol:ip=%{REMOTE_ADDR},nolog
SecRule ARGS:login "!^$" \
nolog,phase:1,setvar:ip.auth_attempt=+1,deprecatevar:ip.auth_attempt=20/120
SecRule IP:AUTH_ATTEMPT "@gt 25" \
log,drop,phase:1,msg:'Possible Brute Force Attack"
+
Note
- This action is currently not available on Windows based builds. This action is extremely
- useful when responding to both Brute Force and Denial of Service attacks in that, in both
- cases, you want to minimize both the network bandwidth and the data returned to the client.
- This action causes error message to appear in the log "(9)Bad file descriptor:
- core_output_filter: writing data to the network"
+
+ This action is currently not available on Windows based builds.
+ This action is extremely useful when responding to both Brute Force and
+ Denial of Service attacks in that, in both cases, you want to minimize
+ both the network bandwidth and the data returned to the client. This
+ action causes error message to appear in the log "(9)Bad file
+ descriptor: core_output_filter: writing data to the network"
+
exec
- Description: Executes an external script/binary supplied as
- parameter. As of v2.5.0, if the parameter supplied to exec is a Lua
- script (detected by the .lua extension) the script will be processed
- internally. This means you will get direct access to the internal
- request context from the script. Please read the SecRuleScript
- documentation for more details on how to write Lua scripts.
+
+ Description: Executes an external
+ script/binary supplied as parameter. As of v2.5.0, if the parameter
+ supplied to exec is a Lua script (detected by the
+ .lua extension) the script will be processed
+ internally. This means you will get direct access
+ to the internal request context from the script. Please read the
+ SecRuleScript documentation for more details on how
+ to write Lua scripts.
+
Action Group: Non-disruptive
+
Example:
+
# The following is going to execute /usr/local/apache/bin/test.sh
# as a shell script on rule match.
SecRule REQUEST_URI "^/cgi-bin/script\.pl" \
@@ -3050,574 +4582,908 @@ SecRule REQUEST_URI "^/cgi-bin/script\.pl" \
# The following is going to process /usr/local/apache/conf/exec.lua
# internally as a Lua script on rule match.
SecRule ARGS:p attack log,exec:/usr/local/apache/conf/exec.lua
+
- The exec action is executed independently from any disruptive actions. External
- scripts will always be called with no parameters. Some transaction information will be
- placed in environment variables. All the usual CGI environment variables will be there.
- You should be aware that forking a threaded process results in all threads being
- replicated in the new process. Forking can therefore incur larger overhead in
- multi-threaded operation. The script you execute must write something (anything) to
- stdout. If it doesn't ModSecurity will assume execution didn't work.
+ The exec action is executed independently from any disruptive
+ actions. External scripts will always be called with no parameters.
+ Some transaction information will be placed in environment variables.
+ All the usual CGI environment variables will be there. You should be
+ aware that forking a threaded process results in all threads being
+ replicated in the new process. Forking can therefore incur larger
+ overhead in multi-threaded operation. The script you execute must
+ write something (anything) to stdout. If it doesn't ModSecurity will
+ assume execution didn't work.
+
expirevar
- Description: Configures a collection variable to expire after the
- given time in seconds.
+
+ Description: Configures a collection variable
+ to expire after the given time in seconds.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REQUEST_COOKIES:JSESSIONID "!^$" nolog,phase:1,pass,chain
SecAction setsid:%{REQUEST_COOKIES:JSESSIONID}
SecRule REQUEST_URI "^/cgi-bin/script\.pl" \
"phase:2,t:none,t:lowercase,t:normalisePath,log,allow,\
setvar:session.suspicious=1,expirevar:session.suspicious=3600,phase:1"
+
Note
- You should use expirevar actions at the same time that you use setvar actions in order
- to keep the indented expiration time. If they are used on their own (perhaps in a SecAction
- directive) the expire time could get re-set. When variables are removed from collections,
- and there are no other changes, collections are not written to disk at the end of request.
- This is because the variables can always be expired again when the collection is read again
- on a subsequent request.
+
+ You should use expirevar actions at the same time that you use
+ setvar actions in order to keep the indented expiration time. If they
+ are used on their own (perhaps in a SecAction directive) the expire time
+ could get re-set. When variables are removed from collections, and there
+ are no other changes, collections are not written to disk at the end of
+ request. This is because the variables can always be expired again when
+ the collection is read again on a subsequent request.
+
id
- Description: Assigns a unique ID to the rule or chain.
+
+ Description: Assigns a unique ID to the rule
+ or chain.
+
Action Group: Meta-data
+
Example:
+
SecRule &REQUEST_HEADERS:Host "@eq 0" \
"log,id:60008,severity:2,msg:'Request Missing a Host Header'"
+
Note
+
These are the reserved ranges:
+
- 1-99,999; reserved for local (internal) use. Use as you see fit but do not use this
- range for rules that are distributed to others.
+ 1-99,999; reserved for local (internal) use. Use as you see
+ fit but do not use this range for rules that are distributed to
+ others.
+
- 100,000-199,999; reserved for internal use of the engine, to assign to rules that do
- not have explicit IDs.
+ 100,000-199,999; reserved for internal use of the engine, to
+ assign to rules that do not have explicit IDs.
+
- 200,000-299,999; reserved for rules published at modsecurity.org.
+ 200,000-299,999; reserved for rules published at
+ modsecurity.org.
+
- 300,000-399,999; reserved for rules published at gotroot.com.
+ 300,000-399,999; reserved for rules published at
+ gotroot.com.
+
400,000-419,999; unused (available for reservation).
+
420,000-429,999; reserved for ScallyWhack.
+ url="http://projects.otaku42.de/wiki/ScallyWhack">ScallyWhack.
+
430,000-899,999; unused (available for reservation).
+
900,000-999,999; reserved for the Core Rules project.
+ url="http://www.modsecurity.org/projects/rules/">Core Rules
+ project.
+
- 1,000,000 and above; unused (available for reservation).
+ 1,000,000 and above; unused (available for
+ reservation).
+
initcol
- Description: Initialises a named persistent collection, either by
- loading data from storage or by creating a new collection in memory.
+
+ Description: Initialises a named persistent
+ collection, either by loading data from storage or by creating a new
+ collection in memory.
+
Action Group: Non-disruptive
- Example: The following example initiates IP address tracking.
+
+ Example: The following example initiates IP address
+ tracking.
+
SecAction initcol:ip=%{REMOTE_ADDR},nolog
+
Note
- Collections are loaded into memory when the initcol action is encountered. The
- collection in storage will be persisted (and the appropriate counters increased)
- only if it was changed during transaction processing.
+
+ Collections are loaded into memory when the initcol action is
+ encountered. The collection in storage will be persisted (and the
+ appropriate counters increased) only if it was
+ changed during transaction processing.
+
See the "Persistant Storage" section for further details.
+
log
- Description: Indicates that a successful match of the rule needs to
- be logged.
+
+ Description: Indicates that a successful
+ match of the rule needs to be logged.
+
Action Group: Non-disruptive
+
Example:
+
SecAction initcol:ip=%{REMOTE_ADDR},log
+
Note
- This action will log matches to the Apache error log file and the ModSecurity audit
- log.
+
+ This action will log matches to the Apache error log file and the
+ ModSecurity audit log.
+
logdata
- Description: Allows a data fragment to be logged as part of the
- alert message.
+
+ Description: Allows a data fragment to be
+ logged as part of the alert message.
+
Action Group: Non-disruptive
+
Example:
+
SecRule &ARGS:p "@eq 0" "log,logdata:'%{TX.0}'"
+
Note
- The logdata information appears in the error and/or audit log files and is not sent back
- to the client in response headers. Macro expansion is preformed so you may use variable
- names such as %{TX.0}, etc. The information is properly escaped for use with logging binary
- data.
+
+ The logdata information appears in the error and/or audit log
+ files and is not sent back to the client in response headers. Macro
+ expansion is preformed so you may use variable names such as %{TX.0},
+ etc. The information is properly escaped for use with logging binary
+ data.
+
msg
- Description: Assigns a custom message to the rule or chain.
+
+ Description: Assigns a custom message to the
+ rule or chain.
+
Action Group: Meta-data
+
Example:
+
SecRule &REQUEST_HEADERS:Host "@eq 0" \
"log,id:60008,severity:2,msg:'Request Missing a Host Header'"
+
Note
- The msg information appears in the error and/or audit log files and is not sent back to
- the client in response headers.
+
+ The msg information appears in the error and/or audit log files
+ and is not sent back to the client in response headers.
+
multiMatch
- Description: If enabled ModSecurity will perform multiple operator
- invocations for every target, before and after every anti-evasion transformation is
- performed.
+
+ Description: If enabled ModSecurity will
+ perform multiple operator invocations for every target, before and after
+ every anti-evasion transformation is performed.
+
Action Group: Non-disruptive
+
Example:
+
SecDefaultAction log,deny,phase:1,t:removeNulls,t:lowercase
SecRule ARGS "attack" multiMatch
+
Note
- Normally, variables are evaluated once, only after all transformation functions have
- completed. With multiMatch, variables are checked against the operator before and after
- every transformation function that changes the input.
+
+ Normally, variables are evaluated once, only after all
+ transformation functions have completed. With multiMatch, variables are
+ checked against the operator before and after every transformation
+ function that changes the input.
+
noauditlog
- Description: Indicates that a successful match of the rule should
- not be used as criteria whether the transaction should be logged to the audit log.
+
+ Description: Indicates that a successful
+ match of the rule should not be used as criteria whether the transaction
+ should be logged to the audit log.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "Test" allow,noauditlog
+
Note
- If the SecAuditEngine is set to On, all of the transactions will be logged. If it is set
- to RelevantOnly, then you can control it with the noauditlog action. Even if the noauditlog
- action is applied to a specific rule and a rule either before or after triggered an audit
- event, then the transaction will be logged to the audit log. The correct way to disable
- audit logging for the entire transaction is to use "ctl:auditEngine=Off"
+
+ If the SecAuditEngine is set to On, all of the transactions will
+ be logged. If it is set to RelevantOnly, then you can control it with
+ the noauditlog action. Even if the noauditlog action is applied to a
+ specific rule and a rule either before or after triggered an audit
+ event, then the transaction will be logged to the audit log. The correct
+ way to disable audit logging for the entire transaction is to use
+ "ctl:auditEngine=Off"
+
nolog
- Description: Prevents rule matches from appearing in both the error
- and audit logs.
+
+ Description: Prevents rule matches from
+ appearing in both the error and audit logs.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "Test" allow,nolog
+
Note
+
The nolog action also implies noauditlog.
+
pass
- Description: Continues processing with the next rule in spite of a
- successful match.
+
+ Description: Continues processing with the
+ next rule in spite of a successful match.
+
Action Group: Disruptive
+
Example1:
+
SecRule REQUEST_HEADERS:User-Agent "Test" log,pass
- When using pass with SecRule with multiple targets,
- all targets will be processed and all
- non-disruptive actions will trigger for every match found. In the
- second example the TX:test target would be incremented by 1 for each matching
- argument.
+
+ When using pass with SecRule with multiple
+ targets, all targets will be processed and
+ all non-disruptive actions will trigger for
+ every match found. In the second example the
+ TX:test target would be incremented by 1 for each matching
+ argument.
+
Example2:
+
SecRule ARGS "test" log,pass,setvar:TX.test=+1
+
Note
- The transaction will not be interrupted but a log will be generated for each matching
- target (unless logging has been suppressed).
+
+ The transaction will not be interrupted but a log will be
+ generated for each matching target (unless logging has been
+ suppressed).
+
pause
- Description: Pauses transaction processing for the specified number
- of milliseconds.
+
+ Description: Pauses transaction processing
+ for the specified number of milliseconds.
+
Action Group: Non-disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "Test" log,deny,status:403,pause:5000
+
Note
- This feature can be of limited benefit for slowing down Brute Force Scanners, however
- use with care. If you are under a Denial of Service type of attack, the pause feature may
- make matters worse as this feature will cause child processes to sit idle until the pause is
- completed.
+
+ This feature can be of limited benefit for slowing down Brute
+ Force Scanners, however use with care. If you are under a Denial of
+ Service type of attack, the pause feature may make matters worse as this
+ feature will cause child processes to sit idle until the pause is
+ completed.
+
phase
- Description: Places the rule (or the rule chain) into one of five
- available processing phases.
+
+ Description: Places the rule (or the rule
+ chain) into one of five available processing phases.
+
Action Group: Meta-data
+
Example:
+
SecDefaultAction log,deny,phase:1,t:removeNulls,t:lowercase
SecRule REQUEST_HEADERS:User-Agent "Test" log,deny,status:403
+
Note
- Keep in mind that is you specify the incorrect phase, the target variable that you
- specify may be empty. This could lead to a false negative situation where your variable and
- operator (RegEx) may be correct, but it misses malicious data because you specified the
- wrong phase.
+
+ Keep in mind that is you specify the incorrect phase, the target
+ variable that you specify may be empty. This could lead to a false
+ negative situation where your variable and operator (RegEx) may be
+ correct, but it misses malicious data because you specified the wrong
+ phase.
+
prepend
- Description: Prepends text given as parameter to the response body.
- For this action to work content injection must be enabled by setting SecContentInjection to On. Also make sure you check the
- content type of the response before you make changes to it (e.g. you don't want to inject
- stuff into images).
+
+ Description: Prepends text given as parameter
+ to the response body. For this action to work content injection must be
+ enabled by setting SecContentInjection to
+ On. Also make sure you check the content type of the
+ response before you make changes to it (e.g. you don't want to inject
+ stuff into images).
+
Action Group: Non-disruptive
+
Processing Phases: 3 and 4.
+
Example:
+
SecRule RESPONSE_CONTENT_TYPE ^text/html "phase:3,nolog,pass,prepend:'Header<br>'"
+
proxy
- Description: Intercepts transaction by forwarding request to
- another web server using the proxy backend.
+
+ Description: Intercepts transaction by
+ forwarding request to another web server using the proxy backend.
+
Action Group: Disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "Test" log,proxy:http://www.honeypothost.com/
+
Note
- For this action to work, mod_proxy must also be installed. This action is useful if you
- would like to proxy matching requests onto a honeypot webserver.
+
+ For this action to work, mod_proxy must also be installed. This
+ action is useful if you would like to proxy matching requests onto a
+ honeypot webserver.
+
redirect
- Description: Intercepts transaction by issuing a redirect to the
- given location.
+
+ Description: Intercepts transaction by
+ issuing a redirect to the given location.
+
Action Group: Disruptive
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "Test" \
log,redirect:http://www.hostname.com/failed.html
+
Note
- If the status action is present and its value is
- acceptable (301, 302, 303, or 307) it will be used for the redirection. Otherwise status
- code 302 will be used.
+
+ If the status action is present
+ and its value is acceptable (301, 302, 303, or 307) it will be used for
+ the redirection. Otherwise status code 302 will be used.
+
rev
+
Description: Specifies rule revision.
+
Action Group: Meta-data
+
Example:
+
SecRule REQUEST_METHOD "^PUT$" "id:340002,rev:1,severity:2,msg:'Restricted HTTP function'"
+
Note
- This action is used in combination with the id action
- to allow the same rule ID to be used after changes take place but to still provide some
- indication the rule changed.
+
+ This action is used in combination with the id action to allow the same rule ID to be used
+ after changes take place but to still provide some indication the rule
+ changed.
+
sanitiseArg
- Description: Sanitises (replaces each byte with an asterisk) a
- named request argument prior to audit logging.
+
+ Description: Sanitises (replaces each byte
+ with an asterisk) a named request argument prior to audit
+ logging.
+
Action Group: Non-disruptive
+
Example:
+
SecAction nolog,phase:2,sanitiseArg:password
+
Note
- The sanitize actions do not sanitize any data within the actual raw requests but only on
- the copy of data within memory that is set to log to the audit log. It will not sanitize the
- data in the modsec_debug.log file (if the log level is set high enough to capture this
- data).
+
+ The sanitize actions do not sanitize any data within the actual
+ raw requests but only on the copy of data within memory that is set to
+ log to the audit log. It will not sanitize the data in the
+ modsec_debug.log file (if the log level is set high enough to capture
+ this data).
+
sanitiseMatched
- Description: Sanitises the variable (request argument, request
- header, or response header) that caused a rule match.
+
+ Description: Sanitises the variable (request
+ argument, request header, or response header) that caused a rule
+ match.
+
Action Group: Non-disruptive
- Example: This action can be used to sanitise arbitrary transaction elements when they
- match a condition. For example, the example below will sanitise any argument that contains
- the word password in the name.
+
+ Example: This action can be used to sanitise arbitrary transaction
+ elements when they match a condition. For example, the example below
+ will sanitise any argument that contains the word
+ password in the name.
+
SecRule ARGS_NAMES password nolog,pass,sanitiseMatched
+
Note
+
Same note as sanitiseArg.
+
sanitiseRequestHeader
- Description: Sanitises a named request header.
+
+ Description: Sanitises a named request
+ header.
+
Action Group: Non-disruptive
- Example: This will sanitise the data in the Authorization header.
+
+ Example: This will sanitise the data in the Authorization
+ header.
+
SecAction log,phase:1,sanitiseRequestHeader:Authorization
+
Note
+
Same note as sanitiseArg.
+
sanitiseResponseHeader
- Description: Sanitises a named response header.
+
+ Description: Sanitises a named response
+ header.
+
Action Group: Non-disruptive
- Example: This will sanitise the Set-Cookie data sent to the client.
+
+ Example: This will sanitise the Set-Cookie data sent to the
+ client.
+
SecAction log,phase:3,sanitiseResponseHeader:Set-Cookie
+
Note
+
Same note as sanitiseArg.
+
severity
- Description: Assigns severity to the rule it is placed with.
+
+ Description: Assigns severity to the rule it
+ is placed with.
+
Action Group: Meta-data
+
Example:
+
SecRule REQUEST_METHOD "^PUT$" "id:340002,rev:1,severity:CRITICAL,msg:'Restricted HTTP function'"
+
Note
- Severity values in ModSecurity follow those of syslog, as below:
+
+ Severity values in ModSecurity follow those of syslog, as
+ below:
+
0 - EMERGENCY
+
1 - ALERT
+
2 - CRITICAL
+
3 - ERROR
+
4 - WARNING
+
5 - NOTICE
+
6 - INFO
+
7 - DEBUG
- It is possible to specify severity levels using either the numerical values or the text
- values. You should always specify severity levels using the text values. The use of the
- numerical values is deprecated (as of v2.5.0) and may be removed in one of the susequent
- major updates.
+
+ It is possible to specify severity levels using either the
+ numerical values or the text values. You should always specify severity
+ levels using the text values. The use of the numerical values is
+ deprecated (as of v2.5.0) and may be removed in one of the susequent
+ major updates.
+
setuid
- Description: Special-purpose action that initialises the USER collection.
+
+ Description: Special-purpose action that
+ initialises the USER
+ collection.
+
Action Group: Non-disruptive
+
Example:
+
SecAction setuid:%{REMOTE_USER},nolog
+
Note
- After initialisation takes place the variable USERID
- will be available for use in the subsequent rules.
+
+ After initialisation takes place the variable USERID will be available for use in the
+ subsequent rules.
+
setsid
- Description: Special-purpose action that initialises the SESSION collection.
+
+ Description: Special-purpose action that
+ initialises the SESSION
+ collection.
+
Action Group: Non-disruptive
+
Example:
+
# Initialise session variables using the session cookie value
SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass
SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}
+
Note
- On first invocation of this action the collection will be empty (not taking the
- predefined variables into account - see initcol for more
- information). On subsequent invocations the contents of the collection (session, in this
- case) will be retrieved from storage. After initialisation takes place the variable SESSIONID will be available for use in the subsequent
- rules.This action understands each application maintains its own set of sessions. It will
- utilise the current web application ID to create a session namespace.
+
+ On first invocation of this action the collection will be empty
+ (not taking the predefined variables into account - see initcol for more information). On subsequent
+ invocations the contents of the collection (session, in this case) will
+ be retrieved from storage. After initialisation takes place the
+ variable SESSIONID will be available
+ for use in the subsequent rules.This action understands each application
+ maintains its own set of sessions. It will utilise the current web
+ application ID to create a session namespace.
+
setenv
- Description: Creates, removes, or updates an environment
- variable.
+
+ Description: Creates, removes, or updates an
+ environment variable.
+
Action Group: Non-disruptive
+
Examples:
- To create a new variable (if you omit the value 1
- will be used):
+
+ To create a new variable (if you omit the value 1 will be used):
+
setenv:name=value
+
To remove a variable:
+
setenv:!name
+
Note
- This action can be used to establish communication with other Apache modules.
+
+ This action can be used to establish communication with other
+ Apache modules.
+
setvar
- Description: Creates, removes, or updates a variable in the
- specified collection.
+
+ Description: Creates, removes, or updates a
+ variable in the specified collection.
+
Action Group: Non-disruptive
+
Examples:
+
To create a new variable:
+
setvar:tx.score=10
+
To remove a variable prefix the name with exclamation mark:
+
setvar:!tx.score
- To increase or decrease variable value use + and
- - characters in front of a numerical value:
+
+ To increase or decrease variable value use + and -
+ characters in front of a numerical value:
+
setvar:tx.score=+5
+
skip
- Description: Skips one or more rules (or chains) on successful
- match.
+
+ Description: Skips one or more rules (or
+ chains) on successful match.
+
Action Group: Flow
+
Example:
-
- SecRule REQUEST_URI "^/$" \
+
+ SecRule REQUEST_URI "^/$" \
"phase:2,chain,t:none,skip:2"
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" \
"deny,log,status:400,id:960008,severity:4,msg:'Request Missing a Host Header'"
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
- "log,deny,log,status:400,id:960015,msg:'Request Missing an Accept Header'"
-
+ "log,deny,log,status:400,id:960015,msg:'Request Missing an Accept Header'"
+
Note
- Skip only applies to the current processing phase and not necessarily the order in which
- the rules appear in the configuration file. If you group rules by processing phases, then
- skip should work as expected. This action can not be used to skip rules within one chain.
- Accepts a single parameter denoting the number of rules (or chains) to skip.
+
+ Skip only applies to the current processing phase and not
+ necessarily the order in which the rules appear in the configuration
+ file. If you group rules by processing phases, then skip should work as
+ expected. This action can not be used to skip rules within one chain.
+ Accepts a single parameter denoting the number of rules (or chains) to
+ skip.
+
skipAfter
- Description: Skips rules (or chains) on successful match resuming
- rule execution after the specified rule ID or marker (see SecMarker) is
- found.
+
+ Description: Skips rules (or chains) on
+ successful match resuming rule execution after the specified rule ID or
+ marker (see SecMarker) is found.
+
Action Group: Flow
+
Example:
-
- SecRule REQUEST_URI "^/$" "chain,t:none,skipAfter:960015"
+
+ SecRule REQUEST_URI "^/$" "chain,t:none,skipAfter:960015"
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" \
"deny,log,status:400,id:960008,severity:4,msg:'Request Missing a Host Header'"
SecRule &REQUEST_HEADERS:Accept "@eq 0" \
- "log,deny,log,status:400,id:960015,msg:'Request Missing an Accept Header'"
-
+ "log,deny,log,status:400,id:960015,msg:'Request Missing an Accept Header'"
+
Note
- SkipAfter only applies to the current processing phase and not
- necessarily the order in which the rules appear in the configuration file. If you group
- rules by processing phases, then skip should work as expected. This action can not be used
- to skip rules within one chain. Accepts a single parameter denoting the last rule ID to
- skip.
+
+ SkipAfter only applies to the current
+ processing phase and not necessarily the order in which the rules appear
+ in the configuration file. If you group rules by processing phases, then
+ skip should work as expected. This action can not be used to skip rules
+ within one chain. Accepts a single parameter denoting the last rule ID
+ to skip.
+
status
- Description: Specifies the response status code to use with
- actions deny and
- redirect.
+
+ Description: Specifies the response status
+ code to use with actions deny
+ and redirect.
+
Action Group: Data
+
Example:
+
SecDefaultAction log,deny,status:403,phase:1
+
Note
- Status actions defined in Apache scope locations (such as Directory, Location, etc...)
- may be superseded by phase:1 action settings. The Apache ErrorDocument directive will be
- triggered if present in the configuration. Therefore if you have previously defined a custom
- error page for a given status then it will be executed and its output presented to the
- user.
+
+ Status actions defined in Apache scope locations (such as
+ Directory, Location, etc...) may be superseded by phase:1 action
+ settings. The Apache ErrorDocument directive will be triggered if
+ present in the configuration. Therefore if you have previously defined a
+ custom error page for a given status then it will be executed and its
+ output presented to the user.
+
t
- Description: This action can be used which transformation function
- should be used against the specified variables before they (or the results, rather) are run
- against the operator specified in the rule.
+
+ Description: This action can be used which
+ transformation function should be used against the specified variables
+ before they (or the results, rather) are run against the operator
+ specified in the rule.
+
Action Group: Non-disruptive
+
Example:
+
SecDefaultAction log,deny,phase:1,t:removeNulls,t:lowercase
SecRule REQUEST_COOKIES:SESSIONID "47414e81cbbef3cf8366e84eeacba091" \
log,deny,status:403,t:md5,t:hexEncode
+
Note
- Any transformation functions that you specify in a SecRule will be in addition to
- previous ones specified in SecDefaultAction. Use of "t:none" will remove all transformation
- functions for the specified rule.
+
+ Any transformation functions that you specify in a SecRule will be
+ in addition to previous ones specified in SecDefaultAction. Use of
+ "t:none" will remove all transformation functions for the specified
+ rule.
+
tag
- Description: Assigns custom text to a rule or chain.
+
+ Description: Assigns custom text to a rule or
+ chain.
+
Action Group: Meta-data
+
Example:
+
SecRule REQUEST_FILENAME "\b(?:n(?:map|et|c)|w(?:guest|sh)|cmd(?:32)?|telnet|rcmd|ftp)\.exe\b" \
"t:none,t:lowercase,deny,msg:'System Command Access',id:'950002',\
tag:'WEB_ATTACK/FILE_INJECTION',tag:'OWASP/A2',severity:'2'"
+
Note
- The tag information appears in the error and/or audit log files. Its intent is to be
- used to automate classification of rules and the alerts generated by rules. Multiple tags
- can be used per rule/chain.
+
+ The tag information appears in the error and/or audit log files.
+ Its intent is to be used to automate classification of rules and the
+ alerts generated by rules. Multiple tags can be used per
+ rule/chain.
+
xmlns
- Description: This action should be used together with an XPath
- expression to register a namespace.
+
+ Description: This action should be used
+ together with an XPath expression to register a namespace.
+
Action Group: Data
+
Example:
+
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
"phase:1,pass,ctl:requestBodyProcessor=XML,ctl:requestBodyAccess=On, \
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
SecRule XML:/soap:Envelope/soap:Body/q1:getInput/id() "123" phase:2,deny
+
Operators
- A number of operators can be used in rules, as documented below. The operator syntax uses
- the @ symbol followed by the specific operator name.
+
+ A number of operators can be used in rules, as documented below. The
+ operator syntax uses the @ symbol followed by the
+ specific operator name.
+
beginsWith
- Description: This operator is a string comparison and returns true
- if the parameter value is found at the beginning of the input. Macro expansion is performed
- so you may use variable names such as %{TX.1}, etc.
+
+ Description: This operator is a string
+ comparison and returns true if the parameter value is found at the
+ beginning of the input. Macro expansion is performed so you may use
+ variable names such as %{TX.1}, etc.
+
Example:
+
SecRule REQUEST_LINE "!@beginsWith GET" t:none,deny,status:403
SecRule REQUEST_ADDR "^(.*)\.\d+$" deny,status:403,capture,chain
SecRule ARGS:gw "!@beginsWith %{TX.1}"
+
contains
- Description: This operator is a string comparison and returns true
- if the parameter value is found anywhere in the input. Macro expansion is performed so you
- may use variable names such as %{TX.1}, etc.
+
+ Description: This operator is a string
+ comparison and returns true if the parameter value is found anywhere in
+ the input. Macro expansion is performed so you may use variable names
+ such as %{TX.1}, etc.
+
Example:
+
SecRule REQUEST_LINE "!@contains .php" t:none,deny,status:403
SecRule REQUEST_ADDR "^(.*)$" deny,status:403,capture,chain
SecRule ARGS:ip "!@contains %{TX.1}"
+
endsWith
- Description: This operator is a string comparison and returns true
- if the parameter value is found at the end of the input. Macro expansion is performed so you
- may use variable names such as %{TX.1}, etc.
+
+ Description: This operator is a string
+ comparison and returns true if the parameter value is found at the end
+ of the input. Macro expansion is performed so you may use variable names
+ such as %{TX.1}, etc.
+
Example:
+
SecRule REQUEST_LINE "!@endsWith HTTP/1.1" t:none,deny,status:403
SecRule ARGS:route "!@endsWith %{REQUEST_ADDR}" t:none,deny,status:403
+
eq
- Description: This operator is a numerical comparison and stands for
- "equal to."
+
+ Description: This operator is a numerical
+ comparison and stands for "equal to."
+
Example:
+
SecRule &REQUEST_HEADERS_NAMES "@eq 15"
+
ge
- Description: This operator is a numerical comparison and stands for
- "greater than or equal to."
+
+ Description: This operator is a numerical
+ comparison and stands for "greater than or equal to."
+
Example:
+
SecRule &REQUEST_HEADERS_NAMES "@ge 15"
+
geoLookup
- Description: This operator looks up various data fields from an IP
- address or hostname. The results will be captured in the GEO collection.
- You must provide a database via SecGeoLookupDb before
- this operator can be used.
- See the GEO variable for an example and more
- information on various fields available.
+
+ Description: This operator looks up various
+ data fields from an IP address or hostname. The results will be captured
+ in the GEO collection.
+
+ You must provide a database via SecGeoLookupDb before this operator can be
+ used.
+
+ See the GEO variable for an
+ example and more information on various fields available.
+
gt
- Description: This operator is a numerical comparison and stands for
- "greater than."
+
+ Description: This operator is a numerical
+ comparison and stands for "greater than."
+
Example:
+
SecRule &REQUEST_HEADERS_NAMES "@gt 15"
+
inspectFile
- Description: Executes the external script/binary given as parameter
- to the operator against every file extracted from the request. As of v2.5.0, if the supplied
- filename is not absolute it is treated as relative to the directory in which the
- configuration file resides. Also as of v2.5.0, if the filename is determined to be a Lua
- script (based on its extension) the script will be processed by the internal engine. As such
- it will have full access to the ModSecurity context.
+
+ Description: Executes the external
+ script/binary given as parameter to the operator against every file
+ extracted from the request. As of v2.5.0, if the supplied filename is
+ not absolute it is treated as relative to the directory in which the
+ configuration file resides. Also as of v2.5.0, if the filename is
+ determined to be a Lua script (based on its extension) the script will
+ be processed by the internal engine. As such it will have full access to
+ the ModSecurity context.
+
Example of using an external binary/script:
+
# Execute external script to validate uploaded files.
SecRule FILES_TMPNAMES "@inspectFile /opt/apache/bin/inspect_script.pl"
+
Example of using Lua script:
+
SecRule FILES_TMPNANMES "@inspectFile inspect.lua"
+
Script inspect.lua:
+
function main(filename)
-- Do something to the file to verify it. In this example, we
-- read up to 10 characters from the beginning of the file.
@@ -3631,369 +5497,542 @@ SecRule FILES_TMPNAMES "@inspectFile /opt/apache/bin/inspec
return null;
end
+
le
- Description: This operator is a numerical comparison and stands for
- "less than or equal to."
+
+ Description: This operator is a numerical
+ comparison and stands for "less than or equal to."
+
Example:
+
SecRule &REQUEST_HEADERS_NAMES "@le 15"
+
lt
- Description: This operator is a numerical comparison and stands for
- "less than."
+
+ Description: This operator is a numerical
+ comparison and stands for "less than."
+
Example:
+
SecRule &REQUEST_HEADERS_NAMES "@lt 15"
+
pm
- Description: 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.
+
+ Description: 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.
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper SiteSnagger ProWebWalker CheeseBot" "deny,status:403
- The above would deny access with 403 if any of the words matched within the User-Agent
- HTTP header value.
+
+ The above would deny access with 403 if any of the words matched
+ within the User-Agent HTTP header value.
+
pmFromFile
- Description: 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 @pm 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.
+
+ Description: 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
+ @pm 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.
+
Notes:
+
- 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.
+ 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.
+
- 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.
+ 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.
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "@pm /path/to/blacklist1 blacklist2" "deny,status:403
- 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 blacklist2 file would need
- to be placed in the same path as the file containing the rule.
+
+ 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
+ blacklist2 file would need to be placed in the same
+ path as the file containing the rule.
+
rbl
- Description: Look up the parameter in the RBL given as parameter.
- Parameter can be an IPv4 address, or a hostname.
+
+ Description: Look up the parameter in the RBL
+ given as parameter. Parameter can be an IPv4 address, or a
+ hostname.
+
Example:
+
SecRule REMOTE_ADDR "@rbl sc.surbl.org"
+
rx
- Description: Regular expression operator. This is the default
- operator, so if the "@" operator is not defined, it is assumed to be rx.
+
+ Description: Regular expression operator.
+ This is the default operator, so if the "@" operator is not defined, it
+ is assumed to be rx.
+
Example:
+
SecRule REQUEST_HEADERS:User-Agent "@rx nikto"
+
Note
- Regular expressions are handled by the PCRE library (http://www.pcre.org). ModSecurity compiles its regular expressions with the
- following settings:
+
+ Regular expressions are handled by the PCRE library (http://www.pcre.org). ModSecurity
+ compiles its regular expressions with the following settings:
+
- The entire input is treated as a single line, even when there are newline characters
- present.
+ The entire input is treated as a single line, even when there
+ are newline characters present.
+
- All matches are case-sensitive. If you do not care about case sensitivity you either
- need to implement the lowercase transformation
- function, or use the per-pattern(?i)modifier, as
- allowed by PCRE.
+ All matches are case-sensitive. If you do not care about case
+ sensitivity you either need to implement the lowercase transformation function, or use
+ the per-pattern(?i)modifier, as
+ allowed by PCRE.
+
- The PCRE_DOTALL and PCRE_DOLLAR_ENDONLY flags are set during compilation, meaning a single dot
- will match any character, including the newlines and a $ end anchor will not match a trailing newline character.
+ The PCRE_DOTALL and
+ PCRE_DOLLAR_ENDONLY flags are set
+ during compilation, meaning a single dot will match any character,
+ including the newlines and a $
+ end anchor will not match a trailing newline character.
+
streq
- Description: This operator is a string comparison and returns true
- if the parameter value matches the input exactly. Macro expansion is performed so you may
- use variable names such as %{TX.1}, etc.
+
+ Description: This operator is a string
+ comparison and returns true if the parameter value matches the input
+ exactly. Macro expansion is performed so you may use variable names such
+ as %{TX.1}, etc.
+
Example:
+
SecRule ARGS:foo "!@streq bar" t:none,deny,status:403
SecRule REQUEST_ADDR "^(.*)$" deny,status:403,capture,chain
SecRule REQUEST_HEADERS:Ip-Address "!@streq %{TX.1}"
+
validateByteRange
- Description: Validates the byte range used in the variable falls
- into the specified range.
+
+ Description: Validates the byte range used in
+ the variable falls into the specified range.
+
Example:
+
SecRule ARG:text "@validateByteRange 10, 13, 32-126"
+
Note
- You can force requests to consist only of bytes from a certain byte range. This can be
- useful to avoid stack overflow attacks (since they usually contain "random" binary content).
- Default range values are 0 and 255, i.e. all byte values are allowed. This directive does
- not check byte range in a POST payload when multipart/form-data encoding
- (file upload) is used. Doing so would prevent binary files from being uploaded. However,
- after the parameters are extracted from such request they are checked for a valid
- range.
- validateByteRange is similar to the ModSecurity 1.X SecFilterForceByteRange Directive
- however since it works in a rule context, it has the following differences:
+
+ You can force requests to consist only of bytes from a certain
+ byte range. This can be useful to avoid stack overflow attacks (since
+ they usually contain "random" binary content). Default range values are
+ 0 and 255, i.e. all byte values are allowed. This directive does not
+ check byte range in a POST payload when
+ multipart/form-data encoding (file upload) is used.
+ Doing so would prevent binary files from being uploaded. However, after
+ the parameters are extracted from such request they are checked for a
+ valid range.
+
+ validateByteRange is similar to the ModSecurity 1.X
+ SecFilterForceByteRange Directive however since it works in a rule
+ context, it has the following differences:
+
- You can specify a different range for different variables.
+ You can specify a different range for different
+ variables.
+
It has an "event" context (id, msg....)
+
- It is executed in the flow of rules rather than being a built in pre-check.
+ It is executed in the flow of rules rather than being a built
+ in pre-check.
+
validateDTD
- Description: Validates the DOM tree generated by the XML request
- body processor against the supplied DTD.
+
+ Description: Validates the DOM tree generated
+ by the XML request body processor against the supplied DTD.
+
Example:
+
SecDefaultAction log,deny,status:403,phase:2
SecRule REQUEST_HEADERS:Content-Type ^text/xml$ \
phase:1,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML
SecRule REQBODY_PROCESSOR "!^XML$" nolog,pass,skipAfter:12345
SecRule XML "@validateDTD /path/to/apache2/conf/xml.dtd" "deny,id:12345"
+
- This operator requires request body to be processed as XML.
+ This operator requires request body to be processed as
+ XML.
+
validateSchema
- Description: Validates the DOM tree generated by the XML request
- body processor against the supplied XML Schema.
+
+ Description: Validates the DOM tree generated
+ by the XML request body processor against the supplied XML
+ Schema.
+
Example:
+
SecDefaultAction log,deny,status:403,phase:2
SecRule REQUEST_HEADERS:Content-Type ^text/xml$ \
phase:1,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML
SecRule REQBODY_PROCESSOR "!^XML$" nolog,pass,skipAfter:12345
SecRule XML "@validateSchema /path/to/apache2/conf/xml.xsd" "deny,id:12345"
+
- This operator requires request body to be processed as XML.
+ This operator requires request body to be processed as
+ XML.
+
validateUrlEncoding
- Description: Verifies the encodings used in the variable (if any)
- are valid.
+
+ Description: Verifies the encodings used in
+ the variable (if any) are valid.
+
Example:
+
SecRule ARGS "@validateUrlEncoding"
+
Note
- URL encoding is an HTTP standard for encoding byte values within a URL. The byte is
- escaped with a % followed by two hexadecimal values (0-F). This directive does not check
- encoding in a POST payload when the multipart/form-data encoding (file
- upload) is used. It is not necessary to do so because URL encoding is not used for this
- encoding.
+
+ URL encoding is an HTTP standard for encoding byte values within a
+ URL. The byte is escaped with a % followed by two hexadecimal values
+ (0-F). This directive does not check encoding in a POST payload when the
+ multipart/form-data encoding (file upload) is used.
+ It is not necessary to do so because URL encoding is not used for this
+ encoding.
+
validateUtf8Encoding
- Description: Verifies the variable is a valid UTF-8 encoded
- string.
+
+ Description: Verifies the variable is a valid
+ UTF-8 encoded string.
+
Example:
+
SecRule ARGS "@validateUtf8Encoding"
+
Note
- UTF-8 encoding is valid on most web servers. Integer values between 0-65535 are encoded
- in a UTF-8 byte sequence that is escaped by percents. The short form is two bytes in
- length.
+
+ UTF-8 encoding is valid on most web servers. Integer values
+ between 0-65535 are encoded in a UTF-8 byte sequence that is escaped by
+ percents. The short form is two bytes in length.
+
check for three types of errors:
+
- Not enough bytes. UTF-8 supports two, three, four, five, and six byte encodings.
- ModSecurity will locate cases when a byte or more is missing.
+ Not enough bytes. UTF-8 supports two, three, four, five, and
+ six byte encodings. ModSecurity will locate cases when a byte or
+ more is missing.
+
- Invalid encoding. The two most significant bits in most characters are supposed to
- be fixed to 0x80. Attackers can use this to subvert Unicode decoders.
+ Invalid encoding. The two most significant bits in most
+ characters are supposed to be fixed to 0x80. Attackers can use this
+ to subvert Unicode decoders.
+
- Overlong characters. ASCII characters are mapped directly into the Unicode space and
- are thus represented with a single byte. However, most ASCII characters can also be
- encoded with two, three, four, five, and six characters thus tricking the decoder into
- thinking that the character is something else (and, presumably, avoiding the security
- check).
+ Overlong characters. ASCII characters are mapped directly into
+ the Unicode space and are thus represented with a single byte.
+ However, most ASCII characters can also be encoded with two, three,
+ four, five, and six characters thus tricking the decoder into
+ thinking that the character is something else (and, presumably,
+ avoiding the security check).
+
verifyCC
- Description: This operator verifies a given regular expression as a
- potential credit card number. It first matches with a single generic regular expression then
- runs the resulting match through a Luhn checksum algorithm to further verify it as a
- potential credit card number.
+
+ Description: This operator verifies a given
+ regular expression as a potential credit card number. It first matches
+ with a single generic regular expression then runs the resulting match
+ through a Luhn checksum algorithm to further verify it as a potential
+ credit card number.
+
Example:
+
SecRule ARGS "@verifyCC \d{13,16}" \
"phase:2,sanitiseMatched,log,auditlog,pass,msg:'Potential credit card number'"
+
within
- Description: 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 @contains, except that the target and match values are reversed. Macro
- expansion is performed so you may use variable names such as %{TX.1}, etc.
+
+ Description: 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
+ @contains, except that the target and match values
+ are reversed. Macro expansion is performed so you may use variable names
+ such as %{TX.1}, etc.
+
Example:
+
SecRule REQUEST_METHOD "!@within get,post,head" t:lowercase,deny,status:403
SecAction "pass,setvar:'tx.allowed_methods=get,post,head'"
SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" t:lowercase,deny,status:403
+
Macro Expansion
- Macros allow for using place holders in rules that will be expanded out to their values at
- runtime. Currently only variable expansion is supported, however more options may be added in
- future versions of ModSecurity.
+
+ Macros allow for using place holders in rules that will be expanded
+ out to their values at runtime. Currently only variable expansion is
+ supported, however more options may be added in future versions of
+ ModSecurity.
+
Format:
+
%{VARIABLE}
%{COLLECTION.VARIABLE}
- Macro expansion can be used in actions such as initcol, setsid, setuid, setvar, setenv,
- logdata. Operators that are evaluated at runtime support expansion and are noted above. Such
- operators include @beginsWith, @endsWith, @contains, @within and @streq. You cannot use macro
- expansion for operators that are "compiled" such as @pm, @rx, etc. as these operators have
- their values fixed at configure time for efficiency.
- Some values you may want to expand include: TX, REMOTE_ADDR, USERID, HIGHEST_SEVERITY,
- MATCHED_VAR, MATCHED_VAR_NAME, MULTIPART_STRICT_ERROR, RULE, SESSION, USERID, among
- others.
+
+ Macro expansion can be used in actions such as initcol, setsid,
+ setuid, setvar, setenv, logdata. Operators that are evaluated at runtime
+ support expansion and are noted above. Such operators include @beginsWith,
+ @endsWith, @contains, @within and @streq. You cannot use macro expansion
+ for operators that are "compiled" such as @pm, @rx, etc. as these
+ operators have their values fixed at configure time for efficiency.
+
+ Some values you may want to expand include: TX, REMOTE_ADDR, USERID,
+ HIGHEST_SEVERITY, MATCHED_VAR, MATCHED_VAR_NAME, MULTIPART_STRICT_ERROR,
+ RULE, SESSION, USERID, among others.
+
Persistant Storage
- At this time it is only possible to have three collections in which data is stored
- persistantly (i.e. data available to multiple requests). These are: IP, SESSION and USER.
- Every collection contains several built-in variables that are available and are read-only
- unless otherwise specified:
+
+ At this time it is only possible to have three collections in which
+ data is stored persistantly (i.e. data available to multiple requests).
+ These are: IP, SESSION and USER.
+
+ Every collection contains several built-in variables that are
+ available and are read-only unless otherwise specified:
+
- CREATE_TIME - date/time of the creation of the
- collection.
+ CREATE_TIME - date/time of
+ the creation of the collection.
+
- IS_NEW - set to 1 if the collection is new (not yet
- persisted) otherwise set to 0.
+ IS_NEW - set to 1 if the
+ collection is new (not yet persisted) otherwise set to 0.
+
- KEY - the value of the initcol variable (the
- client's IP address in the example).
+ KEY - the value of the
+ initcol variable (the client's IP address in the example).
+
- LAST_UPDATE_TIME - date/time of the last update to
- the collection.
+ LAST_UPDATE_TIME - date/time
+ of the last update to the collection.
+
- TIMEOUT - date/time in seconds when the collection
- will be updated on disk from memory (if no other updates occur). This variable may be set
- if you wish to specifiy an explicit expiration time (default is 3600 seconds).
+ TIMEOUT - date/time in
+ seconds when the collection will be updated on disk from memory (if no
+ other updates occur). This variable may be set if you wish to specifiy
+ an explicit expiration time (default is 3600 seconds).
+
- UPDATE_COUNTER - how many times the collection has
- been updated since creation.
+ UPDATE_COUNTER - how many
+ times the collection has been updated since creation.
+
- UPDATE_RATE - is the average rate updates per
- minute since creation.
+ UPDATE_RATE - is the average
+ rate updates per minute since creation.
- To create a collection to hold session variables (SESSION) use action setsid. To create a
- collection to hold user variables (USER) use action
- setuid. To create a collection to hold client address
- variables (IP) use action initcol.
+
+ To create a collection to hold session variables (SESSION) use action setsid. To create a collection to hold user
+ variables (USER) use action setuid. To create a collection to hold client
+ address variables (IP) use action
+ initcol.
+
- ModSecurity implements atomic updates of persistent variables only for integer variables
- (counters) at this time. Variables are read from storage whenever initcol
- is encountered in the rules and persisted at the end of request processing. Counters are
- adjusted by applying a delta generated by re-reading the persisted data just before being
- persisted. This keeps counter data consistent even if the counter was modified and persisted
- by another thread/process during the transaction.
+ ModSecurity implements atomic updates of persistent variables only
+ for integer variables (counters) at this time. Variables are read from
+ storage whenever initcol is encountered in the rules
+ and persisted at the end of request processing. Counters are adjusted by
+ applying a delta generated by re-reading the persisted data just before
+ being persisted. This keeps counter data consistent even if the counter
+ was modified and persisted by another thread/process during the
+ transaction.
+
+ Please note that ModSecurity does not implement atomic updates of
+ persistent variables at this time. Variables are read from storage
+ whenever initcol 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.
+
- ModSecurity uses a Berkley Database (SDBM) for persistant storage. This type of database
- is generally limited to storing a maximum of 1008 bytes per key. This may be a limitation if
- you are attempting to store a considerable amount of data in variables for a single key.
- Some of this limitation is planned to be reduced in a future version of ModSecurity.
+ ModSecurity uses a Berkley Database (SDBM) for persistant storage.
+ This type of database is generally limited to storing a maximum of 1008
+ bytes per key. This may be a limitation if you are attempting to store a
+ considerable amount of data in variables for a single key. Some of this
+ limitation is planned to be reduced in a future version of
+ ModSecurity.
+
Miscellaneous Topics
-
+
+
+
Impedance Mismatch
- Web application firewalls have a difficult job trying to make sense of data that passes
- by, without any knowledge of the application and its business logic. The protection they
- provide comes from having an independent layer of security on the outside. Because data
- validation is done twice, security can be increased without having to touch the application.
- In some cases, however, the fact that everything is done twice brings problems. Problems can
- arise in the areas where the communication protocols are not well specified, or where either
- the device or the application do things that are not in the specification. In such cases it
- may be possible to design payload that will be interpreted in one way by one device and in
- another by the other device. This problem is better known as Impedance Mismatch. It can be
- exploited to evade the security devices.
- While we will continue to enhance ModSecurity to deal with various evasion techniques
- the problem can only be minimized, but never solved. With so many different application
- backend chances are some will always do something completely unexpected. The only solution
- is to be aware of the technologies in the backend when writing rules, adapting the rules to
- remove the mismatch. See the next section for some examples.
+
+ Web application firewalls have a difficult job trying to make
+ sense of data that passes by, without any knowledge of the application
+ and its business logic. The protection they provide comes from having an
+ independent layer of security on the outside. Because data validation is
+ done twice, security can be increased without having to touch the
+ application. In some cases, however, the fact that everything is done
+ twice brings problems. Problems can arise in the areas where the
+ communication protocols are not well specified, or where either the
+ device or the application do things that are not in the specification.
+ In such cases it may be possible to design payload that will be
+ interpreted in one way by one device and in another by the other device.
+ This problem is better known as Impedance Mismatch. It can be exploited
+ to evade the security devices.
+
+ While we will continue to enhance ModSecurity to deal with various
+ evasion techniques the problem can only be minimized, but never solved.
+ With so many different application backend chances are some will always
+ do something completely unexpected. The only solution is to be aware of
+ the technologies in the backend when writing rules, adapting the rules
+ to remove the mismatch. See the next section for some examples.
+
PHP Peculiarities for ModSecurity Users
- When writing rules to protect PHP applications you need to pay attention to the
- following facts:
+
+ When writing rules to protect PHP applications you need to pay
+ attention to the following facts:
+
- When "register_globals" is set to "On" request parameters are automatically
- converted to script variables. In some PHP versions it is even possible to override
- the $GLOBALS array.
+ When "register_globals" is set to "On" request parameters
+ are automatically converted to script variables. In some PHP
+ versions it is even possible to override the $GLOBALS
+ array.
+
- Whitespace at the beginning of parameter names is ignored. (This is very dangerous
- if you are writing rules to target specific named variables.)
+ Whitespace at the beginning of parameter names is ignored.
+ (This is very dangerous if you are writing rules to target
+ specific named variables.)
+
- The remaining whitespace (in parameter names) is converted to underscores. The
- same applies to dots and to a "[" if the variable name does not contain a matching
- closing bracket. (Meaning that if you want to exploit a script through a variable that
- contains an underscore in the name you can send a parameter with a whitespace or a dot
- instead.)
+ The remaining whitespace (in parameter names) is converted
+ to underscores. The same applies to dots and to a "[" if the
+ variable name does not contain a matching closing bracket.
+ (Meaning that if you want to exploit a script through a variable
+ that contains an underscore in the name you can send a parameter
+ with a whitespace or a dot instead.)
+
Cookies can be treated as request parameters.
+
- The discussion about variable names applies equally to the cookie names.
+ The discussion about variable names applies equally to the
+ cookie names.
+
- The order in which parameters are taken from the request and the environment is
- EGPCS (environment, GET, POST, Cookies, built-in variables). This means that a POST
- parameter will overwrite the parameters transported on the request line (in
- QUERY_STRING).
+ The order in which parameters are taken from the request and
+ the environment is EGPCS (environment, GET, POST, Cookies,
+ built-in variables). This means that a POST parameter will
+ overwrite the parameters transported on the request line (in
+ QUERY_STRING).
+
- When "magic_quotes_gpc" is set to "On" PHP will use backslash to escape the
- following characters: single quote, double quote, backslash, and the nul byte.
+ When "magic_quotes_gpc" is set to "On" PHP will use
+ backslash to escape the following characters: single quote, double
+ quote, backslash, and the nul byte.
+
- If "magic_quotes_sybase" is set to "On" only the single quote will be escaped
- using another single quote. In this case the "magic_quotes_gpc" setting becomes
- irrelevant. The "magic_quotes_sybase" setting completely overrides the
- "magic_quotes_gpc" behaviour but "magic_quotes_gpc" still must be set to "On" for the
- Sybase-specific quoting to be work.
+ If "magic_quotes_sybase" is set to "On" only the single
+ quote will be escaped using another single quote. In this case the
+ "magic_quotes_gpc" setting becomes irrelevant. The
+ "magic_quotes_sybase" setting completely overrides the
+ "magic_quotes_gpc" behaviour but "magic_quotes_gpc" still must be
+ set to "On" for the Sybase-specific quoting to be work.
+
- PHP will also automatically create nested arrays for you. For example "p[x][y]=1"
- results in a total of three variables.
+ PHP will also automatically create nested arrays for you.
+ For example "p[x][y]=1" results in a total of three
+ variables.
-
+
\ No newline at end of file
diff --git a/doc/modsecurity2-data-formats.xml b/doc/modsecurity2-data-formats.xml
index 12ffe318..d473023b 100644
--- a/doc/modsecurity2-data-formats.xml
+++ b/doc/modsecurity2-data-formats.xml
@@ -4,7 +4,7 @@
ModSecurity 2 Data Formats
- Version 2.6.0-trunk (December 3, 2008)
+ Version 2.6.0-trunk (March 5, 2009)
2004-2008
Breach Security, Inc. (
-
-
-
- 2008-01-04 :: 10:55:40:361 GMT-08:00
- 2008-01-11 :: 16:47:15:701 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.normal
- Is ENV really cacheable? It could change via setenv.
- /* ENV */
- msre_engine_variable_register(engine,
- "ENV",
- VAR_LIST,
- 0, 1,
- var_env_validate,
- var_env_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 10:57:54:279 GMT-08:00
- 2008-01-11 :: 16:43:38:825 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- GEO is probably not cacheable as it changes with every @geoLookup operator.
- /* GEO */
- msre_engine_variable_register(engine,
- "GEO",
- VAR_LIST,
- 1, 1,
- var_generic_list_validate,
- var_geo_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:02:30:450 GMT-08:00
- 2008-01-11 :: 16:43:20:652 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- GLOBAL is not documented. Is it cacheable?
- /* GLOBAL */
- msre_engine_variable_register(engine,
- "GLOBAL",
- VAR_LIST,
- 1, 1,
- var_generic_list_validate,
- var_global_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:06:50:690 GMT-08:00
- 2008-01-11 :: 16:43:02:916 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- IP undocumented. Probably not cacheable as it can change via setvar, etc.
- /* IP */
- msre_engine_variable_register(engine,
- "IP",
- VAR_LIST,
- 1, 1,
- var_generic_list_validate,
- var_ip_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:08:36:733 GMT-08:00
- 2008-01-11 :: 16:42:44:589 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- RESOURCE is undocumented. Probably not cacheable as it is easily changed.
- /* RESOURCE */
- msre_engine_variable_register(engine,
- "RESOURCE",
- VAR_LIST,
- 1, 1,
- var_generic_list_validate,
- var_resource_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:14:32:043 GMT-08:00
- 2008-01-11 :: 16:41:31:558 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- SESSION is probably not cacheable since it is modifyable via setvar.
- /* SESSION */
- msre_engine_variable_register(engine,
- "SESSION",
- VAR_LIST,
- 1, 1,
- var_generic_list_validate,
- var_session_generate,
- VAR_CACHE,
- PHASE_REQUEST_HEADERS
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:25:25:879 GMT-08:00
- 2008-01-11 :: 17:00:23:571 GMT-08:00
-
- brian
- brian
- apache2/apache2_util.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable way to format sizeof()?
- msr_log(msr, 1, "Exec: Unable to allocate %lu bytes.", (unsigned long)sizeof(*procnew));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 11:48:52:563 GMT-08:00
- 2008-01-04 :: 11:50:30:473 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.irrelevant
- item.severity.label.trivial
- This #if 0'd out code should be removed.
- /* Removed %0-9 macros as it messes up urlEncoding in the match
- * where having '%0a' will be treated as %{TX.0}a, which is incorrect.
- * */
-#if 0
- else if ((*(p + 1) >= '0')&&(*(p + 1) <= '9')) {
- /* Special case for regex captures. */
- var_name = "TX";
- var_value = apr_pstrmemdup(mptmp, p + 1, 1);
- next_text_start = p + 2;
- }
-#endif
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 11:53:45:291 GMT-08:00
- 2008-01-04 :: 14:51:42:573 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.optimization
- item.severity.label.trivial
- Use apr_array_pstrcat(msr->mp, arr, NULL) instead?
- /* If there's more than one member of the array that
- * means there was at least one macro present. Combine
- * text parts into a single string now.
- */
- if (arr->nelts > 1) {
- /* Figure out the required size for the string. */
- var->value_len = 0;
- for(i = 0; i < arr->nelts; i++) {
- part = ((msc_string **)arr->elts)[i];
- var->value_len += part->value_len;
- }
-
- /* Allocate the string. */
- var->value = apr_palloc(msr->mp, var->value_len + 1);
- if (var->value == NULL) return -1;
-
- /* Combine the parts. */
- offset = 0;
- for(i = 0; i < arr->nelts; i++) {
- part = ((msc_string **)arr->elts)[i];
- memcpy((char *)(var->value + offset), part->value, part->value_len);
- offset += part->value_len;
- }
- var->value[offset] = '\0';
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 12:00:50:877 GMT-08:00
- 2008-01-04 :: 12:03:50:156 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- Suggestion
- item.severity.label.trivial
- Use resolve_relative_path() instead? Maybe a config_relative_path() to just get the path?
- /* 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)));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 13:23:49:834 GMT-08:00
- 2008-01-11 :: 16:26:24:257 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *next++ = '\0';
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 14:54:09:456 GMT-08:00
- 2008-01-04 :: 14:55:05:945 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- Need to check return code and log an error on failure.
- acmp_add_pattern(p, buf, NULL, NULL, strlen(buf));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 14:55:53:308 GMT-08:00
- 2008-01-04 :: 14:56:17:267 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- Need to check return code and log an error on failure.
- acmp_prepare(p);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 14:58:08:006 GMT-08:00
- 2008-01-04 :: 15:00:17:190 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.optimization
- item.severity.label.minor
- See if apr_strmatch is faster.
- msre_op_within_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 14:59:32:341 GMT-08:00
- 2008-01-04 :: 14:59:59:858 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.optimization
- item.severity.label.minor
- See if apr_strmatch is faster.
- msre_op_contains_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 15:01:39:208 GMT-08:00
- 2008-01-04 :: 15:02:04:258 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.optimization
- item.severity.label.minor
- See if apr_strmatch is faster.
- msre_op_containsWord_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 15:03:12:792 GMT-08:00
- 2008-01-04 :: 15:04:40:965 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.optimization
- item.severity.label.minor
- This implementation comment needs to be coded as many string operators now attempt to resolve macros.
- /* IMP1 Duplicate the string and create the array on
- * demand, thus not having to do it if there are
- * no macros in the input data.
- */
-
- data = apr_pstrdup(mptmp, var->value); /* IMP1 Are we modifying data anywhere? */
- arr = apr_array_make(mptmp, 16, sizeof(msc_string *));
- if ((data == NULL)||(arr == NULL)) return -1;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 15:12:55:300 GMT-08:00
- 2008-01-04 :: 15:13:19:677 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.minor
- Need more unit tests for operators. Start with new operators.
-
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 15:36:54:292 GMT-08:00
- 2008-01-04 :: 15:37:50:111 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- @m operator is not documented. This does the same as @contains, so it was suggested earlier to use the @m algorithm for contains (if faster) and drop @m.
- /* m */
- msre_engine_op_register(engine,
- "m",
- msre_op_m_param_init,
- msre_op_m_execute
- );
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 15:43:40:931 GMT-08:00
- 2008-01-11 :: 16:38:59:940 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- @geoLookup should set error_msg on success to something like "Successful geograpical lookup of \"%s\" at %s."
- msre_op_geoLookup_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 15:47:09:574 GMT-08:00
- 2008-01-11 :: 16:40:07:483 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- @rbl fails to set the var name in error_msg. Should append "at %s".
- rc = apr_sockaddr_info_get(&sa, name_to_check,
- APR_UNSPEC/*msr->r->connection->remote_addr->family*/, 0, 0, msr->mp);
- if (rc == APR_SUCCESS) {
- *error_msg = apr_psprintf(msr->r->pool, "RBL lookup of %s succeeded.",
- log_escape_nq(msr->mp, name_to_check));
- return 1; /* Match. */
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 15:49:05:878 GMT-08:00
- 2008-01-11 :: 14:56:55:081 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.suggestion
- item.severity.label.major
- Change from TODO to ENH.
-
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 15:54:24:055 GMT-08:00
- 2008-01-11 :: 14:57:08:520 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.suggestion
- item.severity.label.trivial
- Need to remove the LUA #ifdef's
- #ifdef WITH_LUA
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 15:56:23:415 GMT-08:00
- 2008-01-11 :: 14:57:21:641 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.suggestion
- item.severity.label.trivial
- The LUA #ifdef's should be removed, but if it is decided not to, then this lua call needs to be #ifdef'd.
- } else {
- /* Execute internally, as Lua script. */
- char *target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
- msc_script *script = (msc_script *)rule->op_param_data;
- int rc;
-
- rc = lua_execute(script, target, msr, rule, error_msg);
- if (rc < 0) {
- /* Error. */
- return -1;
- }
-
- return rc;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 15:58:01:918 GMT-08:00
- 2008-01-04 :: 15:58:58:621 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.major
- Need an error_msg set for lua execution error.
- rc = lua_execute(script, target, msr, rule, error_msg);
- if (rc < 0) {
- /* Error. */
- return -1;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:00:09:204 GMT-08:00
- 2008-01-11 :: 16:38:08:350 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- @validateByteRange does not output the VAR name on match. Need to append " at %s."
- msre_op_validateByteRange_execute
-
-
- item.resolution.label.invalidWontfix
- item.status.label.closed
-
-
-
- 2008-01-04 :: 16:02:02:403 GMT-08:00
- 2008-01-04 :: 16:06:22:410 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- @validateurlEncoding does not output VAR name nor offset in error_msg on match.
- msre_op_validateUrlEncoding_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:03:51:127 GMT-08:00
- 2008-01-11 :: 16:30:07:550 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.missing
- item.severity.label.trivial
- Numeric operators (@eq, etc) do not output VAR name on match.
- msre_op_eq_execute
-msre_op_gt_execute
-msre_op_lt_execute
-msre_op_ge_execute
-msre_op_le_execute
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 16:12:30:943 GMT-08:00
- 2008-01-11 :: 14:57:45:711 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- No.
- /* ENH Do we want to support %{DIGIT} as well? */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 16:14:51:515 GMT-08:00
- 2008-01-07 :: 14:22:10:119 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Implement. Need to check if Apache will return an invalid status code
- /* status */
-static char *msre_action_status_validate(msre_engine *engine, msre_action *action) {
- /* ENH action->param must be a valid HTTP status code. */
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:15:55:149 GMT-08:00
- 2008-01-04 :: 16:16:52:467 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Implement.
- /* pause */
-static char *msre_action_pause_validate(msre_engine *engine, msre_action *action) {
- /* ENH Validate a positive number. */
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:17:34:464 GMT-08:00
- 2008-01-04 :: 16:22:35:501 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Implement as a valid URI check with apr_uri_parse()?
- /* redirect */
-
-static char *msre_action_redirect_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:22:43:274 GMT-08:00
- 2008-01-04 :: 16:22:54:679 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Implement as a valid URI check with apr_uri_parse()?
- /* proxy */
-
-static char *msre_action_proxy_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:24:58:322 GMT-08:00
- 2008-01-11 :: 16:13:48:178 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.irrelevant
- item.severity.label.trivial
- I believe this is already done and comment needs removed.
- // TODO: Need to keep track of skipAfter IDs so we can insert placeholders after
- // we get to the real rule with that ID.
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 16:26:46:732 GMT-08:00
- 2008-01-04 :: 16:27:54:881 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.irrelevant
- item.severity.label.trivial
- I do not see a need to validate beyound what is already done in the init function.
- msre_action_skip_validate
-msre_action_skipAfter_validate
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:28:48:332 GMT-08:00
- 2008-01-04 :: 16:29:03:587 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Implement.
- /* phase */
-
-static char *msre_action_phase_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:51:52:029 GMT-08:00
- 2008-01-04 :: 17:03:32:872 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Probably should also calc length and validate a length > 0 instead of just checking NULL. Other checks would benefit from checking a length as well, so no harm in calculating that.
- if (value == NULL) {
- return apr_psprintf(engine->mp, "Missing ctl value for name: %s", name);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 16:56:10:995 GMT-08:00
- 2008-01-04 :: 16:59:47:800 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.irrelevant
- item.severity.label.trivial
- Why register init() if we do not use it?
- static apr_status_t msre_action_ctl_init(msre_engine *engine, msre_actionset *actionset,
- msre_action *action)
-{
- /* Do nothing. */
- return 1;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 17:00:49:340 GMT-08:00
- 2008-01-04 :: 17:02:15:141 GMT-08:00
-
- brian
- brian
- apache2/msc_logging.c
- item.type.label.programLogic
- item.severity.label.trivial
- This allows an empty string as a valid part. This misvalidates "ctl:auditLogParts=+", etc.
- is_valid_parts_specification
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 17:04:51:155 GMT-08:00
- 2008-01-11 :: 16:12:33:664 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.optimization
- item.severity.label.trivial
- Inner if's should be else if's.
- if (strcasecmp(name, "ruleEngine") == 0) {
- if (strcasecmp(value, "on") == 0) {
- msr->txcfg->is_enabled = MODSEC_ENABLED;
- msr->usercfg->is_enabled = MODSEC_ENABLED;
- }
-
- if (strcasecmp(value, "off") == 0) {
- msr->txcfg->is_enabled = MODSEC_DISABLED;
- msr->usercfg->is_enabled = MODSEC_DISABLED;
- }
-
- if (strcasecmp(value, "detectiononly") == 0) {
- msr->txcfg->is_enabled = MODSEC_DETECTION_ONLY;
- msr->usercfg->is_enabled = MODSEC_DETECTION_ONLY;
- }
-
- return 1;
- } else
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 17:05:44:757 GMT-08:00
- 2008-01-11 :: 16:12:12:876 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.optimization
- item.severity.label.trivial
- TODO needs looked into.
- if (strcasecmp(name, "auditEngine") == 0) {
- if (strcasecmp(value, "on") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_ON;
- msr->usercfg->auditlog_flag = AUDITLOG_ON;
- }
-
- if (strcasecmp(value, "off") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_OFF;
- msr->usercfg->auditlog_flag = AUDITLOG_OFF;
- }
-
- if (strcasecmp(value, "relevantonly") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_RELEVANT;
- msr->usercfg->auditlog_flag = AUDITLOG_RELEVANT;
- }
-
- msr_log(msr, 4, "Ctl: Set auditEngine to %d.", msr->txcfg->auditlog_flag); // TODO
-
- return 1;
- } else
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-04 :: 17:08:00:396 GMT-08:00
- 2008-01-11 :: 14:59:05:782 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- That warning quieter should be s++. An evil typo that was fixed in 2.1.x, but not trunk!
- while(*s != '\0') {
- if (*s != c) {
- *d++ = *s++;
- } else {
- (*s)++; /* parens quiet compiler warning */
- }
- }
- *d = '\0';
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-04 :: 17:13:11:886 GMT-08:00
- 2008-01-04 :: 17:13:40:681 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Should log an internal error here.
- else {
- /* ENH Should never happen, but log if it does. */
- return -1;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 11:14:40:912 GMT-08:00
- 2008-01-07 :: 11:15:54:834 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Should log a level 9 msg here.
- } else {
- /* We could not identify a valid macro so add it as text. */
- part = (msc_string *)apr_pcalloc(mptmp, sizeof(msc_string));
- if (part == NULL) return -1;
- part->value_len = p - text_start + 1; /* len(text)+len("%") */
- part->value = apr_pstrmemdup(mptmp, text_start, part->value_len);
- *(msc_string **)apr_array_push(arr) = part;
-
- next_text_start = p + 1;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 11:37:09:009 GMT-08:00
- 2008-01-07 :: 11:41:55:614 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Probably should use apr_strtoi64 where we can tell if there was an error in conversion since we are potentially taking a value from a macro expansion. Also may want to look for overflow.
- value += atoi(var_value);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 11:43:13:789 GMT-08:00
- 2008-01-11 :: 16:10:24:140 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.missing
- item.severity.label.trivial
- Missing error log needs implemented.
- } else {
- /* ENH Log warning detected variable name but no collection. */
- return 0;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 11:52:38:857 GMT-08:00
- 2008-01-07 :: 11:53:56:791 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Not sure why we would not want to deprecate a TX var. Further rules could use this even if TX is not persisted.
- /* IMP1 Add message TX variables cannot deprecate in value. */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 11:54:14:673 GMT-08:00
- 2008-01-11 :: 15:04:13:383 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Missing error log needs implemented.
- } else {
- /* ENH Log warning detected variable name but no collection. */
- return 0;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 12:03:17:626 GMT-08:00
- 2008-01-07 :: 23:10:15:221 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- The timeout is hardcoded to 3600. The docs state TIMEOUT is read-only, but this is not true. So, you can modify TIMEOUT.
- /* IMP1 Is the timeout hard-coded to 3600? */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 14:12:19:250 GMT-08:00
- 2008-01-07 :: 14:14:28:669 GMT-08:00
-
- brian
- brian
- apache2/msc_logging.c
- item.type.label.suggestion
- item.severity.label.trivial
- apr_dir_make_recursive will attempt to create the dir straight away and if that fails keep backing off a dir until it can start creating, so I see no need to cache. Besides, what happens if you cache, then someone deletes the path from outside apache?
- /* IMP1 Surely it would be more efficient to check the folders for
- * the audit log repository base path in the configuration phase, to reduce
- * the work we do on every request. Also, since our path depends on time,
- * we could cache the time we last checked and don't check if we know
- * the folder is there.
- */
- rc = apr_dir_make_recursive(entry_basename, CREATEMODE_DIR, msr->mp);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 14:24:02:378 GMT-08:00
- 2008-01-07 :: 14:50:55:762 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- We already have support for relative filenames, but cannot get to this data from here. This needs solved by passing more data to the validate function (cmd_parms rec). Maybe need a warning here stating we do not support them yet, or it might be confusing to users that we do not here but do elsewhere.
- /* TODO Support relative filenames. */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 14:33:59:432 GMT-08:00
- 2008-01-07 :: 15:59:35:056 GMT-08:00
-
- brian
- brian
- apache2/re.h
- item.type.label.suggestion
- item.severity.label.trivial
- Why not stored in op_param_data like @rx, etc. The param_data is used w/exec action for lua.
- /* Compiled Lua script. */
- msc_script *script;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 15:55:08:220 GMT-08:00
- 2008-01-07 :: 16:02:36:938 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- This assumes lua is the only type (which it is now), but should be re-writen with a script_rec stored in param_data.
- if (action->param_data != NULL) { /* Lua */
- msc_script *script = (msc_script *)action->param_data;
- char *my_error_msg = NULL;
-
- if (lua_execute(script, NULL, msr, rule, &my_error_msg) < 0) {
- msr_log(msr, 1, "%s", my_error_msg);
- return 0;
- }
- } else { /* Execute as shell script. */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 16:00:51:901 GMT-08:00
- 2008-01-07 :: 16:04:13:185 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Not sure using an extension is a good idea here. Better I think would be to specify a type: "exec:[type=]/path/to/file" as in "exec:lua=/path/to/script" and make param_data a script_rec with a type and value. Also we use the abstract param_data here vs using a specific field as in SecRuleScript.
- /* Process Lua scripts internally. */
- if (strlen(filename) > 4) {
- char *p = filename + strlen(filename) - 4;
- if ((p[0] == '.')&&(p[1] == 'l')&&(p[2] == 'u')&&(p[3] == 'a')) {
- /* It's a Lua script. */
- msc_script *script = NULL;
-
- /* Compile script. */
- char *msg = lua_compile(&script, filename, engine->mp);
- if (msg != NULL) return msg;
-
- action->param_data = script;
- }
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 16:08:53:365 GMT-08:00
- 2008-01-11 :: 15:25:58:269 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Should not log_escape the actions as they will get double escaped (once now and again when logged).
- } else {
- rule->unparsed = apr_psprintf(ruleset->mp, "SecRuleScript \"%s\" \"%s\"",
- script_filename, log_escape(ruleset->mp, actions));
- }
-
-
- item.resolution.label.invalidWontfix
- item.status.label.closed
-
-
-
- 2008-01-07 :: 16:17:58:895 GMT-08:00
- 2008-01-11 :: 15:26:18:631 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Should not log_escape the actions as they will get double escaped (once now and again when logged).
- /* Add the unparsed rule */
- if ((strcmp(SECACTION_TARGETS, targets) == 0) && (strcmp(SECACTION_ARGS, args) == 0)) {
- rule->unparsed = apr_psprintf(ruleset->mp, "SecAction \"%s\"",
- log_escape(ruleset->mp, actions));
- }
- else
- if ((strcmp(SECMARKER_TARGETS, targets) == 0)
- && (strcmp(SECMARKER_ARGS, args) == 0)
- && (strncmp(SECMARKER_BASE_ACTIONS, actions, strlen(SECMARKER_BASE_ACTIONS)) == 0))
- {
- rule->unparsed = apr_psprintf(ruleset->mp, "SecMarker \"%s\"",
- log_escape(ruleset->mp, actions + strlen(SECMARKER_BASE_ACTIONS)));
- }
- else {
- if (actions == NULL) {
- rule->unparsed = apr_psprintf(ruleset->mp, "SecRule \"%s\" \"%s\"",
- log_escape(ruleset->mp, targets), log_escape(ruleset->mp, args));
- } else {
- rule->unparsed = apr_psprintf(ruleset->mp, "SecRule \"%s\" \"%s\" \"%s\"",
- log_escape(ruleset->mp, targets), log_escape(ruleset->mp, args),
- log_escape(ruleset->mp, actions));
- }
- }
-
-
- item.resolution.label.invalidWontfix
- item.status.label.closed
-
-
-
- 2008-01-07 :: 16:22:43:295 GMT-08:00
- 2008-01-11 :: 15:26:48:665 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- No logging should be done here as we are passing the error_msg back to the parent and they are responsible for this.
- if (*error_msg != NULL) {
- /* ENH Shouldn't we log the problem? */
- return NULL;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 16:30:41:403 GMT-08:00
- 2008-01-07 :: 16:31:00:930 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.missing
- item.severity.label.trivial
- Need to log on failure.
- var = msre_create_var(ruleset, telts[i].key, telts[i].val, NULL, error_msg);
- if (var == NULL) return -1;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 16:36:31:466 GMT-08:00
- 2008-01-07 :: 16:36:54:189 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Should replace with isvarnamechar() if possible.
- while((*p != '\0')&&(*p != '|')&&(*p != ':')&&(*p != ',')&&(!isspace(*p))) p++; /* ENH replace with isvarnamechar() */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 16:39:21:316 GMT-08:00
- 2008-01-11 :: 15:28:02:997 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix or remove TODO.
- // TODO better 64-bit support here
- *error_msg = apr_psprintf(mp, "Missing closing quote at position %d: %s",
- (int)(p - text), text);
- free(value);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 16:39:47:318 GMT-08:00
- 2008-01-11 :: 15:28:24:355 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix or remove TODO.
- // TODO better 64-bit support here
- *error_msg = apr_psprintf(mp, "Invalid quoted pair at position %d: %s",
- (int)(p - text), text);
- free(value);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 16:40:15:634 GMT-08:00
- 2008-01-11 :: 16:07:58:168 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *d++ = *p++;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 16:40:43:464 GMT-08:00
- 2008-01-11 :: 16:07:34:306 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *d++ = *p++;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 20:46:50:832 GMT-08:00
- 2008-01-11 :: 16:06:54:324 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *ucs_chars++ = *c++;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 20:47:54:093 GMT-08:00
- 2008-01-11 :: 16:06:02:231 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *t++ = *p++;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 20:48:42:400 GMT-08:00
- 2008-01-11 :: 16:05:23:686 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.clarity
- item.severity.label.trivial
- Add parens for clarity.
- *d++ = *s++;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 21:42:51:192 GMT-08:00
- 2008-01-07 :: 21:44:12:097 GMT-08:00
-
- brian
- brian
- apache2/apache2_io.c
- item.type.label.programLogic
- item.severity.label.major
- Returning here may fail to free chunks data due to modsecurity_request_body_end() not being called.
- int rcbs = modsecurity_request_body_store(msr, buf, buflen, error_msg);
- if (rcbs < 0) {
- if (rcbs == -5) {
- *error_msg = apr_psprintf(msr->mp, "Requests body no files data length is larger than the "
- "configured limit (%lu).", msr->txcfg->reqbody_no_files_limit);
- return -5;
- }
-
- return -1;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 21:50:32:890 GMT-08:00
- 2008-01-07 :: 21:52:29:239 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.suggestion
- item.severity.label.major
- Good. This looks to solve the other issues noted as possible memory leaks in body chunk data due to modsecurity_request_body_end() not being called. Need to verify, though.
- /* Register TX cleanup */
- apr_pool_cleanup_register(msr->mp, msr, modsecurity_tx_cleanup, apr_pool_cleanup_null);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 21:59:33:579 GMT-08:00
- 2008-01-11 :: 15:29:21:240 GMT-08:00
-
- brian
- brian
- apache2/msc_util.c
- item.type.label.suggestion
- item.severity.label.trivial
- Actually, the parens are *required* for correctness, so remove the comments.
- (*invalid_count)++; /* parens quiet compiler warning */
- }
- } else {
- /* Not enough bytes available, copy the raw bytes. */
- *d++ = input[i++];
- count ++;
- (*invalid_count)++; /* parens quiet compiler warning */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 22:03:31:138 GMT-08:00
- 2008-01-07 :: 22:04:07:108 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.irrelevant
- item.severity.label.trivial
- Does not appear to be used anywhere.
- /**
- * Destroys an engine instance, releasing the consumed memory.
- */
-void msre_engine_destroy(msre_engine *engine) {
- /* Destroyed automatically by the parent pool.
- * apr_pool_destroy(engine->mp);
- */
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 22:04:22:398 GMT-08:00
- 2008-01-07 :: 22:04:35:724 GMT-08:00
-
- brian
- brian
- apache2/re.h
- item.type.label.irrelevant
- item.severity.label.trivial
- Does not appear to be used anywhere.
- void DSOLOCAL msre_engine_destroy(msre_engine *engine);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 22:23:48:909 GMT-08:00
- 2008-01-11 :: 16:04:30:061 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.clarity
- item.severity.label.trivial
- This version should be moved up next to the normal version.
- #if defined(PERFORMANCE_MEASUREMENT)
-apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr) {
- ...
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 22:30:42:215 GMT-08:00
- 2008-01-11 :: 16:02:09:916 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.missing
- item.severity.label.major
- Hmm, I thought this had already been fixed in trunk. Missing logging phase. Need to fix in 2.1.5 as well.
- /**
- * Removes from the ruleset all rules that match the given exception.
- */
-int msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re) {
- int count = 0;
-
- if (ruleset == NULL) return 0;
-
- count += msre_ruleset_phase_rule_remove_with_exception(ruleset, re, ruleset->phase_request_headers);
- count += msre_ruleset_phase_rule_remove_with_exception(ruleset, re, ruleset->phase_request_body);
- count += msre_ruleset_phase_rule_remove_with_exception(ruleset, re, ruleset->phase_response_headers);
- count += msre_ruleset_phase_rule_remove_with_exception(ruleset, re, ruleset->phase_response_body);
-
- return count;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 22:46:51:423 GMT-08:00
- 2008-01-11 :: 16:01:31:111 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.optimization
- item.severity.label.trivial
- Should move this to a static global for performance.
- static const char *const severities[] = {
- "EMERGENCY",
- "ALERT",
- "CRITICAL",
- "ERROR",
- "WARNING",
- "NOTICE",
- "INFO",
- "DEBUG",
- NULL,
- };
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-07 :: 22:49:04:822 GMT-08:00
- 2008-01-07 :: 22:49:16:740 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.suggestion
- item.severity.label.trivial
- Implement TODO.
- //TODO: restrict to 512 bytes
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-07 :: 22:51:40:727 GMT-08:00
- 2008-01-07 :: 22:53:13:118 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.optimization
- item.severity.label.trivial
- tags set to NULL would be a bit better as it would stop apr_pstrcat() earlier, but tags *must* remain last or wierd results.
- char *tags = "";
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-08 :: 11:44:13:484 GMT-08:00
- 2008-01-08 :: 11:45:29:864 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.optimization
- item.severity.label.trivial
- This causes two loops through the action list. Perhaps there is a more performant way to do these at the same time? Maybe split into two lists?
- /* Perform non-disruptive actions. */
- msre_perform_nondisruptive_actions(msr, rule, rule->actionset, mptmp);
-
- /* Perform disruptive actions, but only if
- * this rule is not part of a chain.
- */
- if (rule->actionset->is_chained == 0) {
- msre_perform_disruptive_actions(msr, rule, acting_actionset, mptmp, my_error_msg);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-08 :: 12:16:20:280 GMT-08:00
- 2008-01-11 :: 15:59:48:300 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.irrelevant
- item.severity.label.trivial
- These do not appear to be needed.
- tfnspath = NULL;
- tfnskey = NULL;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-08 :: 12:20:29:491 GMT-08:00
- 2008-01-11 :: 15:59:23:210 GMT-08:00
-
- brian
- brian
- apache2/re.c
- item.type.label.programLogic
- item.severity.label.major
- This does not appear to work as the tfnskey is not being built here. Need to build the tfnskey in this loop for this to work.
- /* check cache, saving the 'most complete' */
- crec = (msre_cache_rec *)apr_table_get(cachetab, tfnskey);
- if (crec != NULL) {
- last_crec = crec;
- last_cached_tfn = tfnscount;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-08 :: 21:29:14:889 GMT-08:00
- 2008-01-08 :: 21:30:41:759 GMT-08:00
-
- brian
- brian
- apache2/re_tfns.c
- item.type.label.optimization
- item.severity.label.trivial
- No need to set this on all. Only set it once when we find the first non-space char.
- (*rval)[i] = '\0';
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-08 :: 22:09:10:463 GMT-08:00
- 2008-01-11 :: 14:20:53:411 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- Indention off.
- return var_simple_generate_ex(var, vartab, mptmp,
- apr_pmemdup(mptmp,
- msr->matched_var->value,
- msr->matched_var->value_len),
- msr->matched_var->value_len);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-08 :: 22:09:35:664 GMT-08:00
- 2008-01-11 :: 14:21:28:242 GMT-08:00
-
- brian
- brian
- apache2/re_variables.c
- item.type.label.suggestion
- item.severity.label.trivial
- Indention off.
- return var_simple_generate_ex(var, vartab, mptmp,
- apr_pmemdup(mptmp,
- msr->matched_var->name,
- msr->matched_var->name_len),
- msr->matched_var->name_len);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 10:55:38:639 GMT-08:00
- 2008-01-11 :: 14:25:15:860 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.suggestion
- item.severity.label.trivial
- Remove comment.
- //return acmp_child_for_code(node, letter)
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:01:01:815 GMT-08:00
- 2008-01-11 :: 15:55:50:363 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change to #idef DEBUG_ACMP or similar.
- /* printf("%c ->left %c \n", node->node->letter, node->left->node->letter); */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:01:41:424 GMT-08:00
- 2008-01-11 :: 15:56:10:175 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change to #idef DEBUG_ACMP or similar.
- /* printf("%c ->right %c \n", node->node->letter, node->right->node->letter); */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:02:22:279 GMT-08:00
- 2008-01-11 :: 15:56:41:045 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change to #idef DEBUG_ACMP or similar.
- /* printf("fail direction: *%s* => *%s*\n", child->text, child->fail->text); */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:02:42:897 GMT-08:00
- 2008-01-11 :: 15:54:16:807 GMT-08:00
-
- brian
- brian
- apache2/acmp.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change to #idef DEBUG_ACMP or similar.
- /* printf("fail direction: *%s* => *%s*\n", node->text, node->fail->text); */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:10:25:157 GMT-08:00
- 2008-01-11 :: 14:24:57:212 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- The 'tag' and 'severity' metadata actions should be included. Some actions are missing from the log msg.
- /* Must NOT use metadata actions. */
- if ((rule->actionset->id != NOT_SET_P)
- ||(rule->actionset->rev != NOT_SET_P)
- ||(rule->actionset->msg != NOT_SET_P)
- ||(rule->actionset->logdata != NOT_SET_P))
- {
- return apr_psprintf(cmd->pool, "ModSecurity: Metadata actions (id, rev, msg) "
- " can only be specified by chain starter rules.");
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 11:18:38:672 GMT-08:00
- 2008-01-11 :: 14:29:49:134 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Probably should check we were able to allocate.
- msre_rule *phrule = apr_palloc(rule->ruleset->mp, sizeof(msre_rule));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:05:40:949 GMT-08:00
- 2008-01-11 :: 14:30:01:771 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Comment or remove.
- TODO
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:06:48:653 GMT-08:00
- 2008-01-11 :: 14:30:40:514 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- ENH instead of TODO
- TODO
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:09:17:114 GMT-08:00
- 2008-01-11 :: 14:31:50:812 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- The 'tag' and 'severity' metadata actions should be included. Some actions are missing from the log msg.
- /* Must not use metadata actions. */
- if ((dcfg->tmp_default_actionset->id != NOT_SET_P)
- ||(dcfg->tmp_default_actionset->rev != NOT_SET_P)
- ||(dcfg->tmp_default_actionset->msg != NOT_SET_P)
- ||(dcfg->tmp_default_actionset->logdata != NOT_SET_P))
- {
- return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must not "
- "contain any metadata actions (id, rev, msg).");
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:17:06:712 GMT-08:00
- 2008-01-11 :: 14:33:23:560 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or make ENH
- // TODO Validate encoding
- // return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyAccess: %s", p1);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:17:55:545 GMT-08:00
- 2008-01-09 :: 12:25:33:617 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.irrelevant
- item.severity.label.trivial
- Remove code?
- /*
-static const char *cmd_rule_import_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
- directory_config *dcfg = (directory_config *)_dcfg;
- rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
- re->type = RULE_EXCEPTION_IMPORT_ID;
- // TODO verify p1
- re->param = p1;
- *(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
-
- return NULL;
-}
-
-static const char *cmd_rule_import_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
- directory_config *dcfg = (directory_config *)_dcfg;
- rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
- re->type = RULE_EXCEPTION_IMPORT_MSG;
- // TODO verify p1
- re->param = p1;
- *(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
-
- return NULL;
-}
-*/
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:18:34:399 GMT-08:00
- 2008-01-11 :: 14:34:07:673 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix or TODO->ENH
- // TODO enforce format (letters, digits, ., _, -)
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:20:16:234 GMT-08:00
- 2008-01-11 :: 14:40:53:633 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Need to allow for relative filename based of rule file.
- /* -- Geo Lookup configuration -- */
-
-static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
- const char *p1)
-{
- char *error_msg;
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
- if (geo_init(dcfg, p1, &error_msg) <= 0) {
- return error_msg;
- }
-
- return NULL;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:22:58:798 GMT-08:00
- 2008-01-09 :: 12:23:11:462 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable?
- /* The NOT_SET indicator is -1, a signed long, and therfore
- * we cannot be >= the unsigned value of NOT_SET.
- */
- if ((unsigned long)intval >= (unsigned long)NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen must be less than: %lu", (unsigned long)NOT_SET);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:23:33:676 GMT-08:00
- 2008-01-09 :: 12:23:39:437 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable?
- /* The NOT_SET indicator is -1, a signed long, and therfore
- * we cannot be >= the unsigned value of NOT_SET.
- */
- if ((unsigned long)intval >= (unsigned long)NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen must be less than: %lu", (unsigned long)NOT_SET);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:24:06:001 GMT-08:00
- 2008-01-09 :: 12:24:23:994 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Could use strtol as Ivan has as well.
- intval = apr_atoi64(charval);
- if (errno == ERANGE) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen out of range: %s", charval);
- }
- if (intval < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen must be positive: %s", charval);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:24:37:453 GMT-08:00
- 2008-01-09 :: 12:24:42:462 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Could use strtol as Ivan has as well.
- intval = apr_atoi64(charval);
- if (errno == ERANGE) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen out of range: %s", charval);
- }
- if (intval < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen must be positive: %s", charval);
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:25:36:799 GMT-08:00
- 2008-01-09 :: 12:31:35:264 GMT-08:00
-
- brian
- brian
- apache2/apache2_io.c
- item.type.label.programLogic
- item.severity.label.major
- Remove code? It is actually used below, so need to verify.
- #if 0
-static void dummy_free_func(void *data) {}
-#endif
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:27:10:252 GMT-08:00
- 2008-01-09 :: 12:29:31:617 GMT-08:00
-
- brian
- brian
- apache2/apache2_io.c
- item.type.label.programLogic
- item.severity.label.major
- dummy_free_func() is defined where? It is ifdef'd out at the top of source, so need to verify it is valid.
- /* Do not make a copy of the data we received in the chunk. */
- bucket = apr_bucket_heap_create(chunk->data, chunk->length, dummy_free_func,
- f->r->connection->bucket_alloc);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:35:21:613 GMT-08:00
- 2008-01-09 :: 13:02:40:668 GMT-08:00
-
- brian
- brian
- apache2/apache2_io.c
- item.type.label.suggestion
- item.severity.label.trivial
- Yes, why do we ignore the rc - why have one at all?
- // TODO: Why ignore the return code here?
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 12:55:19:633 GMT-08:00
- 2008-01-11 :: 17:00:04:416 GMT-08:00
-
- brian
- brian
- apache2/msc_reqbody.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable way to format sizeof()?
- *error_msg = apr_psprintf(msr->mp, "Input filter: Failed to allocate %lu bytes for request body chunk.", (unsigned long)sizeof(msc_data_chunk));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:55:39:585 GMT-08:00
- 2008-01-11 :: 16:58:16:438 GMT-08:00
-
- brian
- brian
- apache2/msc_reqbody.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable way to format sizeof()?
- *error_msg = apr_psprintf(msr->mp, "Failed to allocate %lu bytes for request body disk chunk.", (unsigned long)sizeof(msc_data_chunk));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:56:05:302 GMT-08:00
- 2008-01-11 :: 16:57:58:049 GMT-08:00
-
- brian
- brian
- apache2/msc_reqbody.c
- item.type.label.suggestion
- item.severity.label.trivial
- Portable way to format sizeof()?
- *error_msg = apr_psprintf(msr->mp, "Failed to allocate %lu bytes for request body disk chunk.", (unsigned long)sizeof(msc_data_chunk));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:56:51:734 GMT-08:00
- 2008-01-11 :: 14:41:50:773 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- // TODO check whether the parameter is a valid MIME type of "null"
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:58:11:331 GMT-08:00
- 2008-01-11 :: 14:42:59:645 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecAction",
- cmd_action,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:58:29:461 GMT-08:00
- 2008-01-11 :: 14:46:15:813 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecDataDir",
- cmd_data_dir,
- NULL,
- CMD_SCOPE_MAIN,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:58:45:647 GMT-08:00
- 2008-01-11 :: 14:46:51:173 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecDefaultAction",
- cmd_default_action,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:59:03:959 GMT-08:00
- 2008-01-11 :: 14:47:05:294 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecResponseBodyLimit",
- cmd_response_body_limit,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 12:59:17:580 GMT-08:00
- 2008-01-11 :: 14:49:00:349 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecResponseBodyLimitAction",
- cmd_response_body_limit_action,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:00:04:205 GMT-08:00
- 2008-01-11 :: 14:50:22:367 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE23 (
- "SecRule",
- cmd_rule,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:00:30:606 GMT-08:00
- 2008-01-11 :: 14:51:16:772 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE12 (
- "SecRuleScript",
- cmd_rule_script,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
- AP_INIT_ITERATE (
- "SecRuleRemoveById",
- cmd_rule_remove_by_id,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
- AP_INIT_ITERATE (
- "SecRuleRemoveByMsg",
- cmd_rule_remove_by_msg,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:00:56:319 GMT-08:00
- 2008-01-11 :: 14:52:48:192 GMT-08:00
-
- brian
- brian
- apache2/apache2_config.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- AP_INIT_TAKE1 (
- "SecTmpDir",
- cmd_tmp_dir,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
- AP_INIT_TAKE1 (
- "SecUploadDir",
- cmd_upload_dir,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
- AP_INIT_TAKE1 (
- "SecUploadKeepFiles",
- cmd_upload_keep_files,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
- AP_INIT_TAKE1 (
- "SecWebAppId",
- cmd_web_app_id,
- NULL,
- CMD_SCOPE_ANY,
- "" // TODO
- ),
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:01:32:996 GMT-08:00
- 2008-01-11 :: 14:54:32:209 GMT-08:00
-
- brian
- brian
- apache2/mod_security2.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- /* Update the request headers. They might have changed after
- * the body was read (trailers).
- */
- // TODO We still need to keep a copy of the original headers
- // to log in the audit log.
- msr->request_headers = apr_table_copy(msr->mp, r->headers_in);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:02:05:035 GMT-08:00
- 2008-01-09 :: 13:02:47:482 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.suggestion
- item.severity.label.trivial
- Yes, why do we ignore the rc - why have one at all?
- // TODO: Why do we ignore return code here?
- modsecurity_request_body_clear(msr, &my_error_msg);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:03:24:928 GMT-08:00
- 2008-01-09 :: 13:04:49:633 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO.
- offset = -3;
- apr_file_seek(geo->db, APR_END, &offset);
- /* TODO check offset */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:04:20:937 GMT-08:00
- 2008-01-09 :: 13:04:39:295 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO.
- rc = apr_file_read_full(geo->db, &buf, 1, &nbytes);
- /* TODO: check rc */
- geo->dbtype = (int)buf[0];
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:05:16:204 GMT-08:00
- 2008-01-09 :: 13:05:27:720 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO.
- apr_file_seek(geo->db, APR_SET, &seekto);
- /* TODO: check rc */
- rc = apr_file_read_full(geo->db, &buf, (2 * reclen), &nbytes);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:05:58:953 GMT-08:00
- 2008-01-09 :: 13:06:03:494 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO.
- apr_file_seek(geo->db, APR_SET, &seekto);
- /* TODO: check rc */
- rc = apr_file_read_full(geo->db, &cbuf, sizeof(cbuf), &nbytes);
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:06:45:422 GMT-08:00
- 2008-01-11 :: 14:55:10:355 GMT-08:00
-
- brian
- brian
- apache2/msc_logging.c
- item.type.label.suggestion
- item.severity.label.trivial
- Fix TODO or change to ENH.
- /* The audit log storage directory should be explicitly
- * defined. But if it isn't try to write to the same
- * directory where the index file is placed. Of course,
- * it is *very* bad practice to allow the Apache user
- * to write to the same directory where a root user is
- * writing to but it's not us that's causing the problem
- * and there isn't anything we can do about that.
- *
- * TODO Actually there is something we can do! We will make
- * SecAuditStorageDir mandatory, ask the user to explicitly
- * define the storage location *and* refuse to work if the
- * index and the storage location are in the same folder.
- */
- if (msr->txcfg->auditlog_storage_dir == NULL) {
- entry_filename = file_dirname(msr->mp, msr->txcfg->auditlog_name);
- }
- else {
- entry_filename = msr->txcfg->auditlog_storage_dir;
- }
- if (entry_filename == NULL) return;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:07:22:398 GMT-08:00
- 2008-01-11 :: 14:55:42:896 GMT-08:00
-
- brian
- brian
- apache2/msc_logging.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change TODO to ENH.
- /* AUDITLOG_PART_UPLOADS */
- // TODO: Implement
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:08:02:613 GMT-08:00
- 2008-01-11 :: 15:51:28:546 GMT-08:00
-
- brian
- brian
- apache2/msc_lua.c
- item.type.label.missing
- item.severity.label.trivial
- Log an error.
- } else {
- // TODO Error
- return NULL;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:08:51:978 GMT-08:00
- 2008-01-09 :: 13:09:44:680 GMT-08:00
-
- brian
- brian
- apache2/msc_util.c
- item.type.label.suggestion
- item.severity.label.normal
- Fix TODO.
- char *resolve_relative_path(apr_pool_t *pool, const char *parent_filename, const char *filename) {
- if (filename == NULL) return NULL;
- // TODO Support paths on operating systems other than Unix.
- if (filename[0] == '/') return (char *)filename;
-
- return apr_pstrcat(pool, apr_pstrndup(pool, parent_filename,
- strlen(parent_filename) - strlen(apr_filepath_name_get(parent_filename))),
- filename, NULL);
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:10:22:786 GMT-08:00
- 2008-01-09 :: 13:10:31:982 GMT-08:00
-
- brian
- brian
- apache2/pdf_protect.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change from TODO to ENH.
- // TODO We need ID and REV values for the PDF XSS alert.
-
-// TODO It would be nice if the user could choose the ID/REV/SEVERITY/MESSAGE, etc.
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:10:53:181 GMT-08:00
- 2008-01-09 :: 13:11:06:931 GMT-08:00
-
- brian
- brian
- apache2/pdf_protect.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change from TODO to ENH.
- // TODO Should we look at err_headers_out too?
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:11:23:251 GMT-08:00
- 2008-01-09 :: 13:11:28:132 GMT-08:00
-
- brian
- brian
- apache2/pdf_protect.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change from TODO to ENH.
- // 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 ???
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:11:54:942 GMT-08:00
- 2008-01-09 :: 13:12:24:617 GMT-08:00
-
- brian
- brian
- apache2/pdf_protect.c
- item.type.label.missing
- item.severity.label.trivial
- Add the missing alert.
- // TODO Log alert
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:13:04:159 GMT-08:00
- 2008-01-09 :: 13:13:38:064 GMT-08:00
-
- brian
- brian
- apache2/re_actions.c
- item.type.label.suggestion
- item.severity.label.trivial
- Not positive why the TODO here. Perhaps for a decision as to log and/or at what level?
- msr_log(msr, 4, "Ctl: Set auditEngine to %d.", msr->txcfg->auditlog_flag); // TODO
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:14:02:379 GMT-08:00
- 2008-01-11 :: 15:42:21:749 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change from TODO to ENH.
- // TODO Write & use string_ends(s, e).
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:14:29:571 GMT-08:00
- 2008-01-11 :: 15:43:53:997 GMT-08:00
-
- brian
- brian
- apache2/re_operators.c
- item.type.label.suggestion
- item.severity.label.trivial
- Remove the ifdef as lua is required?
- #ifdef WITH_LUA
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:17:47:759 GMT-08:00
- 2008-01-11 :: 15:41:12:538 GMT-08:00
-
- brian
- brian
- CHANGES
- item.type.label.suggestion
- item.severity.label.trivial
- Remove TODO.
- TODO: more to come
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 13:35:00:891 GMT-08:00
- 2008-01-09 :: 13:35:40:975 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.h
- item.type.label.optimization
- item.severity.label.trivial
- Need to re-test implementing this as just a table.
- /* data cache */
- apr_hash_t *tcache;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 13:37:04:264 GMT-08:00
- 2008-01-09 :: 13:37:25:196 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.h
- item.type.label.suggestion
- item.severity.label.trivial
- Should probably use STRINGIFY and define the numeric value.
- #define MODSEC_VERSION_MAJOR "2"
-#define MODSEC_VERSION_MINOR "5"
-#define MODSEC_VERSION_MAINT "0"
-#define MODSEC_VERSION_TYPE "rc"
-#define MODSEC_VERSION_RELEASE "1"
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 14:08:14:025 GMT-08:00
- 2008-01-11 :: 15:40:12:054 GMT-08:00
-
- brian
- brian
- apache2/msc_logging.c
- item.type.label.suggestion
- item.severity.label.trivial
- Spelling.
- throught
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-09 :: 14:21:32:782 GMT-08:00
- 2008-01-09 :: 14:22:32:803 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.h
- item.type.label.suggestion
- item.severity.label.trivial
- This value may not be portable based on endianness. The algorithm compares it to the IP address as int in host order.
- #define GEO_COUNTRY_OFFSET 0xffff00
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 14:31:25:720 GMT-08:00
- 2008-01-09 :: 14:45:20:612 GMT-08:00
-
- brian
- brian
- apache2/msc_geo.c
- item.type.label.suggestion
- item.severity.label.trivial
- Check portability due to endianness. It seems that the DB values are assumed to be in host order. Perhaps the compiled DB is little-endian and we need to compensate?
-
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 15:28:14:563 GMT-08:00
- 2008-01-09 :: 15:28:24:203 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.irrelevant
- item.severity.label.trivial
- Remove code?
- #if 0
-static char *multipart_construct_filename(modsec_rec *msr) {
- char c, *p, *q = msr->mpd->mpp->filename;
- char *filename;
-
- /* find the last backward slash and consider the
- * filename to be only what's right from it
- */
- p = strrchr(q, '\\');
- if (p != NULL) q = p + 1;
-
- /* do the same for the forward slash */
- p = strrchr(q, '/');
- if (p != NULL) q = p + 1;
-
- /* allow letters, digits and dots, replace
- * everything else with underscores
- */
- p = filename = apr_pstrdup(msr->mp, q);
- while((c = *p) != 0) {
- if (!( isalnum(c)||(c == '.') )) *p = '_';
- p++;
- }
-
- return filename;
-}
-#endif
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 15:35:50:978 GMT-08:00
- 2008-01-09 :: 15:49:54:128 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.programLogic
- item.severity.label.trivial
- The multipart C-D header is case insensitive (rfc 2183), so we should probably use strncasecmp() here.
- /* accept only what we understand */
- if (strncmp(c_d_value, "form-data", 9) != 0) {
- return -1;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 16:05:05:601 GMT-08:00
- 2008-01-09 :: 16:07:17:436 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- This allows for a name of "", so maybe check for name[0] == '\0' and return an error. Although we catch this later on as an unrecognized name and return -10.
- start = p;
- while((*p != '\0')&&(*p != '=')&&(*p != '\t')&&(*p != ' ')) p++;
- if (*p == '\0') return -4;
-
- name = apr_pstrmemdup(msr->mp, start, (p - start));
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 16:14:36:307 GMT-08:00
- 2008-01-09 :: 17:02:47:324 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- For a quoted value we just include everything until the end quote. The field values should be US-ASCII 'qtext' or 'quoted-pair' (RFC 822) or escaped using RFC 2047.
- if (*p == '"') {
- *t = '\0';
- break;
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 16:59:12:520 GMT-08:00
- 2008-01-09 :: 17:00:55:566 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- I think this is wrong. RFC 822 defines a quoted-string as <"> *(qtext/quoted-pair) <"> and quoted-par being able to quote any CHAR.
- /* only " and \ can be escaped */
- if ((*(p + 1) == '"')||(*(p + 1) == '\\')) {
- p++;
- }
- else {
- /* improper escaping */
-
- /* We allow for now because IE sends
- * improperly escaped content and there's
- * nothing we can do about it.
- *
- * return -9;
- */
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-09 :: 17:04:30:357 GMT-08:00
- 2008-01-09 :: 17:05:19:369 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- RFC 2045 defines an 'attribute' as "ALWAYS case-insensitive", so these should be strncasecmp()
- if (strcmp(name, "name") == 0) {
- if (msr->mpd->mpp->name != NULL) return -14;
- msr->mpd->mpp->name = value;
-
- if (msr->txcfg->debuglog_level >= 9) {
- msr_log(msr, 9, "Multipart: Content-Disposition name: %s",
- log_escape_nq(msr->mp, value));
- }
- }
- else
- if (strcmp(name, "filename") == 0) {
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 12:24:59:317 GMT-08:00
- 2008-01-11 :: 16:58:44:275 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- len is always assumed to be at least 1. What is preventing a len of 0?
- if (len > 1) {
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 12:27:34:472 GMT-08:00
- 2008-01-11 :: 15:39:17:001 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- Use MULTIPART_BUF_SIZE for the constant.
- if (strlen(new_value) > 4096) {
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 13:04:27:048 GMT-08:00
- 2008-01-10 :: 13:04:57:229 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- Cannot find anything that supports that this is or is not allowed.
- /* Flag for whitespace after parameter name. */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:05:06:226 GMT-08:00
- 2008-01-10 :: 13:05:11:552 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- Cannot find anything that supports that this is or is not allowed.
- /* Flag for whitespace before parameter value. */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:12:20:299 GMT-08:00
- 2008-01-11 :: 15:38:39:261 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- Use '\r' vs 0x0d as is done elsewhere.
- if ((c == 0x0d)&&(msr->mpd->bufleft == 1)) {
- /* we don't want to take 0x0d as the last byte in the buffer */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 13:12:54:295 GMT-08:00
- 2008-01-11 :: 15:36:43:726 GMT-08:00
-
- brian
- brian
- apache2/msc_multipart.c
- item.type.label.suggestion
- item.severity.label.trivial
- Use '\n' vs 0x0a as is done elsewhere.
- if ((c == 0x0a)||(msr->mpd->bufleft == 0)||(process_buffer)) {
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 13:19:16:539 GMT-08:00
- 2008-01-11 :: 15:35:53:104 GMT-08:00
-
- brian
- brian
- apache2/msc_parsers.c
- item.type.label.suggestion
- item.severity.label.trivial
- Headers are not used. I think they were added for iconv support, but Ivan removed it.
- #include "iconv.h"
-#include <errno.h>
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 13:26:56:609 GMT-08:00
- 2008-01-10 :: 13:27:21:817 GMT-08:00
-
- brian
- brian
- apache2/msc_util.c
- item.type.label.suggestion
- item.severity.label.trivial
- Be more consistent in naming.
- #define VALID_HEX(X) (((X >= '0')&&(X <= '9')) || ((X >= 'a')&&(X <= 'f')) || ((X >= 'A')&&(X <= 'F')))
-#define ISODIGIT(X) ((X >= '0')&&(X <= '7'))
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:32:29:278 GMT-08:00
- 2008-01-11 :: 16:51:13:950 GMT-08:00
-
- brian
- brian
- apache2/msc_util.c
- item.type.label.optimization
- item.severity.label.trivial
- No need to do a strlen twice *and* loop through the string. Just loop and exit on non-space.
- if (strlen(string) == 0) return 1;
-
- for(i = 0; i < strlen(string); i++) {
- if (!isspace(string[i])) {
- return 0;
- }
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
- 2008-01-10 :: 13:35:40:307 GMT-08:00
- 2008-01-10 :: 13:36:03:933 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.irrelevant
- item.severity.label.trivial
- Remove commented code?
- /* Serial audit log mutext */
- rc = apr_global_mutex_create(&msce->auditlog_lock, NULL, APR_LOCK_DEFAULT, mp);
- if (rc != APR_SUCCESS) {
- //ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "mod_security: Could not create modsec_auditlog_lock");
- //return HTTP_INTERNAL_SERVER_ERROR;
- return -1;
- }
-
- #ifdef __SET_MUTEX_PERMS
- rc = unixd_set_global_mutex_perms(msce->auditlog_lock);
- if (rc != APR_SUCCESS) {
- // ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "mod_security: Could not set permissions on modsec_auditlog_lock; check User and Group directives");
- // return HTTP_INTERNAL_SERVER_ERROR;
- return -1;
- }
- #endif
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:36:28:229 GMT-08:00
- 2008-01-10 :: 13:36:52:702 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.suggestion
- item.severity.label.trivial
- What *should* we do on error here?
- if (rc != APR_SUCCESS) {
- // ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to child-init auditlog mutex");
- }
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:37:17:326 GMT-08:00
- 2008-01-10 :: 13:37:25:682 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.suggestion
- item.severity.label.trivial
- This does nothing.
- /**
- * Releases resources held by engine instance.
- */
-void modsecurity_shutdown(msc_engine *msce) {
- if (msce == NULL) return;
-}
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:39:01:265 GMT-08:00
- 2008-01-10 :: 13:39:22:070 GMT-08:00
-
- brian
- brian
- apache2/modsecurity.c
- item.type.label.suggestion
- item.severity.label.trivial
- Figure out the optimal initial size for the arrays/tables.
- /* Collections. */
- msr->tx_vars = apr_table_make(msr->mp, 32);
- if (msr->tx_vars == NULL) return -1;
-
- msr->geo_vars = apr_table_make(msr->mp, 8);
- if (msr->geo_vars == NULL) return -1;
-
- msr->collections = apr_table_make(msr->mp, 8);
- if (msr->collections == NULL) return -1;
- msr->collections_dirty = apr_table_make(msr->mp, 8);
- if (msr->collections_dirty == NULL) return -1;
-
- /* Other */
- msr->tcache = apr_hash_make(msr->mp);
- if (msr->tcache == NULL) return -1;
-
- msr->matched_rules = apr_array_make(msr->mp, 16, sizeof(void *));
- if (msr->matched_rules == NULL) return -1;
-
- msr->matched_var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
- if (msr->matched_var == NULL) return -1;
-
- msr->highest_severity = 255; /* high, invalid value */
-
- msr->removed_rules = apr_array_make(msr->mp, 16, sizeof(char *));
- if (msr->removed_rules == NULL) return -1;
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:42:33:518 GMT-08:00
- 2008-01-10 :: 13:42:50:351 GMT-08:00
-
- brian
- brian
- apache2/msc_xml.c
- item.type.label.suggestion
- item.severity.label.trivial
- Remove #if 0'd code?
- #if 0
-static void xml_receive_sax_error(void *data, const char *msg, ...) {
- modsec_rec *msr = (modsec_rec *)data;
- char message[256];
-
- if (msr == NULL) return;
-
- apr_snprintf(message, sizeof(message), "%s (line %d offset %d)",
- log_escape_nq(msr->mp, msr->xml->parsing_ctx->lastError.message),
- msr->xml->parsing_ctx->lastError.line,
- msr->xml->parsing_ctx->lastError.int2);
-
- msr_log(msr, 5, "XML: Parsing error: %s", message);
-}
-#endif
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:54:16:193 GMT-08:00
- 2008-01-10 :: 13:54:45:610 GMT-08:00
-
- brian
- brian
- apache2/mod_security2.c
- item.type.label.suggestion
- item.severity.label.trivial
- What is the history of this?
- /* Our own hook to handle RPC transactions (not used at the moment).
- * // ap_hook_handler(hook_handler, NULL, NULL, APR_HOOK_MIDDLE);
- */
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.open
-
-
-
- 2008-01-10 :: 13:56:58:413 GMT-08:00
- 2008-01-11 :: 15:34:14:676 GMT-08:00
-
- brian
- brian
- apache2/msc_lua.c
- item.type.label.suggestion
- item.severity.label.trivial
- Change C++ to C style comment.
- // Get the response from the script.
-
-
- item.resolution.label.validNeedsfixing
- item.status.label.resolved
-
-
-
diff --git a/review/pre-2.5-brian.txt b/review/pre-2.5-brian.txt
deleted file mode 100644
index 3f2f49f9..00000000
--- a/review/pre-2.5-brian.txt
+++ /dev/null
@@ -1,982 +0,0 @@
-File: apache2/apache2_config.c
-===================================================================
-[brian] Irrelevant @ 1251
-
-Remove code?
-
-/*
-static const char *cmd_rule_import_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
- directory_config *dcfg = (directory_config *)_dcfg;
- rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
- re->type = RULE_EXCEPTION_IMPORT_ID;
- // TODO verify p1
- re->param = p1;
- *(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
-
- return NULL;
-}
-
-static const char *cmd_rule_import_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
- directory_config *dcfg = (directory_config *)_dcfg;
- rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
- re->type = RULE_EXCEPTION_IMPORT_MSG;
- // TODO verify p1
- re->param = p1;
- *(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
-
- return NULL;
-}
-*/
-
-
-[brian] Suggestion @ 1514
-
-Could use strtol as Ivan has as well.
-
-intval = apr_atoi64(charval);
- if (errno == ERANGE) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen out of range: %s", charval);
- }
- if (intval < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen must be positive: %s", charval);
- }
-
-
-[brian] Suggestion @ 1522
-
-Portable?
-
-/* The NOT_SET indicator is -1, a signed long, and therfore
- * we cannot be >= the unsigned value of NOT_SET.
- */
- if ((unsigned long)intval >= (unsigned long)NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations minlen must be less than: %lu", (unsigned long)NOT_SET);
- }
-
-
-[brian] Suggestion @ 1534
-
-Could use strtol as Ivan has as well.
-
-intval = apr_atoi64(charval);
- if (errno == ERANGE) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen out of range: %s", charval);
- }
- if (intval < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen must be positive: %s", charval);
- }
-
-
-[brian] Suggestion @ 1542
-
-Portable?
-
-/* The NOT_SET indicator is -1, a signed long, and therfore
- * we cannot be >= the unsigned value of NOT_SET.
- */
- if ((unsigned long)intval >= (unsigned long)NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecCacheTransformations maxlen must be less than: %lu", (unsigned long)NOT_SET);
- }
-
-
-
-File: apache2/apache2_io.c
-===================================================================
-[brian] ProgramLogic @ 17
-
-Remove code? It is actually used below, so need to verify.
-
-#if 0
-static void dummy_free_func(void *data) {}
-#endif
-
-
-[brian] ProgramLogic @ 92
-
-dummy_free_func() is defined where? It is ifdef'd out at the top of source, so need to verify it is valid.
-
-/* Do not make a copy of the data we received in the chunk. */
- bucket = apr_bucket_heap_create(chunk->data, chunk->length, dummy_free_func,
- f->r->connection->bucket_alloc);
-
-
-[brian] ProgramLogic @ 224
-
-Returning here may fail to free chunks data due to modsecurity_request_body_end() not being called.
-
-int rcbs = modsecurity_request_body_store(msr, buf, buflen, error_msg);
- if (rcbs < 0) {
- if (rcbs == -5) {
- *error_msg = apr_psprintf(msr->mp, "Requests body no files data length is larger than the "
- "configured limit (%lu).", msr->txcfg->reqbody_no_files_limit);
- return -5;
- }
-
- return -1;
- }
-
-
-[brian] Suggestion @ 246
-
-Yes, why do we ignore the rc - why have one at all?
-
-// TODO: Why ignore the return code here?
-
-
-
-File: apache2/mod_security2.c
-===================================================================
-[brian] Suggestion @ 1074
-
-What is the history of this?
-
-/* Our own hook to handle RPC transactions (not used at the moment).
- * // ap_hook_handler(hook_handler, NULL, NULL, APR_HOOK_MIDDLE);
- */
-
-
-
-File: apache2/modsecurity.c
-===================================================================
-[brian] Irrelevant @ 100
-
-Remove commented code?
-
-/* Serial audit log mutext */
- rc = apr_global_mutex_create(&msce->auditlog_lock, NULL, APR_LOCK_DEFAULT, mp);
- if (rc != APR_SUCCESS) {
- //ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "mod_security: Could not create modsec_auditlog_lock");
- //return HTTP_INTERNAL_SERVER_ERROR;
- return -1;
- }
-
- #ifdef __SET_MUTEX_PERMS
- rc = unixd_set_global_mutex_perms(msce->auditlog_lock);
- if (rc != APR_SUCCESS) {
- // ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "mod_security: Could not set permissions on modsec_auditlog_lock; check User and Group directives");
- // return HTTP_INTERNAL_SERVER_ERROR;
- return -1;
- }
- #endif
-
-
-[brian] Suggestion @ 126
-
-What *should* we do on error here?
-
-if (rc != APR_SUCCESS) {
- // ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, "Failed to child-init auditlog mutex");
- }
-
-
-[brian] Suggestion @ 132
-
-This does nothing.
-
-/**
- * Releases resources held by engine instance.
- */
-void modsecurity_shutdown(msc_engine *msce) {
- if (msce == NULL) return;
-}
-
-
-[brian] Suggestion @ 178
-
-Yes, why do we ignore the rc - why have one at all?
-
-// TODO: Why do we ignore return code here?
- modsecurity_request_body_clear(msr, &my_error_msg);
-
-
-[brian] Suggestion @ 196
-
-Good. This looks to solve the other issues noted as possible memory leaks in body chunk data due to modsecurity_request_body_end() not being called. Need to verify, though.
-
-/* Register TX cleanup */
- apr_pool_cleanup_register(msr->mp, msr, modsecurity_tx_cleanup, apr_pool_cleanup_null);
-
-
-[brian] Suggestion @ 298
-
-Figure out the optimal initial size for the arrays/tables.
-
-/* Collections. */
- msr->tx_vars = apr_table_make(msr->mp, 32);
- if (msr->tx_vars == NULL) return -1;
-
- msr->geo_vars = apr_table_make(msr->mp, 8);
- if (msr->geo_vars == NULL) return -1;
-
- msr->collections = apr_table_make(msr->mp, 8);
- if (msr->collections == NULL) return -1;
- msr->collections_dirty = apr_table_make(msr->mp, 8);
- if (msr->collections_dirty == NULL) return -1;
-
- /* Other */
- msr->tcache = apr_hash_make(msr->mp);
- if (msr->tcache == NULL) return -1;
-
- msr->matched_rules = apr_array_make(msr->mp, 16, sizeof(void *));
- if (msr->matched_rules == NULL) return -1;
-
- msr->matched_var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
- if (msr->matched_var == NULL) return -1;
-
- msr->highest_severity = 255; /* high, invalid value */
-
- msr->removed_rules = apr_array_make(msr->mp, 16, sizeof(char *));
- if (msr->removed_rules == NULL) return -1;
-
-
-
-File: apache2/modsecurity.h
-===================================================================
-[brian] Suggestion @ 63
-
-Should probably use STRINGIFY and define the numeric value.
-
-#define MODSEC_VERSION_MAJOR "2"
-#define MODSEC_VERSION_MINOR "5"
-#define MODSEC_VERSION_MAINT "0"
-#define MODSEC_VERSION_TYPE "rc"
-#define MODSEC_VERSION_RELEASE "1"
-
-
-[brian] Optimization @ 363
-
-Need to re-test implementing this as just a table.
-
-/* data cache */
- apr_hash_t *tcache;
-
-
-
-File: apache2/msc_geo.c
-===================================================================
-[brian] Suggestion
-
-Check portability due to endianness. It seems that the DB values are assumed to be in host order. Perhaps the compiled DB is little-endian and we need to compensate?
-
-
-[brian] Suggestion @ 153
-
-Fix TODO.
-
-offset = -3;
- apr_file_seek(geo->db, APR_END, &offset);
- /* TODO check offset */
-
-
-[brian] Suggestion @ 176
-
-Fix TODO.
-
-rc = apr_file_read_full(geo->db, &buf, 1, &nbytes);
- /* TODO: check rc */
- geo->dbtype = (int)buf[0];
-
-
-[brian] Suggestion @ 325
-
-Fix TODO.
-
-apr_file_seek(geo->db, APR_SET, &seekto);
- /* TODO: check rc */
- rc = apr_file_read_full(geo->db, &buf, (2 * reclen), &nbytes);
-
-
-[brian] Suggestion @ 374
-
-Fix TODO.
-
-apr_file_seek(geo->db, APR_SET, &seekto);
- /* TODO: check rc */
- rc = apr_file_read_full(geo->db, &cbuf, sizeof(cbuf), &nbytes);
-
-
-
-File: apache2/msc_geo.h
-===================================================================
-[brian] Suggestion @ 16
-
-This value may not be portable based on endianness. The algorithm compares it to the IP address as int in host order.
-
-#define GEO_COUNTRY_OFFSET 0xffff00
-
-
-
-File: apache2/msc_logging.c
-===================================================================
-[brian] ProgramLogic @ 235
-
-This allows an empty string as a valid part. This misvalidates "ctl:auditLogParts=+", etc.
-
-is_valid_parts_specification
-
-
-[brian] Suggestion @ 432
-
-apr_dir_make_recursive will attempt to create the dir straight away and if that fails keep backing off a dir until it can start creating, so I see no need to cache. Besides, what happens if you cache, then someone deletes the path from outside apache?
-
-/* IMP1 Surely it would be more efficient to check the folders for
- * the audit log repository base path in the configuration phase, to reduce
- * the work we do on every request. Also, since our path depends on time,
- * we could cache the time we last checked and don't check if we know
- * the folder is there.
- */
- rc = apr_dir_make_recursive(entry_basename, CREATEMODE_DIR, msr->mp);
-
-
-
-File: apache2/msc_multipart.c
-===================================================================
-[brian] Irrelevant @ 18
-
-Remove code?
-
-#if 0
-static char *multipart_construct_filename(modsec_rec *msr) {
- char c, *p, *q = msr->mpd->mpp->filename;
- char *filename;
-
- /* find the last backward slash and consider the
- * filename to be only what's right from it
- */
- p = strrchr(q, '\\');
- if (p != NULL) q = p + 1;
-
- /* do the same for the forward slash */
- p = strrchr(q, '/');
- if (p != NULL) q = p + 1;
-
- /* allow letters, digits and dots, replace
- * everything else with underscores
- */
- p = filename = apr_pstrdup(msr->mp, q);
- while((c = *p) != 0) {
- if (!( isalnum(c)||(c == '.') )) *p = '_';
- p++;
- }
-
- return filename;
-}
-#endif
-
-
-[brian] ProgramLogic @ 52
-
-The multipart C-D header is case insensitive (rfc 2183), so we should probably use strncasecmp() here.
-
-/* accept only what we understand */
- if (strncmp(c_d_value, "form-data", 9) != 0) {
- return -1;
- }
-
-
-[brian] Suggestion @ 75
-
-This allows for a name of "", so maybe check for name[0] == '\0' and return an error. Although we catch this later on as an unrecognized name and return -10.
-
-start = p;
- while((*p != '\0')&&(*p != '=')&&(*p != '\t')&&(*p != ' ')) p++;
- if (*p == '\0') return -4;
-
- name = apr_pstrmemdup(msr->mp, start, (p - start));
-
-
-[brian] Suggestion @ 106
-
-I think this is wrong. RFC 822 defines a quoted-string as <"> *(qtext/quoted-pair) <"> and quoted-par being able to quote any CHAR.
-
-/* only " and \ can be escaped */
- if ((*(p + 1) == '"')||(*(p + 1) == '\\')) {
- p++;
- }
- else {
- /* improper escaping */
-
- /* We allow for now because IE sends
- * improperly escaped content and there's
- * nothing we can do about it.
- *
- * return -9;
- */
- }
-
-
-[brian] Suggestion @ 122
-
-For a quoted value we just include everything until the end quote. The field values should be US-ASCII 'qtext' or 'quoted-pair' (RFC 822) or escaped using RFC 2047.
-
-if (*p == '"') {
- *t = '\0';
- break;
- }
-
-
-[brian] Suggestion @ 143
-
-RFC 2045 defines an 'attribute' as "ALWAYS case-insensitive", so these should be strncasecmp()
-
-if (strcmp(name, "name") == 0) {
- if (msr->mpd->mpp->name != NULL) return -14;
- msr->mpd->mpp->name = value;
-
- if (msr->txcfg->debuglog_level >= 9) {
- msr_log(msr, 9, "Multipart: Content-Disposition name: %s",
- log_escape_nq(msr->mp, value));
- }
- }
- else
- if (strcmp(name, "filename") == 0) {
-
-
-[brian] Suggestion @ 722
-
-Cannot find anything that supports that this is or is not allowed.
-
-/* Flag for whitespace after parameter name. */
-
-
-[brian] Suggestion @ 735
-
-Cannot find anything that supports that this is or is not allowed.
-
-/* Flag for whitespace before parameter value. */
-
-
-
-File: apache2/msc_util.c
-===================================================================
-[brian] Suggestion @ 24
-
-Be more consistent in naming.
-
-#define VALID_HEX(X) (((X >= '0')&&(X <= '9')) || ((X >= 'a')&&(X <= 'f')) || ((X >= 'A')&&(X <= 'F')))
-#define ISODIGIT(X) ((X >= '0')&&(X <= '7'))
-
-
-[brian] Suggestion @ 1186
-
-Fix TODO.
-
-char *resolve_relative_path(apr_pool_t *pool, const char *parent_filename, const char *filename) {
- if (filename == NULL) return NULL;
- // TODO Support paths on operating systems other than Unix.
- if (filename[0] == '/') return (char *)filename;
-
- return apr_pstrcat(pool, apr_pstrndup(pool, parent_filename,
- strlen(parent_filename) - strlen(apr_filepath_name_get(parent_filename))),
- filename, NULL);
-}
-
-
-
-File: apache2/msc_xml.c
-===================================================================
-[brian] Suggestion @ 27
-
-Remove #if 0'd code?
-
-#if 0
-static void xml_receive_sax_error(void *data, const char *msg, ...) {
- modsec_rec *msr = (modsec_rec *)data;
- char message[256];
-
- if (msr == NULL) return;
-
- apr_snprintf(message, sizeof(message), "%s (line %d offset %d)",
- log_escape_nq(msr->mp, msr->xml->parsing_ctx->lastError.message),
- msr->xml->parsing_ctx->lastError.line,
- msr->xml->parsing_ctx->lastError.int2);
-
- msr_log(msr, 5, "XML: Parsing error: %s", message);
-}
-#endif
-
-
-
-File: apache2/pdf_protect.c
-===================================================================
-[brian] Suggestion @ 26
-
-Change from TODO to ENH.
-
-// TODO We need ID and REV values for the PDF XSS alert.
-
-// TODO It would be nice if the user could choose the ID/REV/SEVERITY/MESSAGE, etc.
-
-
-[brian] Suggestion @ 217
-
-Change from TODO to ENH.
-
-// TODO Should we look at err_headers_out too?
-
-
-[brian] Suggestion @ 244
-
-Change from TODO to ENH.
-
-// 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 ???
-
-
-[brian] Missing @ 472
-
-Add the missing alert.
-
-// TODO Log alert
-
-
-
-File: apache2/re.c
-===================================================================
-[brian] Missing @ 47
-
-Need to log on failure.
-
-var = msre_create_var(ruleset, telts[i].key, telts[i].val, NULL, error_msg);
- if (var == NULL) return -1;
-
-
-[brian] Suggestion @ 297
-
-Should replace with isvarnamechar() if possible.
-
-while((*p != '\0')&&(*p != '|')&&(*p != ':')&&(*p != ',')&&(!isspace(*p))) p++; /* ENH replace with isvarnamechar() */
-
-
-[brian] Irrelevant @ 608
-
-Does not appear to be used anywhere.
-
-/**
- * Destroys an engine instance, releasing the consumed memory.
- */
-void msre_engine_destroy(msre_engine *engine) {
- /* Destroyed automatically by the parent pool.
- * apr_pool_destroy(engine->mp);
- */
-}
-
-
-[brian] Optimization @ 1150
-
-tags set to NULL would be a bit better as it would stop apr_pstrcat() earlier, but tags *must* remain last or wierd results.
-
-char *tags = "";
-
-
-[brian] Suggestion @ 1179
-
-Implement TODO.
-
-//TODO: restrict to 512 bytes
-
-
-[brian] Optimization @ 1528
-
-This causes two loops through the action list. Perhaps there is a more performant way to do these at the same time? Maybe split into two lists?
-
-/* Perform non-disruptive actions. */
- msre_perform_nondisruptive_actions(msr, rule, rule->actionset, mptmp);
-
- /* Perform disruptive actions, but only if
- * this rule is not part of a chain.
- */
- if (rule->actionset->is_chained == 0) {
- msre_perform_disruptive_actions(msr, rule, acting_actionset, mptmp, my_error_msg);
- }
-
-
-
-File: apache2/re.h
-===================================================================
-[brian] Irrelevant @ 86
-
-Does not appear to be used anywhere.
-
-void DSOLOCAL msre_engine_destroy(msre_engine *engine);
-
-
-[brian] Suggestion @ 148
-
-Why not stored in op_param_data like @rx, etc. The param_data is used w/exec action for lua.
-
-/* Compiled Lua script. */
- msc_script *script;
-
-
-
-File: apache2/re_actions.c
-===================================================================
-[brian] Optimization @ 170
-
-This implementation comment needs to be coded as many string operators now attempt to resolve macros.
-
-/* IMP1 Duplicate the string and create the array on
- * demand, thus not having to do it if there are
- * no macros in the input data.
- */
-
- data = apr_pstrdup(mptmp, var->value); /* IMP1 Are we modifying data anywhere? */
- arr = apr_array_make(mptmp, 16, sizeof(msc_string *));
- if ((data == NULL)||(arr == NULL)) return -1;
-
-
-[brian] Irrelevant @ 209
-
-This #if 0'd out code should be removed.
-
-/* Removed %0-9 macros as it messes up urlEncoding in the match
- * where having '%0a' will be treated as %{TX.0}a, which is incorrect.
- * */
-#if 0
- else if ((*(p + 1) >= '0')&&(*(p + 1) <= '9')) {
- /* Special case for regex captures. */
- var_name = "TX";
- var_value = apr_pstrmemdup(mptmp, p + 1, 1);
- next_text_start = p + 2;
- }
-#endif
-
-
-[brian] Suggestion @ 257
-
-Should log a level 9 msg here.
-
-} else {
- /* We could not identify a valid macro so add it as text. */
- part = (msc_string *)apr_pcalloc(mptmp, sizeof(msc_string));
- if (part == NULL) return -1;
- part->value_len = p - text_start + 1; /* len(text)+len("%") */
- part->value = apr_pstrmemdup(mptmp, text_start, part->value_len);
- *(msc_string **)apr_array_push(arr) = part;
-
- next_text_start = p + 1;
- }
-
-
-[brian] Optimization @ 276
-
-Use apr_array_pstrcat(msr->mp, arr, NULL) instead?
-
-/* If there's more than one member of the array that
- * means there was at least one macro present. Combine
- * text parts into a single string now.
- */
- if (arr->nelts > 1) {
- /* Figure out the required size for the string. */
- var->value_len = 0;
- for(i = 0; i < arr->nelts; i++) {
- part = ((msc_string **)arr->elts)[i];
- var->value_len += part->value_len;
- }
-
- /* Allocate the string. */
- var->value = apr_palloc(msr->mp, var->value_len + 1);
- if (var->value == NULL) return -1;
-
- /* Combine the parts. */
- offset = 0;
- for(i = 0; i < arr->nelts; i++) {
- part = ((msc_string **)arr->elts)[i];
- memcpy((char *)(var->value + offset), part->value, part->value_len);
- offset += part->value_len;
- }
- var->value[offset] = '\0';
- }
-
-
-[brian] Missing @ 402
-
-Implement. Need to check if Apache will return an invalid status code
-
-/* status */
-static char *msre_action_status_validate(msre_engine *engine, msre_action *action) {
- /* ENH action->param must be a valid HTTP status code. */
- return NULL;
-}
-
-
-[brian] Missing @ 422
-
-Implement.
-
-/* pause */
-static char *msre_action_pause_validate(msre_engine *engine, msre_action *action) {
- /* ENH Validate a positive number. */
- return NULL;
-}
-
-
-[brian] Missing @ 434
-
-Implement as a valid URI check with apr_uri_parse()?
-
-/* redirect */
-
-static char *msre_action_redirect_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
-[brian] Missing @ 465
-
-Implement as a valid URI check with apr_uri_parse()?
-
-/* proxy */
-
-static char *msre_action_proxy_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
-[brian] Irrelevant @ 507
-
-I do not see a need to validate beyound what is already done in the init function.
-
-msre_action_skip_validate
-msre_action_skipAfter_validate
-
-
-[brian] Missing @ 570
-
-Implement.
-
-/* phase */
-
-static char *msre_action_phase_validate(msre_engine *engine, msre_action *action) {
- /* ENH Add validation. */
- return NULL;
-}
-
-
-[brian] Suggestion @ 612
-
-Probably should also calc length and validate a length > 0 instead of just checking NULL. Other checks would benefit from checking a length as well, so no harm in calculating that.
-
-if (value == NULL) {
- return apr_psprintf(engine->mp, "Missing ctl value for name: %s", name);
- }
-
-
-[brian] Irrelevant @ 708
-
-Why register init() if we do not use it?
-
-static apr_status_t msre_action_ctl_init(msre_engine *engine, msre_actionset *actionset,
- msre_action *action)
-{
- /* Do nothing. */
- return 1;
-}
-
-
-[brian] Optimization @ 774
-
-TODO needs looked into.
-
-if (strcasecmp(name, "auditEngine") == 0) {
- if (strcasecmp(value, "on") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_ON;
- msr->usercfg->auditlog_flag = AUDITLOG_ON;
- }
-
- if (strcasecmp(value, "off") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_OFF;
- msr->usercfg->auditlog_flag = AUDITLOG_OFF;
- }
-
- if (strcasecmp(value, "relevantonly") == 0) {
- msr->txcfg->auditlog_flag = AUDITLOG_RELEVANT;
- msr->usercfg->auditlog_flag = AUDITLOG_RELEVANT;
- }
-
- msr_log(msr, 4, "Ctl: Set auditEngine to %d.", msr->txcfg->auditlog_flag); // TODO
-
- return 1;
- } else
-
-
-[brian] Suggestion @ 790
-
-Not positive why the TODO here. Perhaps for a decision as to log and/or at what level?
-
-msr_log(msr, 4, "Ctl: Set auditEngine to %d.", msr->txcfg->auditlog_flag); // TODO
-
-
-[brian] Missing @ 855
-
-Should log an internal error here.
-
-else {
- /* ENH Should never happen, but log if it does. */
- return -1;
- }
-
-
-[brian] Suggestion @ 1152
-
-Probably should use apr_strtoi64 where we can tell if there was an error in conversion since we are potentially taking a value from a macro expansion. Also may want to look for overflow.
-
-value += atoi(var_value);
-
-
-[brian] Suggestion @ 1288
-
-Not sure why we would not want to deprecate a TX var. Further rules could use this even if TX is not persisted.
-
-/* IMP1 Add message TX variables cannot deprecate in value. */
-
-
-[brian] Suggestion @ 1383
-
-The timeout is hardcoded to 3600. The docs state TIMEOUT is read-only, but this is not true. So, you can modify TIMEOUT.
-
-/* IMP1 Is the timeout hard-coded to 3600? */
-
-
-[brian] Suggestion @ 1555
-
-We already have support for relative filenames, but cannot get to this data from here. This needs solved by passing more data to the validate function (cmd_parms rec). Maybe need a warning here stating we do not support them yet, or it might be confusing to users that we do not here but do elsewhere.
-
-/* TODO Support relative filenames. */
-
-
-[brian] Suggestion @ 1557
-
-Not sure using an extension is a good idea here. Better I think would be to specify a type: "exec:[type=]/path/to/file" as in "exec:lua=/path/to/script" and make param_data a script_rec with a type and value. Also we use the abstract param_data here vs using a specific field as in SecRuleScript.
-
-/* Process Lua scripts internally. */
- if (strlen(filename) > 4) {
- char *p = filename + strlen(filename) - 4;
- if ((p[0] == '.')&&(p[1] == 'l')&&(p[2] == 'u')&&(p[3] == 'a')) {
- /* It's a Lua script. */
- msc_script *script = NULL;
-
- /* Compile script. */
- char *msg = lua_compile(&script, filename, engine->mp);
- if (msg != NULL) return msg;
-
- action->param_data = script;
- }
- }
-
-
-[brian] Suggestion @ 1578
-
-This assumes lua is the only type (which it is now), but should be re-writen with a script_rec stored in param_data.
-
-if (action->param_data != NULL) { /* Lua */
- msc_script *script = (msc_script *)action->param_data;
- char *my_error_msg = NULL;
-
- if (lua_execute(script, NULL, msr, rule, &my_error_msg) < 0) {
- msr_log(msr, 1, "%s", my_error_msg);
- return 0;
- }
- } else { /* Execute as shell script. */
-
-
-
-File: apache2/re_operators.c
-===================================================================
-[brian] Missing
-
-Need more unit tests for operators. Start with new operators.
-
-
-[brian] Suggestion @ 246
-
-Use resolve_relative_path() instead? Maybe a config_relative_path() to just get the path?
-
-/* 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)));
-
-
-[brian] Missing @ 310
-
-Need to check return code and log an error on failure.
-
-acmp_add_pattern(p, buf, NULL, NULL, strlen(buf));
-
-
-[brian] Missing @ 315
-
-Need to check return code and log an error on failure.
-
-acmp_prepare(p);
-
-
-[brian] Optimization @ 379
-
-See if apr_strmatch is faster.
-
-msre_op_within_execute
-
-
-[brian] Optimization @ 442
-
-See if apr_strmatch is faster.
-
-msre_op_contains_execute
-
-
-[brian] Optimization @ 506
-
-See if apr_strmatch is faster.
-
-msre_op_containsWord_execute
-
-
-[brian] Missing @ 1330
-
-Need an error_msg set for lua execution error.
-
-rc = lua_execute(script, target, msr, rule, error_msg);
- if (rc < 0) {
- /* Error. */
- return -1;
- }
-
-
-[brian] Missing @ 1477
-
-@validateurlEncoding does not output VAR name nor offset in error_msg on match.
-
-msre_op_validateUrlEncoding_execute
-
-
-[brian] Missing @ 1885
-
-@m operator is not documented. This does the same as @contains, so it was suggested earlier to use the @m algorithm for contains (if faster) and drop @m.
-
-/* m */
- msre_engine_op_register(engine,
- "m",
- msre_op_m_param_init,
- msre_op_m_execute
- );
-
-
-
-File: apache2/re_tfns.c
-===================================================================
-[brian] Optimization @ 77
-
-No need to set this on all. Only set it once when we find the first non-space char.
-
-(*rval)[i] = '\0';
-
-
-
diff --git a/review/review-summary.pl b/review/review-summary.pl
deleted file mode 100755
index 799f1672..00000000
--- a/review/review-summary.pl
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use XML::Simple;
-#use Data::Dumper;
-
-my $REVIEW = shift @ARGV;
-my %ISSUES = ();
-
-unless (defined $REVIEW) {
- print STDERR "Usage: $0 [ ... ]\n";
- exit 1;
-}
-
-# XML => hashref
-my $review = XMLin(
- $REVIEW,
- KeepRoot => 0,
- KeyAttr => { ReviewIssue => "+id" },
- ContentKey => "value",
- SuppressEmpty => undef,
-);
-#print Dumper($review);
-
-# Reorg hashref to be only open issues by filename
-for my $rec (values %{$review->{ReviewIssue} || {}}) {
- my $key = defined($rec->{File}->{value}) ? $rec->{File}->{value} : "";
- push @{$ISSUES{$key}}, $rec if ($rec->{Status} =~ m/\.open$/);
-}
-
-
-# Write report
-for my $fn (@ARGV ? (@ARGV) : (sort keys %ISSUES)) {
- print "File: $fn\n";
- print "===================================================================\n";
- for my $r (sort { $a->{File}->{line} <=> $b->{File}->{line} || $a->{ReviewerId} cmp $b->{ReviewerId} } @{$ISSUES{$fn} || []}) {
- (my $type = $r->{Type}) =~ s/^.*\.([^\.]+)$/$1/;
- $type = ucfirst($type);
- (my $res = $r->{Resolution}) =~ s/^.*\.([^\.]+)$/$1/;
- my $line = ($r->{File}->{line} and $r->{File}->{line} > 1) ? " @ $r->{File}->{line}" : "";
- my $summary = $r->{Summary} ? "\n$r->{Summary}\n\n" : "";
- my $desc = $r->{Description} ? "$r->{Description}\n\n" : "";
-
- print << "EOT";
-[$r->{ReviewerId}] $type$line
-$summary$desc
-EOT
- }
- print "\n";
-}
-