mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
6372 lines
319 KiB
HTML
6372 lines
319 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html dir="ltr" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"
|
||
lang="en"><head>
|
||
|
||
|
||
<meta name="sfhaproxy" content="NOFOOTER,NOHEADER">
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||
<meta name="generator" content="MediaWiki 1.15.1">
|
||
<meta name="robots" content="noindex,follow">
|
||
<meta name="keywords" content="Reference Manual">
|
||
<link rel="shortcut icon" href="http://sourceforge.net/favicon.ico">
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/opensearch_desc.php"
|
||
title="mod-security (en)">
|
||
<link rel="alternate" type="application/rss+xml" title="mod-security
|
||
RSS Feed"
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:RecentChanges&feed=rss">
|
||
<link rel="alternate" type="application/atom+xml" title="mod-security
|
||
Atom Feed"
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:RecentChanges&feed=atom">
|
||
<title>SourceForge.net: Reference Manual - mod-security</title>
|
||
<link rel="stylesheet" href="Reference_Manual_files/commonPrint.css"
|
||
type="text/css">
|
||
<link rel="stylesheet" href="Reference_Manual_files/index_003.css"
|
||
type="text/css">
|
||
<link rel="stylesheet" href="Reference_Manual_files/index.css"
|
||
type="text/css">
|
||
<link rel="stylesheet" href="Reference_Manual_files/index_004.css"
|
||
type="text/css">
|
||
<link rel="stylesheet" href="Reference_Manual_files/index_002.css"
|
||
type="text/css">
|
||
<!--[if lt IE 7]><script type="text/javascript" src="/apps/mediawiki/mod-security/skins/common/IEFixes.js?207"></script>
|
||
<meta http-equiv="imagetoolbar" content="no" /><![endif]-->
|
||
|
||
<script type="text/javascript">/*<![CDATA[*/
|
||
var skin = "sourceforge";
|
||
var stylepath = "/apps/mediawiki/mod-security/skins";
|
||
var wgArticlePath = "/apps/mediawiki/mod-security/index.php?title=$1";
|
||
var wgScriptPath = "/apps/mediawiki/mod-security";
|
||
var wgScript = "/apps/mediawiki/mod-security/index.php";
|
||
var wgVariantArticlePath = false;
|
||
var wgActionPaths = {};
|
||
var wgServer = "http://sourceforge.net";
|
||
var wgCanonicalNamespace = "";
|
||
var wgCanonicalSpecialPageName = false;
|
||
var wgNamespaceNumber = 0;
|
||
var wgPageName = "Reference_Manual";
|
||
var wgTitle = "Reference Manual";
|
||
var wgAction = "view";
|
||
var wgArticleId = "12";
|
||
var wgIsArticle = true;
|
||
var wgUserName = null;
|
||
var wgUserGroups = null;
|
||
var wgUserLanguage = "en";
|
||
var wgContentLanguage = "en";
|
||
var wgBreakFrames = false;
|
||
var wgCurRevisionId = 500;
|
||
var wgVersion = "1.15.1";
|
||
var wgEnableAPI = true;
|
||
var wgEnableWriteAPI = true;
|
||
var wgSeparatorTransformTable = ["", ""];
|
||
var wgDigitTransformTable = ["", ""];
|
||
var wgRestrictionEdit = [];
|
||
var wgRestrictionMove = [];
|
||
/*]]>*/</script>
|
||
|
||
<script type="text/javascript" src="Reference_Manual_files/wikibits.js"><!-- wikibits js --></script>
|
||
<!-- Head Scripts -->
|
||
<script type="text/javascript" src="Reference_Manual_files/ajax.js"></script>
|
||
<script type="text/javascript" src="Reference_Manual_files/index.php"><!-- site js --></script>
|
||
|
||
|
||
</head><body class="mediawiki ltr ns-0 ns-subject page-Reference_Manual
|
||
skin-sourceforge">
|
||
|
||
|
||
|
||
<div id="globalWrapper">
|
||
<div id="column-content">
|
||
<div id="content">
|
||
<a name="top" id="top"></a>
|
||
<h1 id="firstHeading" class="firstHeading">Reference Manual</h1>
|
||
<div id="bodyContent">
|
||
<h3 id="siteSub">From mod-security</h3>
|
||
<div id="contentSub"></div>
|
||
<div id="jump-to-nav">Jump to: <a href="#column-one">navigation</a>,
|
||
<a href="#searchInput">search</a></div> <!-- start content -->
|
||
<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div
|
||
id="toctitle"><h2>Contents</h2> <span class="toctoggle">[<a
|
||
href="javascript:toggleToc()" class="internal" id="togglelink">hide</a>]</span></div>
|
||
<ul>
|
||
<li class="toclevel-1"><a href="#ModSecurity.C2.AE_Reference_Manual"><span
|
||
class="tocnumber">1</span> <span class="toctext">ModSecurity® Reference
|
||
Manual</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#Current_as_of_v2.5.13_v2.6_and_v2.7"><span
|
||
class="tocnumber">1.1</span> <span class="toctext">Current as of
|
||
v2.5.13 v2.6 and v2.7</span></a>
|
||
<ul>
|
||
<li class="toclevel-3"><a
|
||
href="#Copyright_.C2.A9_2004-2011_Trustwave_Holdings.2C_Inc."><span
|
||
class="tocnumber">1.1.1</span> <span class="toctext">Copyright ©
|
||
2004-2011 Trustwave Holdings, Inc.</span></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Table_of_Contents"><span
|
||
class="tocnumber">2</span> <span class="toctext">Table of Contents</span></a></li>
|
||
<li class="toclevel-1"><a href="#Introduction"><span class="tocnumber">3</span>
|
||
<span class="toctext">Introduction</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#HTTP_Traffic_Logging"><span
|
||
class="tocnumber">3.1</span> <span class="toctext">HTTP Traffic Logging</span></a></li>
|
||
<li class="toclevel-2"><a
|
||
href="#Real-Time_Monitoring_and_Attack_Detection"><span
|
||
class="tocnumber">3.2</span> <span class="toctext">Real-Time Monitoring
|
||
and Attack Detection</span></a></li>
|
||
<li class="toclevel-2"><a href="#Attack_Prevention_and_Virtual_Patching"><span
|
||
class="tocnumber">3.3</span> <span class="toctext">Attack Prevention
|
||
and Virtual Patching</span></a></li>
|
||
<li class="toclevel-2"><a href="#Flexible_Rule_Engine"><span
|
||
class="tocnumber">3.4</span> <span class="toctext">Flexible Rule Engine</span></a></li>
|
||
<li class="toclevel-2"><a href="#Embedded-mode_Deployment"><span
|
||
class="tocnumber">3.5</span> <span class="toctext">Embedded-mode
|
||
Deployment</span></a></li>
|
||
<li class="toclevel-2"><a href="#Network-based_Deployment"><span
|
||
class="tocnumber">3.6</span> <span class="toctext">Network-based
|
||
Deployment</span></a></li>
|
||
<li class="toclevel-2"><a href="#Portability"><span class="tocnumber">3.7</span>
|
||
<span class="toctext">Portability</span></a></li>
|
||
<li class="toclevel-2"><a href="#Licensing"><span class="tocnumber">3.8</span>
|
||
<span class="toctext">Licensing</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a
|
||
href="#OWASP_ModSecurity_Core_Rule_Set_.28CRS.29_Project"><span
|
||
class="tocnumber">4</span> <span class="toctext">OWASP ModSecurity Core
|
||
Rule Set (CRS) Project</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#Overview"><span class="tocnumber">4.1</span>
|
||
<span class="toctext">Overview</span></a></li>
|
||
<li class="toclevel-2"><a href="#Core_Rules_Content"><span
|
||
class="tocnumber">4.2</span> <span class="toctext">Core Rules Content</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Installation"><span class="tocnumber">5</span>
|
||
<span class="toctext">Installation</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#Prerequisites"><span class="tocnumber">5.1</span>
|
||
<span class="toctext">Prerequisites</span></a>
|
||
<ul>
|
||
<li class="toclevel-3"><a
|
||
href="#ModSecurity_2.x_works_only_with_Apache_2.0.x_or_higher"><span
|
||
class="tocnumber">5.1.1</span> <span class="toctext">ModSecurity 2.x
|
||
works only with Apache 2.0.x or higher</span></a></li>
|
||
<li class="toclevel-3"><a href="#mod_uniqueid"><span class="tocnumber">5.1.2</span>
|
||
<span class="toctext">mod_uniqueid</span></a></li>
|
||
<li class="toclevel-3"><a href="#libapr_and_libapr-util"><span
|
||
class="tocnumber">5.1.3</span> <span class="toctext">libapr and
|
||
libapr-util</span></a></li>
|
||
<li class="toclevel-3"><a href="#libpcre"><span class="tocnumber">5.1.4</span>
|
||
<span class="toctext">libpcre</span></a></li>
|
||
<li class="toclevel-3"><a href="#libxml2"><span class="tocnumber">5.1.5</span>
|
||
<span class="toctext">libxml2</span></a></li>
|
||
<li class="toclevel-3"><a href="#liblua_v5.1.x"><span class="tocnumber">5.1.6</span>
|
||
<span class="toctext">liblua v5.1.x</span></a></li>
|
||
<li class="toclevel-3"><a href="#libcurl_v7.15.1_or_higher"><span
|
||
class="tocnumber">5.1.7</span> <span class="toctext">libcurl v7.15.1 or
|
||
higher</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-2"><a href="#Installation_Methods"><span
|
||
class="tocnumber">5.2</span> <span class="toctext">Installation Methods</span></a></li>
|
||
<li class="toclevel-2"><a href="#SVN_Access"><span class="tocnumber">5.3</span>
|
||
<span class="toctext">SVN Access</span></a></li>
|
||
<li class="toclevel-2"><a href="#Stable_Release_Download"><span
|
||
class="tocnumber">5.4</span> <span class="toctext">Stable Release
|
||
Download</span></a></li>
|
||
<li class="toclevel-2"><a href="#Installation_Steps"><span
|
||
class="tocnumber">5.5</span> <span class="toctext">Installation Steps</span></a>
|
||
<ul>
|
||
<li class="toclevel-3"><a href="#UNIX"><span class="tocnumber">5.5.1</span>
|
||
<span class="toctext">UNIX</span></a></li>
|
||
<li class="toclevel-3"><a href="#Windows_.28MS_VC.2B.2B_8.29"><span
|
||
class="tocnumber">5.5.2</span> <span class="toctext">Windows (MS VC++ 8)</span></a></li>
|
||
<li class="toclevel-3"><a
|
||
href="#Edit_the_main_Apache_httpd_config_file_.28usually_httpd.conf.29"><span
|
||
class="tocnumber">5.5.3</span> <span class="toctext">Edit the main
|
||
Apache httpd config file (usually httpd.conf)</span></a></li>
|
||
<li class="toclevel-3"><a href="#Configure_ModSecurity"><span
|
||
class="tocnumber">5.5.4</span> <span class="toctext">Configure
|
||
ModSecurity</span></a></li>
|
||
<li class="toclevel-3"><a href="#Start_Apache_httpd"><span
|
||
class="tocnumber">5.5.5</span> <span class="toctext">Start Apache httpd</span></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Configuration_Directives"><span
|
||
class="tocnumber">6</span> <span class="toctext">Configuration
|
||
Directives</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#SecAction"><span class="tocnumber">6.1</span>
|
||
<span class="toctext">SecAction</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecArgumentSeparator"><span
|
||
class="tocnumber">6.2</span> <span class="toctext">SecArgumentSeparator</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditEngine"><span class="tocnumber">6.3</span>
|
||
<span class="toctext">SecAuditEngine</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLog"><span class="tocnumber">6.4</span>
|
||
<span class="toctext">SecAuditLog</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLog2"><span class="tocnumber">6.5</span>
|
||
<span class="toctext">SecAuditLog2</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogDirMode"><span
|
||
class="tocnumber">6.6</span> <span class="toctext">SecAuditLogDirMode</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogFileMode"><span
|
||
class="tocnumber">6.7</span> <span class="toctext">SecAuditLogFileMode</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogParts"><span
|
||
class="tocnumber">6.8</span> <span class="toctext">SecAuditLogParts</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogRelevantStatus"><span
|
||
class="tocnumber">6.9</span> <span class="toctext">SecAuditLogRelevantStatus</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogStorageDir"><span
|
||
class="tocnumber">6.10</span> <span class="toctext">SecAuditLogStorageDir</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecAuditLogType"><span
|
||
class="tocnumber">6.11</span> <span class="toctext">SecAuditLogType</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecCacheTransformations"><span
|
||
class="tocnumber">6.12</span> <span class="toctext">SecCacheTransformations</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecChrootDir"><span class="tocnumber">6.13</span>
|
||
<span class="toctext">SecChrootDir</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecComponentSignature"><span
|
||
class="tocnumber">6.14</span> <span class="toctext">SecComponentSignature</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecContentInjection"><span
|
||
class="tocnumber">6.15</span> <span class="toctext">SecContentInjection</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecCookieFormat"><span
|
||
class="tocnumber">6.16</span> <span class="toctext">SecCookieFormat</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecDataDir"><span class="tocnumber">6.17</span>
|
||
<span class="toctext">SecDataDir</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecDebugLog"><span class="tocnumber">6.18</span>
|
||
<span class="toctext">SecDebugLog</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecDebugLogLevel"><span
|
||
class="tocnumber">6.19</span> <span class="toctext">SecDebugLogLevel</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecDefaultAction"><span
|
||
class="tocnumber">6.20</span> <span class="toctext">SecDefaultAction</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecDisableBackendCompression"><span
|
||
class="tocnumber">6.21</span> <span class="toctext">SecDisableBackendCompression</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecEncryptionEngine"><span
|
||
class="tocnumber">6.22</span> <span class="toctext">SecEncryptionEngine</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecEncryptionKey"><span
|
||
class="tocnumber">6.23</span> <span class="toctext">SecEncryptionKey</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecEncryptionParam"><span
|
||
class="tocnumber">6.24</span> <span class="toctext">SecEncryptionParam</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecEncryptionMethodRx"><span
|
||
class="tocnumber">6.25</span> <span class="toctext">SecEncryptionMethodRx</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecEncryptionMethodPm"><span
|
||
class="tocnumber">6.26</span> <span class="toctext">SecEncryptionMethodPm</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecGeoLookupDb"><span class="tocnumber">6.27</span>
|
||
<span class="toctext">SecGeoLookupDb</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecGsbLookupDb"><span class="tocnumber">6.28</span>
|
||
<span class="toctext">SecGsbLookupDb</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecGuardianLog"><span class="tocnumber">6.29</span>
|
||
<span class="toctext">SecGuardianLog</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecHttpBlKey"><span class="tocnumber">6.30</span>
|
||
<span class="toctext">SecHttpBlKey</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecInterceptOnError"><span
|
||
class="tocnumber">6.31</span> <span class="toctext">SecInterceptOnError</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecMarker"><span class="tocnumber">6.32</span>
|
||
<span class="toctext">SecMarker</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPcreMatchLimit"><span
|
||
class="tocnumber">6.33</span> <span class="toctext">SecPcreMatchLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPcreMatchLimitRecursion"><span
|
||
class="tocnumber">6.34</span> <span class="toctext">SecPcreMatchLimitRecursion</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPdfProtect"><span class="tocnumber">6.35</span>
|
||
<span class="toctext">SecPdfProtect</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPdfProtectMethod"><span
|
||
class="tocnumber">6.36</span> <span class="toctext">SecPdfProtectMethod</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPdfProtectSecret"><span
|
||
class="tocnumber">6.37</span> <span class="toctext">SecPdfProtectSecret</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPdfProtectTimeout"><span
|
||
class="tocnumber">6.38</span> <span class="toctext">SecPdfProtectTimeout</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecPdfProtectTokenName"><span
|
||
class="tocnumber">6.39</span> <span class="toctext">SecPdfProtectTokenName</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecReadStateLimit"><span
|
||
class="tocnumber">6.40</span> <span class="toctext">SecReadStateLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecSensorId"><span class="tocnumber">6.41</span>
|
||
<span class="toctext">SecSensorId</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecWriteStateLimit"><span
|
||
class="tocnumber">6.42</span> <span class="toctext">SecWriteStateLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRequestBodyAccess"><span
|
||
class="tocnumber">6.43</span> <span class="toctext">SecRequestBodyAccess</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRequestBodyInMemoryLimit"><span
|
||
class="tocnumber">6.44</span> <span class="toctext">SecRequestBodyInMemoryLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRequestBodyLimit"><span
|
||
class="tocnumber">6.45</span> <span class="toctext">SecRequestBodyLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRequestBodyNoFilesLimit"><span
|
||
class="tocnumber">6.46</span> <span class="toctext">SecRequestBodyNoFilesLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRequestBodyLimitAction"><span
|
||
class="tocnumber">6.47</span> <span class="toctext">SecRequestBodyLimitAction</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecResponseBodyLimit"><span
|
||
class="tocnumber">6.48</span> <span class="toctext">SecResponseBodyLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecResponseBodyLimitAction"><span
|
||
class="tocnumber">6.49</span> <span class="toctext">SecResponseBodyLimitAction</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecResponseBodyMimeType"><span
|
||
class="tocnumber">6.50</span> <span class="toctext">SecResponseBodyMimeType</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecResponseBodyMimeTypesClear"><span
|
||
class="tocnumber">6.51</span> <span class="toctext">SecResponseBodyMimeTypesClear</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecResponseBodyAccess"><span
|
||
class="tocnumber">6.52</span> <span class="toctext">SecResponseBodyAccess</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRule"><span class="tocnumber">6.53</span>
|
||
<span class="toctext">SecRule</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleInheritance"><span
|
||
class="tocnumber">6.54</span> <span class="toctext">SecRuleInheritance</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleEngine"><span class="tocnumber">6.55</span>
|
||
<span class="toctext">SecRuleEngine</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRulePerfTime"><span
|
||
class="tocnumber">6.56</span> <span class="toctext">SecRulePerfTime</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleRemoveById"><span
|
||
class="tocnumber">6.57</span> <span class="toctext">SecRuleRemoveById</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleRemoveByMsg"><span
|
||
class="tocnumber">6.58</span> <span class="toctext">SecRuleRemoveByMsg</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleRemoveByTag"><span
|
||
class="tocnumber">6.59</span> <span class="toctext">SecRuleRemoveByTag</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleScript"><span class="tocnumber">6.60</span>
|
||
<span class="toctext">SecRuleScript</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleUpdateActionById"><span
|
||
class="tocnumber">6.61</span> <span class="toctext">SecRuleUpdateActionById</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleUpdateTargetById"><span
|
||
class="tocnumber">6.62</span> <span class="toctext">SecRuleUpdateTargetById</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleUpdateTargetByMsg"><span
|
||
class="tocnumber">6.63</span> <span class="toctext">SecRuleUpdateTargetByMsg</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecRuleUpdateTargetByTag"><span
|
||
class="tocnumber">6.64</span> <span class="toctext">SecRuleUpdateTargetByTag</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecServerSignature"><span
|
||
class="tocnumber">6.65</span> <span class="toctext">SecServerSignature</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecStreamInBodyInspection"><span
|
||
class="tocnumber">6.66</span> <span class="toctext">SecStreamInBodyInspection</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecStreamOutBodyInspection"><span
|
||
class="tocnumber">6.67</span> <span class="toctext">SecStreamOutBodyInspection</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecTmpDir"><span class="tocnumber">6.68</span>
|
||
<span class="toctext">SecTmpDir</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUnicodeMapFile"><span
|
||
class="tocnumber">6.69</span> <span class="toctext">SecUnicodeMapFile</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUnicodeCodePage"><span
|
||
class="tocnumber">6.70</span> <span class="toctext">SecUnicodeCodePage</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUploadDir"><span class="tocnumber">6.71</span>
|
||
<span class="toctext">SecUploadDir</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUploadFileLimit"><span
|
||
class="tocnumber">6.72</span> <span class="toctext">SecUploadFileLimit</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUploadFileMode"><span
|
||
class="tocnumber">6.73</span> <span class="toctext">SecUploadFileMode</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecUploadKeepFiles"><span
|
||
class="tocnumber">6.74</span> <span class="toctext">SecUploadKeepFiles</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecWebAppId"><span class="tocnumber">6.75</span>
|
||
<span class="toctext">SecWebAppId</span></a></li>
|
||
<li class="toclevel-2"><a href="#SecCollectionTimeout"><span
|
||
class="tocnumber">6.76</span> <span class="toctext">SecCollectionTimeout</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Processing_Phases"><span
|
||
class="tocnumber">7</span> <span class="toctext">Processing Phases</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#Phase_Request_Headers"><span
|
||
class="tocnumber">7.1</span> <span class="toctext">Phase Request Headers</span></a></li>
|
||
<li class="toclevel-2"><a href="#Phase_Request_Body"><span
|
||
class="tocnumber">7.2</span> <span class="toctext">Phase Request Body</span></a></li>
|
||
<li class="toclevel-2"><a href="#Phase_Response_Headers"><span
|
||
class="tocnumber">7.3</span> <span class="toctext">Phase Response
|
||
Headers</span></a></li>
|
||
<li class="toclevel-2"><a href="#Phase_Response_Body"><span
|
||
class="tocnumber">7.4</span> <span class="toctext">Phase Response Body</span></a></li>
|
||
<li class="toclevel-2"><a href="#Phase_Logging"><span class="tocnumber">7.5</span>
|
||
<span class="toctext">Phase Logging</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Variables"><span class="tocnumber">8</span>
|
||
<span class="toctext">Variables</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#ARGS"><span class="tocnumber">8.1</span>
|
||
<span class="toctext">ARGS</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_COMBINED_SIZE"><span
|
||
class="tocnumber">8.2</span> <span class="toctext">ARGS_COMBINED_SIZE</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_GET"><span class="tocnumber">8.3</span>
|
||
<span class="toctext">ARGS_GET</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_GET_NAMES"><span class="tocnumber">8.4</span>
|
||
<span class="toctext">ARGS_GET_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_NAMES"><span class="tocnumber">8.5</span>
|
||
<span class="toctext">ARGS_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_POST"><span class="tocnumber">8.6</span>
|
||
<span class="toctext">ARGS_POST</span></a></li>
|
||
<li class="toclevel-2"><a href="#ARGS_POST_NAMES"><span
|
||
class="tocnumber">8.7</span> <span class="toctext">ARGS_POST_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#AUTH_TYPE"><span class="tocnumber">8.8</span>
|
||
<span class="toctext">AUTH_TYPE</span></a></li>
|
||
<li class="toclevel-2"><a href="#DURATION"><span class="tocnumber">8.9</span>
|
||
<span class="toctext">DURATION</span></a></li>
|
||
<li class="toclevel-2"><a href="#ENV"><span class="tocnumber">8.10</span>
|
||
<span class="toctext">ENV</span></a></li>
|
||
<li class="toclevel-2"><a href="#FILES"><span class="tocnumber">8.11</span>
|
||
<span class="toctext">FILES</span></a></li>
|
||
<li class="toclevel-2"><a href="#FILES_COMBINED_SIZE"><span
|
||
class="tocnumber">8.12</span> <span class="toctext">FILES_COMBINED_SIZE</span></a></li>
|
||
<li class="toclevel-2"><a href="#FILES_NAMES"><span class="tocnumber">8.13</span>
|
||
<span class="toctext">FILES_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#FILES_SIZES"><span class="tocnumber">8.14</span>
|
||
<span class="toctext">FILES_SIZES</span></a></li>
|
||
<li class="toclevel-2"><a href="#FILES_TMPNAMES"><span class="tocnumber">8.15</span>
|
||
<span class="toctext">FILES_TMPNAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#GEO"><span class="tocnumber">8.16</span>
|
||
<span class="toctext">GEO</span></a></li>
|
||
<li class="toclevel-2"><a href="#HIGHEST_SEVERITY"><span
|
||
class="tocnumber">8.17</span> <span class="toctext">HIGHEST_SEVERITY</span></a></li>
|
||
<li class="toclevel-2"><a href="#INBOUND_ERROR_DATA"><span
|
||
class="tocnumber">8.18</span> <span class="toctext">INBOUND_ERROR_DATA</span></a></li>
|
||
<li class="toclevel-2"><a href="#MATCHED_VAR"><span class="tocnumber">8.19</span>
|
||
<span class="toctext">MATCHED_VAR</span></a></li>
|
||
<li class="toclevel-2"><a href="#MATCHED_VARS"><span class="tocnumber">8.20</span>
|
||
<span class="toctext">MATCHED_VARS</span></a></li>
|
||
<li class="toclevel-2"><a href="#MATCHED_VAR_NAME"><span
|
||
class="tocnumber">8.21</span> <span class="toctext">MATCHED_VAR_NAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#MATCHED_VARS_NAMES"><span
|
||
class="tocnumber">8.22</span> <span class="toctext">MATCHED_VARS_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#MODSEC_BUILD"><span class="tocnumber">8.23</span>
|
||
<span class="toctext">MODSEC_BUILD</span></a></li>
|
||
<li class="toclevel-2"><a href="#MULTIPART_CRLF_LF_LINES"><span
|
||
class="tocnumber">8.24</span> <span class="toctext">MULTIPART_CRLF_LF_LINES</span></a></li>
|
||
<li class="toclevel-2"><a href="#MULTIPART_STRICT_ERROR"><span
|
||
class="tocnumber">8.25</span> <span class="toctext">MULTIPART_STRICT_ERROR</span></a></li>
|
||
<li class="toclevel-2"><a href="#MULTIPART_UNMATCHED_BOUNDARY"><span
|
||
class="tocnumber">8.26</span> <span class="toctext">MULTIPART_UNMATCHED_BOUNDARY</span></a></li>
|
||
<li class="toclevel-2"><a href="#PATH_INFO"><span class="tocnumber">8.27</span>
|
||
<span class="toctext">PATH_INFO</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_COMBINED"><span class="tocnumber">8.28</span>
|
||
<span class="toctext">PERF_COMBINED</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_GC"><span class="tocnumber">8.29</span>
|
||
<span class="toctext">PERF_GC</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_LOGGING"><span class="tocnumber">8.30</span>
|
||
<span class="toctext">PERF_LOGGING</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_PHASE1"><span class="tocnumber">8.31</span>
|
||
<span class="toctext">PERF_PHASE1</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_PHASE2"><span class="tocnumber">8.32</span>
|
||
<span class="toctext">PERF_PHASE2</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_PHASE3"><span class="tocnumber">8.33</span>
|
||
<span class="toctext">PERF_PHASE3</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_PHASE4"><span class="tocnumber">8.34</span>
|
||
<span class="toctext">PERF_PHASE4</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_PHASE5"><span class="tocnumber">8.35</span>
|
||
<span class="toctext">PERF_PHASE5</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_RULES"><span class="tocnumber">8.36</span>
|
||
<span class="toctext">PERF_RULES</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_SREAD"><span class="tocnumber">8.37</span>
|
||
<span class="toctext">PERF_SREAD</span></a></li>
|
||
<li class="toclevel-2"><a href="#PERF_SWRITE"><span class="tocnumber">8.38</span>
|
||
<span class="toctext">PERF_SWRITE</span></a></li>
|
||
<li class="toclevel-2"><a href="#QUERY_STRING"><span class="tocnumber">8.39</span>
|
||
<span class="toctext">QUERY_STRING</span></a></li>
|
||
<li class="toclevel-2"><a href="#REMOTE_ADDR"><span class="tocnumber">8.40</span>
|
||
<span class="toctext">REMOTE_ADDR</span></a></li>
|
||
<li class="toclevel-2"><a href="#REMOTE_HOST"><span class="tocnumber">8.41</span>
|
||
<span class="toctext">REMOTE_HOST</span></a></li>
|
||
<li class="toclevel-2"><a href="#REMOTE_PORT"><span class="tocnumber">8.42</span>
|
||
<span class="toctext">REMOTE_PORT</span></a></li>
|
||
<li class="toclevel-2"><a href="#REMOTE_USER"><span class="tocnumber">8.43</span>
|
||
<span class="toctext">REMOTE_USER</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQBODY_ERROR"><span class="tocnumber">8.44</span>
|
||
<span class="toctext">REQBODY_ERROR</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQBODY_ERROR_MSG"><span
|
||
class="tocnumber">8.45</span> <span class="toctext">REQBODY_ERROR_MSG</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQBODY_PROCESSOR"><span
|
||
class="tocnumber">8.46</span> <span class="toctext">REQBODY_PROCESSOR</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_BASENAME"><span
|
||
class="tocnumber">8.47</span> <span class="toctext">REQUEST_BASENAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_BODY"><span class="tocnumber">8.48</span>
|
||
<span class="toctext">REQUEST_BODY</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_BODY_LENGTH"><span
|
||
class="tocnumber">8.49</span> <span class="toctext">REQUEST_BODY_LENGTH</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_COOKIES"><span
|
||
class="tocnumber">8.50</span> <span class="toctext">REQUEST_COOKIES</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_COOKIES_NAMES"><span
|
||
class="tocnumber">8.51</span> <span class="toctext">REQUEST_COOKIES_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_FILENAME"><span
|
||
class="tocnumber">8.52</span> <span class="toctext">REQUEST_FILENAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_HEADERS"><span
|
||
class="tocnumber">8.53</span> <span class="toctext">REQUEST_HEADERS</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_HEADERS_NAMES"><span
|
||
class="tocnumber">8.54</span> <span class="toctext">REQUEST_HEADERS_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_LINE"><span class="tocnumber">8.55</span>
|
||
<span class="toctext">REQUEST_LINE</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_METHOD"><span class="tocnumber">8.56</span>
|
||
<span class="toctext">REQUEST_METHOD</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_PROTOCOL"><span
|
||
class="tocnumber">8.57</span> <span class="toctext">REQUEST_PROTOCOL</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_URI"><span class="tocnumber">8.58</span>
|
||
<span class="toctext">REQUEST_URI</span></a></li>
|
||
<li class="toclevel-2"><a href="#REQUEST_URI_RAW"><span
|
||
class="tocnumber">8.59</span> <span class="toctext">REQUEST_URI_RAW</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_BODY"><span class="tocnumber">8.60</span>
|
||
<span class="toctext">RESPONSE_BODY</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_CONTENT_LENGTH"><span
|
||
class="tocnumber">8.61</span> <span class="toctext">RESPONSE_CONTENT_LENGTH</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_CONTENT_TYPE"><span
|
||
class="tocnumber">8.62</span> <span class="toctext">RESPONSE_CONTENT_TYPE</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_HEADERS"><span
|
||
class="tocnumber">8.63</span> <span class="toctext">RESPONSE_HEADERS</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_HEADERS_NAMES"><span
|
||
class="tocnumber">8.64</span> <span class="toctext">RESPONSE_HEADERS_NAMES</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_PROTOCOL"><span
|
||
class="tocnumber">8.65</span> <span class="toctext">RESPONSE_PROTOCOL</span></a></li>
|
||
<li class="toclevel-2"><a href="#RESPONSE_STATUS"><span
|
||
class="tocnumber">8.66</span> <span class="toctext">RESPONSE_STATUS</span></a></li>
|
||
<li class="toclevel-2"><a href="#RULE"><span class="tocnumber">8.67</span>
|
||
<span class="toctext">RULE</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_BASENAME"><span
|
||
class="tocnumber">8.68</span> <span class="toctext">SCRIPT_BASENAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_FILENAME"><span
|
||
class="tocnumber">8.69</span> <span class="toctext">SCRIPT_FILENAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_GID"><span class="tocnumber">8.70</span>
|
||
<span class="toctext">SCRIPT_GID</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_GROUPNAME"><span
|
||
class="tocnumber">8.71</span> <span class="toctext">SCRIPT_GROUPNAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_MODE"><span class="tocnumber">8.72</span>
|
||
<span class="toctext">SCRIPT_MODE</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_UID"><span class="tocnumber">8.73</span>
|
||
<span class="toctext">SCRIPT_UID</span></a></li>
|
||
<li class="toclevel-2"><a href="#SCRIPT_USERNAME"><span
|
||
class="tocnumber">8.74</span> <span class="toctext">SCRIPT_USERNAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#SERVER_ADDR"><span class="tocnumber">8.75</span>
|
||
<span class="toctext">SERVER_ADDR</span></a></li>
|
||
<li class="toclevel-2"><a href="#SERVER_NAME"><span class="tocnumber">8.76</span>
|
||
<span class="toctext">SERVER_NAME</span></a></li>
|
||
<li class="toclevel-2"><a href="#SERVER_PORT"><span class="tocnumber">8.77</span>
|
||
<span class="toctext">SERVER_PORT</span></a></li>
|
||
<li class="toclevel-2"><a href="#SESSION"><span class="tocnumber">8.78</span>
|
||
<span class="toctext">SESSION</span></a></li>
|
||
<li class="toclevel-2"><a href="#SESSIONID"><span class="tocnumber">8.79</span>
|
||
<span class="toctext">SESSIONID</span></a></li>
|
||
<li class="toclevel-2"><a href="#STREAM_INPUT_BODY"><span
|
||
class="tocnumber">8.80</span> <span class="toctext">STREAM_INPUT_BODY</span></a></li>
|
||
<li class="toclevel-2"><a href="#STREAM_OUTPUT_BODY"><span
|
||
class="tocnumber">8.81</span> <span class="toctext">STREAM_OUTPUT_BODY</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME"><span class="tocnumber">8.82</span>
|
||
<span class="toctext">TIME</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_DAY"><span class="tocnumber">8.83</span>
|
||
<span class="toctext">TIME_DAY</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_EPOCH"><span class="tocnumber">8.84</span>
|
||
<span class="toctext">TIME_EPOCH</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_HOUR"><span class="tocnumber">8.85</span>
|
||
<span class="toctext">TIME_HOUR</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_MIN"><span class="tocnumber">8.86</span>
|
||
<span class="toctext">TIME_MIN</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_MON"><span class="tocnumber">8.87</span>
|
||
<span class="toctext">TIME_MON</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_SEC"><span class="tocnumber">8.88</span>
|
||
<span class="toctext">TIME_SEC</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_WDAY"><span class="tocnumber">8.89</span>
|
||
<span class="toctext">TIME_WDAY</span></a></li>
|
||
<li class="toclevel-2"><a href="#TIME_YEAR"><span class="tocnumber">8.90</span>
|
||
<span class="toctext">TIME_YEAR</span></a></li>
|
||
<li class="toclevel-2"><a href="#TX"><span class="tocnumber">8.91</span>
|
||
<span class="toctext">TX</span></a></li>
|
||
<li class="toclevel-2"><a href="#UNIQUE_ID"><span class="tocnumber">8.92</span>
|
||
<span class="toctext">UNIQUE_ID</span></a></li>
|
||
<li class="toclevel-2"><a href="#URLENCODED_ERROR"><span
|
||
class="tocnumber">8.93</span> <span class="toctext">URLENCODED_ERROR</span></a></li>
|
||
<li class="toclevel-2"><a href="#USERID"><span class="tocnumber">8.94</span>
|
||
<span class="toctext">USERID</span></a></li>
|
||
<li class="toclevel-2"><a href="#USERAGENT_IP"><span class="tocnumber">8.95</span>
|
||
<span class="toctext">USERAGENT_IP</span></a></li>
|
||
<li class="toclevel-2"><a href="#WEBAPPID"><span class="tocnumber">8.96</span>
|
||
<span class="toctext">WEBAPPID</span></a></li>
|
||
<li class="toclevel-2"><a href="#WEBSERVER_ERROR_LOG"><span
|
||
class="tocnumber">8.97</span> <span class="toctext">WEBSERVER_ERROR_LOG</span></a></li>
|
||
<li class="toclevel-2"><a href="#XML"><span class="tocnumber">8.98</span>
|
||
<span class="toctext">XML</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Transformation_functions"><span
|
||
class="tocnumber">9</span> <span class="toctext">Transformation
|
||
functions</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#base64Decode"><span class="tocnumber">9.1</span>
|
||
<span class="toctext">base64Decode</span></a></li>
|
||
<li class="toclevel-2"><a href="#sqlHexDecode"><span class="tocnumber">9.2</span>
|
||
<span class="toctext">sqlHexDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#base64DecodeExt"><span
|
||
class="tocnumber">9.3</span> <span class="toctext">base64DecodeExt</span></a></li>
|
||
<li class="toclevel-2"><a href="#base64Encode"><span class="tocnumber">9.4</span>
|
||
<span class="toctext">base64Encode</span></a></li>
|
||
<li class="toclevel-2"><a href="#cmdLine"><span class="tocnumber">9.5</span>
|
||
<span class="toctext">cmdLine</span></a></li>
|
||
<li class="toclevel-2"><a href="#compressWhitespace"><span
|
||
class="tocnumber">9.6</span> <span class="toctext">compressWhitespace</span></a></li>
|
||
<li class="toclevel-2"><a href="#cssDecode"><span class="tocnumber">9.7</span>
|
||
<span class="toctext">cssDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#escapeSeqDecode"><span
|
||
class="tocnumber">9.8</span> <span class="toctext">escapeSeqDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#hexDecode"><span class="tocnumber">9.9</span>
|
||
<span class="toctext">hexDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#hexEncode"><span class="tocnumber">9.10</span>
|
||
<span class="toctext">hexEncode</span></a></li>
|
||
<li class="toclevel-2"><a href="#htmlEntityDecode"><span
|
||
class="tocnumber">9.11</span> <span class="toctext">htmlEntityDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#jsDecode"><span class="tocnumber">9.12</span>
|
||
<span class="toctext">jsDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#length"><span class="tocnumber">9.13</span>
|
||
<span class="toctext">length</span></a></li>
|
||
<li class="toclevel-2"><a href="#lowercase"><span class="tocnumber">9.14</span>
|
||
<span class="toctext">lowercase</span></a></li>
|
||
<li class="toclevel-2"><a href="#md5"><span class="tocnumber">9.15</span>
|
||
<span class="toctext">md5</span></a></li>
|
||
<li class="toclevel-2"><a href="#none"><span class="tocnumber">9.16</span>
|
||
<span class="toctext">none</span></a></li>
|
||
<li class="toclevel-2"><a href="#normalisePath"><span class="tocnumber">9.17</span>
|
||
<span class="toctext">normalisePath</span></a></li>
|
||
<li class="toclevel-2"><a href="#normalisePathWin"><span
|
||
class="tocnumber">9.18</span> <span class="toctext">normalisePathWin</span></a></li>
|
||
<li class="toclevel-2"><a href="#parityEven7bit"><span class="tocnumber">9.19</span>
|
||
<span class="toctext">parityEven7bit</span></a></li>
|
||
<li class="toclevel-2"><a href="#parityOdd7bit"><span class="tocnumber">9.20</span>
|
||
<span class="toctext">parityOdd7bit</span></a></li>
|
||
<li class="toclevel-2"><a href="#parityZero7bit"><span class="tocnumber">9.21</span>
|
||
<span class="toctext">parityZero7bit</span></a></li>
|
||
<li class="toclevel-2"><a href="#removeNulls"><span class="tocnumber">9.22</span>
|
||
<span class="toctext">removeNulls</span></a></li>
|
||
<li class="toclevel-2"><a href="#removeWhitespace"><span
|
||
class="tocnumber">9.23</span> <span class="toctext">removeWhitespace</span></a></li>
|
||
<li class="toclevel-2"><a href="#replaceComments"><span
|
||
class="tocnumber">9.24</span> <span class="toctext">replaceComments</span></a></li>
|
||
<li class="toclevel-2"><a href="#removeCommentsChar"><span
|
||
class="tocnumber">9.25</span> <span class="toctext">removeCommentsChar</span></a></li>
|
||
<li class="toclevel-2"><a href="#removeComments"><span class="tocnumber">9.26</span>
|
||
<span class="toctext">removeComments</span></a></li>
|
||
<li class="toclevel-2"><a href="#replaceNulls"><span class="tocnumber">9.27</span>
|
||
<span class="toctext">replaceNulls</span></a></li>
|
||
<li class="toclevel-2"><a href="#urlDecode"><span class="tocnumber">9.28</span>
|
||
<span class="toctext">urlDecode</span></a></li>
|
||
<li class="toclevel-2"><a href="#urlDecodeUni"><span class="tocnumber">9.29</span>
|
||
<span class="toctext">urlDecodeUni</span></a></li>
|
||
<li class="toclevel-2"><a href="#urlEncode"><span class="tocnumber">9.30</span>
|
||
<span class="toctext">urlEncode</span></a></li>
|
||
<li class="toclevel-2"><a href="#sha1"><span class="tocnumber">9.31</span>
|
||
<span class="toctext">sha1</span></a></li>
|
||
<li class="toclevel-2"><a href="#trimLeft"><span class="tocnumber">9.32</span>
|
||
<span class="toctext">trimLeft</span></a></li>
|
||
<li class="toclevel-2"><a href="#trimRight"><span class="tocnumber">9.33</span>
|
||
<span class="toctext">trimRight</span></a></li>
|
||
<li class="toclevel-2"><a href="#trim"><span class="tocnumber">9.34</span>
|
||
<span class="toctext">trim</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Actions"><span class="tocnumber">10</span>
|
||
<span class="toctext">Actions</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#accuracy"><span class="tocnumber">10.1</span>
|
||
<span class="toctext">accuracy</span></a></li>
|
||
<li class="toclevel-2"><a href="#allow"><span class="tocnumber">10.2</span>
|
||
<span class="toctext">allow</span></a></li>
|
||
<li class="toclevel-2"><a href="#append"><span class="tocnumber">10.3</span>
|
||
<span class="toctext">append</span></a></li>
|
||
<li class="toclevel-2"><a href="#auditlog"><span class="tocnumber">10.4</span>
|
||
<span class="toctext">auditlog</span></a></li>
|
||
<li class="toclevel-2"><a href="#block"><span class="tocnumber">10.5</span>
|
||
<span class="toctext">block</span></a></li>
|
||
<li class="toclevel-2"><a href="#capture"><span class="tocnumber">10.6</span>
|
||
<span class="toctext">capture</span></a></li>
|
||
<li class="toclevel-2"><a href="#chain"><span class="tocnumber">10.7</span>
|
||
<span class="toctext">chain</span></a></li>
|
||
<li class="toclevel-2"><a href="#ctl"><span class="tocnumber">10.8</span>
|
||
<span class="toctext">ctl</span></a></li>
|
||
<li class="toclevel-2"><a href="#deny"><span class="tocnumber">10.9</span>
|
||
<span class="toctext">deny</span></a></li>
|
||
<li class="toclevel-2"><a href="#deprecatevar"><span class="tocnumber">10.10</span>
|
||
<span class="toctext">deprecatevar</span></a></li>
|
||
<li class="toclevel-2"><a href="#drop"><span class="tocnumber">10.11</span>
|
||
<span class="toctext">drop</span></a></li>
|
||
<li class="toclevel-2"><a href="#exec"><span class="tocnumber">10.12</span>
|
||
<span class="toctext">exec</span></a></li>
|
||
<li class="toclevel-2"><a href="#expirevar"><span class="tocnumber">10.13</span>
|
||
<span class="toctext">expirevar</span></a></li>
|
||
<li class="toclevel-2"><a href="#id"><span class="tocnumber">10.14</span>
|
||
<span class="toctext">id</span></a></li>
|
||
<li class="toclevel-2"><a href="#initcol"><span class="tocnumber">10.15</span>
|
||
<span class="toctext">initcol</span></a></li>
|
||
<li class="toclevel-2"><a href="#log"><span class="tocnumber">10.16</span>
|
||
<span class="toctext">log</span></a></li>
|
||
<li class="toclevel-2"><a href="#logdata"><span class="tocnumber">10.17</span>
|
||
<span class="toctext">logdata</span></a></li>
|
||
<li class="toclevel-2"><a href="#maturity"><span class="tocnumber">10.18</span>
|
||
<span class="toctext">maturity</span></a></li>
|
||
<li class="toclevel-2"><a href="#msg"><span class="tocnumber">10.19</span>
|
||
<span class="toctext">msg</span></a></li>
|
||
<li class="toclevel-2"><a href="#multiMatch"><span class="tocnumber">10.20</span>
|
||
<span class="toctext">multiMatch</span></a></li>
|
||
<li class="toclevel-2"><a href="#noauditlog"><span class="tocnumber">10.21</span>
|
||
<span class="toctext">noauditlog</span></a></li>
|
||
<li class="toclevel-2"><a href="#nolog"><span class="tocnumber">10.22</span>
|
||
<span class="toctext">nolog</span></a></li>
|
||
<li class="toclevel-2"><a href="#pass"><span class="tocnumber">10.23</span>
|
||
<span class="toctext">pass</span></a></li>
|
||
<li class="toclevel-2"><a href="#pause"><span class="tocnumber">10.24</span>
|
||
<span class="toctext">pause</span></a></li>
|
||
<li class="toclevel-2"><a href="#phase"><span class="tocnumber">10.25</span>
|
||
<span class="toctext">phase</span></a></li>
|
||
<li class="toclevel-2"><a href="#prepend"><span class="tocnumber">10.26</span>
|
||
<span class="toctext">prepend</span></a></li>
|
||
<li class="toclevel-2"><a href="#proxy"><span class="tocnumber">10.27</span>
|
||
<span class="toctext">proxy</span></a></li>
|
||
<li class="toclevel-2"><a href="#redirect"><span class="tocnumber">10.28</span>
|
||
<span class="toctext">redirect</span></a></li>
|
||
<li class="toclevel-2"><a href="#rev"><span class="tocnumber">10.29</span>
|
||
<span class="toctext">rev</span></a></li>
|
||
<li class="toclevel-2"><a href="#sanitiseArg"><span class="tocnumber">10.30</span>
|
||
<span class="toctext">sanitiseArg</span></a></li>
|
||
<li class="toclevel-2"><a href="#sanitiseMatched"><span
|
||
class="tocnumber">10.31</span> <span class="toctext">sanitiseMatched</span></a></li>
|
||
<li class="toclevel-2"><a href="#sanitiseMatchedBytes"><span
|
||
class="tocnumber">10.32</span> <span class="toctext">sanitiseMatchedBytes</span></a></li>
|
||
<li class="toclevel-2"><a href="#sanitiseRequestHeader"><span
|
||
class="tocnumber">10.33</span> <span class="toctext">sanitiseRequestHeader</span></a></li>
|
||
<li class="toclevel-2"><a href="#sanitiseResponseHeader"><span
|
||
class="tocnumber">10.34</span> <span class="toctext">sanitiseResponseHeader</span></a></li>
|
||
<li class="toclevel-2"><a href="#severity"><span class="tocnumber">10.35</span>
|
||
<span class="toctext">severity</span></a></li>
|
||
<li class="toclevel-2"><a href="#setuid"><span class="tocnumber">10.36</span>
|
||
<span class="toctext">setuid</span></a></li>
|
||
<li class="toclevel-2"><a href="#setrsc"><span class="tocnumber">10.37</span>
|
||
<span class="toctext">setrsc</span></a></li>
|
||
<li class="toclevel-2"><a href="#setsid"><span class="tocnumber">10.38</span>
|
||
<span class="toctext">setsid</span></a></li>
|
||
<li class="toclevel-2"><a href="#setenv"><span class="tocnumber">10.39</span>
|
||
<span class="toctext">setenv</span></a></li>
|
||
<li class="toclevel-2"><a href="#setvar"><span class="tocnumber">10.40</span>
|
||
<span class="toctext">setvar</span></a></li>
|
||
<li class="toclevel-2"><a href="#skip"><span class="tocnumber">10.41</span>
|
||
<span class="toctext">skip</span></a></li>
|
||
<li class="toclevel-2"><a href="#skipAfter"><span class="tocnumber">10.42</span>
|
||
<span class="toctext">skipAfter</span></a></li>
|
||
<li class="toclevel-2"><a href="#status"><span class="tocnumber">10.43</span>
|
||
<span class="toctext">status</span></a></li>
|
||
<li class="toclevel-2"><a href="#t"><span class="tocnumber">10.44</span>
|
||
<span class="toctext">t</span></a></li>
|
||
<li class="toclevel-2"><a href="#tag"><span class="tocnumber">10.45</span>
|
||
<span class="toctext">tag</span></a></li>
|
||
<li class="toclevel-2"><a href="#ver"><span class="tocnumber">10.46</span>
|
||
<span class="toctext">ver</span></a></li>
|
||
<li class="toclevel-2"><a href="#xmlns"><span class="tocnumber">10.47</span>
|
||
<span class="toctext">xmlns</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Operators"><span class="tocnumber">11</span>
|
||
<span class="toctext">Operators</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#beginsWith"><span class="tocnumber">11.1</span>
|
||
<span class="toctext">beginsWith</span></a></li>
|
||
<li class="toclevel-2"><a href="#contains"><span class="tocnumber">11.2</span>
|
||
<span class="toctext">contains</span></a></li>
|
||
<li class="toclevel-2"><a href="#endsWith"><span class="tocnumber">11.3</span>
|
||
<span class="toctext">endsWith</span></a></li>
|
||
<li class="toclevel-2"><a href="#eq"><span class="tocnumber">11.4</span>
|
||
<span class="toctext">eq</span></a></li>
|
||
<li class="toclevel-2"><a href="#ge"><span class="tocnumber">11.5</span>
|
||
<span class="toctext">ge</span></a></li>
|
||
<li class="toclevel-2"><a href="#geoLookup"><span class="tocnumber">11.6</span>
|
||
<span class="toctext">geoLookup</span></a></li>
|
||
<li class="toclevel-2"><a href="#gsbLookup"><span class="tocnumber">11.7</span>
|
||
<span class="toctext">gsbLookup</span></a></li>
|
||
<li class="toclevel-2"><a href="#gt"><span class="tocnumber">11.8</span>
|
||
<span class="toctext">gt</span></a></li>
|
||
<li class="toclevel-2"><a href="#inspectFile"><span class="tocnumber">11.9</span>
|
||
<span class="toctext">inspectFile</span></a></li>
|
||
<li class="toclevel-2"><a href="#ipMatch"><span class="tocnumber">11.10</span>
|
||
<span class="toctext">ipMatch</span></a></li>
|
||
<li class="toclevel-2"><a href="#ipMatchF"><span class="tocnumber">11.11</span>
|
||
<span class="toctext">ipMatchF</span></a></li>
|
||
<li class="toclevel-2"><a href="#ipMatchFromFile"><span
|
||
class="tocnumber">11.12</span> <span class="toctext">ipMatchFromFile</span></a></li>
|
||
<li class="toclevel-2"><a href="#le"><span class="tocnumber">11.13</span>
|
||
<span class="toctext">le</span></a></li>
|
||
<li class="toclevel-2"><a href="#lt"><span class="tocnumber">11.14</span>
|
||
<span class="toctext">lt</span></a></li>
|
||
<li class="toclevel-2"><a href="#pm"><span class="tocnumber">11.15</span>
|
||
<span class="toctext">pm</span></a></li>
|
||
<li class="toclevel-2"><a href="#pmf"><span class="tocnumber">11.16</span>
|
||
<span class="toctext">pmf</span></a></li>
|
||
<li class="toclevel-2"><a href="#pmFromFile"><span class="tocnumber">11.17</span>
|
||
<span class="toctext">pmFromFile</span></a></li>
|
||
<li class="toclevel-2"><a href="#rbl"><span class="tocnumber">11.18</span>
|
||
<span class="toctext">rbl</span></a></li>
|
||
<li class="toclevel-2"><a href="#rsub"><span class="tocnumber">11.19</span>
|
||
<span class="toctext">rsub</span></a></li>
|
||
<li class="toclevel-2"><a href="#rx"><span class="tocnumber">11.20</span>
|
||
<span class="toctext">rx</span></a></li>
|
||
<li class="toclevel-2"><a href="#streq"><span class="tocnumber">11.21</span>
|
||
<span class="toctext">streq</span></a></li>
|
||
<li class="toclevel-2"><a href="#strmatch"><span class="tocnumber">11.22</span>
|
||
<span class="toctext">strmatch</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateByteRange"><span
|
||
class="tocnumber">11.23</span> <span class="toctext">validateByteRange</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateDTD"><span class="tocnumber">11.24</span>
|
||
<span class="toctext">validateDTD</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateEncryption"><span
|
||
class="tocnumber">11.25</span> <span class="toctext">validateEncryption</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateSchema"><span class="tocnumber">11.26</span>
|
||
<span class="toctext">validateSchema</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateUrlEncoding"><span
|
||
class="tocnumber">11.27</span> <span class="toctext">validateUrlEncoding</span></a></li>
|
||
<li class="toclevel-2"><a href="#validateUtf8Encoding"><span
|
||
class="tocnumber">11.28</span> <span class="toctext">validateUtf8Encoding</span></a></li>
|
||
<li class="toclevel-2"><a href="#verifyCC"><span class="tocnumber">11.29</span>
|
||
<span class="toctext">verifyCC</span></a></li>
|
||
<li class="toclevel-2"><a href="#verifyCPF"><span class="tocnumber">11.30</span>
|
||
<span class="toctext">verifyCPF</span></a></li>
|
||
<li class="toclevel-2"><a href="#verifySSN"><span class="tocnumber">11.31</span>
|
||
<span class="toctext">verifySSN</span></a></li>
|
||
<li class="toclevel-2"><a href="#within"><span class="tocnumber">11.32</span>
|
||
<span class="toctext">within</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#Macro_Expansion"><span
|
||
class="tocnumber">12</span> <span class="toctext">Macro Expansion</span></a></li>
|
||
<li class="toclevel-1"><a href="#Persistant_Storage"><span
|
||
class="tocnumber">13</span> <span class="toctext">Persistant Storage</span></a></li>
|
||
<li class="toclevel-1"><a href="#Miscellaneous_Topics"><span
|
||
class="tocnumber">14</span> <span class="toctext">Miscellaneous Topics</span></a>
|
||
<ul>
|
||
<li class="toclevel-2"><a href="#Impedance_Mismatch"><span
|
||
class="tocnumber">14.1</span> <span class="toctext">Impedance Mismatch</span></a>
|
||
<ul>
|
||
<li class="toclevel-3"><a href="#Impedance_Mismatch_with_PHP_Apps"><span
|
||
class="tocnumber">14.1.1</span> <span class="toctext">Impedance
|
||
Mismatch with PHP Apps</span></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="toclevel-1"><a href="#A_Recommended_Base_Configuration"><span
|
||
class="tocnumber">15</span> <span class="toctext">A Recommended Base
|
||
Configuration</span></a></li>
|
||
</ul>
|
||
</td></tr></tbody></table><script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
|
||
<a name="ModSecurity.C2.AE_Reference_Manual"
|
||
id="ModSecurity.C2.AE_Reference_Manual"></a><h1> <span
|
||
class="mw-headline"> ModSecurity® Reference Manual </span></h1>
|
||
<a name="Current_as_of_v2.5.13_v2.6_and_v2.7"
|
||
id="Current_as_of_v2.5.13_v2.6_and_v2.7"></a><h2> <span
|
||
class="mw-headline"> Current as of v2.5.13 v2.6 and v2.7 </span></h2>
|
||
<a name="Copyright_.C2.A9_2004-2011_Trustwave_Holdings.2C_Inc."
|
||
id="Copyright_.C2.A9_2004-2011_Trustwave_Holdings.2C_Inc."></a><h3> <span
|
||
class="mw-headline"> Copyright © 2004-2011 <a
|
||
href="https://www.trustwave.com/" class="external text"
|
||
title="https://www.trustwave.com/" rel="nofollow">Trustwave Holdings,
|
||
Inc.</a> </span></h3>
|
||
<a name="Table_of_Contents" id="Table_of_Contents"></a><h1> <span
|
||
class="mw-headline"> Table of Contents </span></h1>
|
||
<a name="Introduction" id="Introduction"></a><h1> <span
|
||
class="mw-headline"> Introduction </span></h1>
|
||
<p>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.
|
||
</p>
|
||
<a name="HTTP_Traffic_Logging" id="HTTP_Traffic_Logging"></a><h2> <span
|
||
class="mw-headline"> HTTP Traffic Logging </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="Real-Time_Monitoring_and_Attack_Detection"
|
||
id="Real-Time_Monitoring_and_Attack_Detection"></a><h2> <span
|
||
class="mw-headline"> Real-Time Monitoring and Attack Detection </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="Attack_Prevention_and_Virtual_Patching"
|
||
id="Attack_Prevention_and_Virtual_Patching"></a><h2> <span
|
||
class="mw-headline"> Attack Prevention and Virtual Patching </span></h2>
|
||
<p>ModSecurity can also act immediately to prevent attacks from reaching
|
||
your web applications. There are three commonly used approaches:
|
||
</p>
|
||
<ol><li>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.
|
||
</li><li>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.
|
||
</li><li>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.
|
||
</li></ol>
|
||
<a name="Flexible_Rule_Engine" id="Flexible_Rule_Engine"></a><h2> <span
|
||
class="mw-headline"> Flexible Rule Engine </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="Embedded-mode_Deployment" id="Embedded-mode_Deployment"></a><h2>
|
||
<span class="mw-headline"> Embedded-mode Deployment </span></h2>
|
||
<p>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:
|
||
</p>
|
||
<ol><li>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.
|
||
</li><li>No single point of failure. Unlike with network-based
|
||
deployments, you will not be introducing a new point of failure to your
|
||
system.
|
||
</li><li>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.
|
||
</li><li>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.
|
||
</li><li>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.
|
||
</li></ol>
|
||
<a name="Network-based_Deployment" id="Network-based_Deployment"></a><h2>
|
||
<span class="mw-headline"> Network-based Deployment </span></h2>
|
||
<p>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).
|
||
</p>
|
||
<a name="Portability" id="Portability"></a><h2> <span
|
||
class="mw-headline"> Portability </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="Licensing" id="Licensing"></a><h2> <span class="mw-headline">
|
||
Licensing </span></h2>
|
||
<p>ModSecurity is available under the Apache Software License v2 <a
|
||
href="http://www.apache.org/licenses/LICENSE-2.0.txt" class="external
|
||
autonumber" title="http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||
rel="nofollow">[1]</a>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> ModSecurity, mod_security, ModSecurity Pro,
|
||
and ModSecurity Core Rules are trademarks or registered trademarks of
|
||
Trustwave Holdings, Inc.
|
||
</dd></dl>
|
||
<a name="OWASP_ModSecurity_Core_Rule_Set_.28CRS.29_Project"
|
||
id="OWASP_ModSecurity_Core_Rule_Set_.28CRS.29_Project"></a><h1> <span
|
||
class="mw-headline"> OWASP ModSecurity Core Rule Set (CRS) Project </span></h1>
|
||
<a name="Overview" id="Overview"></a><h2> <span class="mw-headline">
|
||
Overview </span></h2>
|
||
<p>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, Trustwave's SpiderLabs created
|
||
the OWASP ModSecurity Core Rule Set (CRS) Project. Unlike intrusion
|
||
detection and prevention systems, which rely on signatures specific to
|
||
known vulnerabilities, the CRS provide generic protection from unknown
|
||
vulnerabilities often found in web applications, which are in most cases
|
||
custom coded. The CRS is heavily commented to allow it to be used as a
|
||
step-by-step deployment guide for ModSecurity. The latest rules packages
|
||
can be found at the <a
|
||
href="http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project"
|
||
class="external text"
|
||
title="http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project"
|
||
rel="nofollow">OWASP ModSecurity CRS Project Site</a>.
|
||
</p>
|
||
<a name="Core_Rules_Content" id="Core_Rules_Content"></a><h2> <span
|
||
class="mw-headline"> Core Rules Content </span></h2>
|
||
<p>In order to provide generic web applications protection, the CRS use
|
||
some of the following example techniques:
|
||
</p>
|
||
<ul><li>HTTP protection - detecting violations of the HTTP protocol and a
|
||
locally defined usage policy.
|
||
</li><li>Common Web Attacks Protection - detecting common web
|
||
application security attack.
|
||
</li><li>Automation detection - Detecting bots, crawlers, scanners and
|
||
other surface malicious activity.
|
||
</li><li>Trojan Protection - Detecting access to Trojans horses.
|
||
</li><li>Error Hiding - Disguising error messages sent by the server.
|
||
</li></ul>
|
||
<a name="Installation" id="Installation"></a><h1> <span
|
||
class="mw-headline"> Installation </span></h1>
|
||
<a name="Prerequisites" id="Prerequisites"></a><h2> <span
|
||
class="mw-headline"> Prerequisites </span></h2>
|
||
<a name="ModSecurity_2.x_works_only_with_Apache_2.0.x_or_higher"
|
||
id="ModSecurity_2.x_works_only_with_Apache_2.0.x_or_higher"></a><h3> <span
|
||
class="mw-headline"> ModSecurity 2.x works only with Apache 2.0.x or
|
||
higher </span></h3>
|
||
<p>Version 2.2.x is highly recommended.
|
||
</p>
|
||
<a name="mod_uniqueid" id="mod_uniqueid"></a><h3> <span
|
||
class="mw-headline"> mod_uniqueid </span></h3>
|
||
<p>Make sure you have <code>mod_unique_id</code> installed.
|
||
mod_unique_id is packaged with Apache httpd.
|
||
</p>
|
||
<a name="libapr_and_libapr-util" id="libapr_and_libapr-util"></a><h3> <span
|
||
class="mw-headline"> libapr and libapr-util </span></h3>
|
||
<p>libapr and libapr-util - <a href="http://apr.apache.org/"
|
||
class="external free" title="http://apr.apache.org/" rel="nofollow">http://apr.apache.org/</a>
|
||
</p>
|
||
<a name="libpcre" id="libpcre"></a><h3> <span class="mw-headline">
|
||
libpcre </span></h3>
|
||
<p><a href="http://www.pcre.org/" class="external free"
|
||
title="http://www.pcre.org/" rel="nofollow">http://www.pcre.org/</a>
|
||
</p>
|
||
<a name="libxml2" id="libxml2"></a><h3> <span class="mw-headline">
|
||
libxml2 </span></h3>
|
||
<p><a href="http://xmlsoft.org/downloads.html" class="external free"
|
||
title="http://xmlsoft.org/downloads.html" rel="nofollow">http://xmlsoft.org/downloads.html</a>
|
||
</p>
|
||
<a name="liblua_v5.1.x" id="liblua_v5.1.x"></a><h3> <span
|
||
class="mw-headline"> liblua v5.1.x </span></h3>
|
||
<p>This library is optional and only needed if you will be using the new
|
||
Lua engine - <a href="http://www.lua.org/download.html" class="external
|
||
free" title="http://www.lua.org/download.html" rel="nofollow">http://www.lua.org/download.html</a>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> that ModSecurity requires the dynamic
|
||
libraries. These are not built by default in the source distribution, so
|
||
the binary distribution is recommended.
|
||
</dd></dl>
|
||
<a name="libcurl_v7.15.1_or_higher" id="libcurl_v7.15.1_or_higher"></a><h3>
|
||
<span class="mw-headline"> libcurl v7.15.1 or higher </span></h3>
|
||
<p>If you will be using the ModSecurity Log Collector (mlogc) to send
|
||
audit logs to a central repository, then you will also need the curl
|
||
library.
|
||
</p><p><a href="http://curl.haxx.se/libcurl/" class="external free"
|
||
title="http://curl.haxx.se/libcurl/" rel="nofollow">http://curl.haxx.se/libcurl/</a>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Many have had issues with libcurl linked
|
||
with the GnuTLS library for SSL/TLS support. It is recommended that the
|
||
openssl library be used for SSL/TLS support in libcurl.
|
||
</dd></dl>
|
||
<a name="Installation_Methods" id="Installation_Methods"></a><h2> <span
|
||
class="mw-headline"> Installation Methods </span></h2>
|
||
<p>Before you begin with installation you will need to choose your
|
||
preferred installation method. First you need to choose whether to
|
||
install the latest version of ModSecurity directly from CVS (best
|
||
features, but possibly unstable) or use the latest stable release
|
||
(recommended). If you choose a stable release, it might be possible to
|
||
install ModSecurity from binary. It is always possible to compile it
|
||
from source code.
|
||
</p><p>The following few pages will give you more information on
|
||
benefits of choosing one method over another.
|
||
</p>
|
||
<a name="SVN_Access" id="SVN_Access"></a><h2> <span class="mw-headline">
|
||
SVN Access </span></h2>
|
||
<p>If you want to access the latest version of the module you need to
|
||
get it from the svn repository. The list of changes made since the last
|
||
stable release is normally available on the web site (and in the file
|
||
CHANGES). The SVN repository for ModSecurity is hosted by SourceForge (<a
|
||
href="http://www.sf.net/" class="external free"
|
||
title="http://www.sf.net" rel="nofollow">http://www.sf.net</a>). You can
|
||
access it directly or view if through web using this address: <a
|
||
href="http://mod-security.svn.sourceforge.net/viewvc/mod-security/"
|
||
class="external free"
|
||
title="http://mod-security.svn.sourceforge.net/viewvc/mod-security/"
|
||
rel="nofollow">http://mod-security.svn.sourceforge.net/viewvc/mod-security/</a>
|
||
|
||
</p><p>To download the lastest TRUNK source code to your computer you
|
||
need to execute the following command:
|
||
</p><p><b>git</b>
|
||
</p>
|
||
<pre>$git svn clone --prefix=svn/ https://mod-security.svn.sourceforge.net/svnroot/mod-security/m2/trunk
|
||
</pre>
|
||
<p><b>svn</b>
|
||
</p>
|
||
<pre>svn co https://mod-security.svn.sourceforge.net/svnroot/mod-security/m2/trunk modsecurity
|
||
</pre>
|
||
<p>For v2.6.0 and above, the installation process has changed. Follow
|
||
these steps:
|
||
</p>
|
||
<ol><li>cd into the directory - <code>$cd modsecurity</code>
|
||
</li><li>Run autogen.sh script - <code>$./autogen.sh</code>
|
||
</li><li>Run configure script - <code>$./configure</code>
|
||
</li><li>Run make - <code>$make</code>
|
||
</li><li>Run make install - <code>$make install</code>
|
||
</li><li>Copy the new mod_security2.so file into the proper Apache
|
||
modules directory - <code>$cp
|
||
/usr/local/modsecurity/lib/mod_security2.so /usr/local/apache/modules/</code>
|
||
</li></ol>
|
||
<a name="Stable_Release_Download" id="Stable_Release_Download"></a><h2> <span
|
||
class="mw-headline"> Stable Release Download </span></h2>
|
||
<p>To download the stable release go to <a
|
||
href="http://www.modsecurity.org/download/" class="external free"
|
||
title="http://www.modsecurity.org/download/" rel="nofollow">http://www.modsecurity.org/download/</a>.
|
||
Binary distributions are sometimes available. If they are, they are
|
||
listed on the download page. If not download the source code
|
||
distribution.
|
||
</p>
|
||
<a name="Installation_Steps" id="Installation_Steps"></a><h2> <span
|
||
class="mw-headline"> Installation Steps </span></h2>
|
||
<ul><li>Stop Apache httpd
|
||
</li><li>Unpack the ModSecurity archive
|
||
</li><li>Build
|
||
</li></ul>
|
||
<p>Building differs for UNIX (or UNIX-like) operating systems and
|
||
Windows.
|
||
</p>
|
||
<a name="UNIX" id="UNIX"></a><h3> <span class="mw-headline"> UNIX </span></h3>
|
||
<p>Run the configure script to generate a Makefile. Typically no options
|
||
are needed.
|
||
</p>
|
||
<pre>./configure</pre>
|
||
<p>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.
|
||
</p>
|
||
<pre>./configure --with-apxs=/path/to/httpd-2.x.y/bin/apxs</pre>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<p>Compile with:
|
||
</p>
|
||
<pre>make</pre>
|
||
<p>Optionally test with:
|
||
</p>
|
||
<pre>make CFLAGS=-DMSC_TEST test</pre>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<p>Optionally build the ModSecurity Log Collector with:
|
||
</p>
|
||
<pre>make mlogc</pre>
|
||
<p>Optionally install mlogc: Review the INSTALL file included in the
|
||
apache2/mlogc-src directory in the distribution.
|
||
Install the ModSecurity module with:
|
||
</p>
|
||
<pre>make install</pre>
|
||
<a name="Windows_.28MS_VC.2B.2B_8.29" id="Windows_.28MS_VC.2B.2B_8.29"></a><h3>
|
||
<span class="mw-headline"> Windows (MS VC++ 8) </span></h3>
|
||
<p>Edit Makefile.win to configure the Apache base and library paths.
|
||
Compile with: <code>nmake -f Makefile.win</code>
|
||
Install the ModSecurity module with: <code>nmake -f Makefile.win install</code>
|
||
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.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Users should follow the steps present in
|
||
README_WINDOWS.txt into ModSecurity tarball.
|
||
</dd></dl>
|
||
<a
|
||
name="Edit_the_main_Apache_httpd_config_file_.28usually_httpd.conf.29"
|
||
id="Edit_the_main_Apache_httpd_config_file_.28usually_httpd.conf.29"></a><h3>
|
||
<span class="mw-headline"> Edit the main Apache httpd config file
|
||
(usually httpd.conf) </span></h3>
|
||
<p>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:
|
||
</p>
|
||
<pre>LoadFile /usr/lib/libxml2.so
|
||
LoadFile /usr/lib/liblua5.1.so
|
||
</pre>
|
||
<p>Load the ModSecurity module with:
|
||
</p>
|
||
<pre>LoadModule security2_module modules/mod_security2.so
|
||
</pre>
|
||
<a name="Configure_ModSecurity" id="Configure_ModSecurity"></a><h3> <span
|
||
class="mw-headline"> Configure ModSecurity </span></h3>
|
||
<a name="Start_Apache_httpd" id="Start_Apache_httpd"></a><h3> <span
|
||
class="mw-headline"> Start Apache httpd </span></h3>
|
||
<p>You should now have ModSecurity 2.x up and running.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> 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).
|
||
</dd></dl>
|
||
<dl><dd> 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).
|
||
</dd></dl>
|
||
<dl><dd> 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.
|
||
</dd></dl>
|
||
<dl><dd> Non-gcc compilers may have problems running out-of-the-box as
|
||
the current build system was designed around the gcc compiler and some
|
||
compiler/linker flags may differ. To use a non-gcc compiler you may need
|
||
some manual Makefile tweaks if issues cannot be solved by exporting
|
||
custom CFLAGS and CPPFLAGS environment variables.
|
||
</dd></dl>
|
||
<dl><dd> If you are upgrading from ModSecurity 1.x, please refer to the
|
||
migration matrix at <a
|
||
href="http://www.modsecurity.org/documentation/ModSecurity-Migration-Matrix.pdf"
|
||
class="external free"
|
||
title="http://www.modsecurity.org/documentation/ModSecurity-Migration-Matrix.pdf"
|
||
rel="nofollow">http://www.modsecurity.org/documentation/ModSecurity-Migration-Matrix.pdf</a>
|
||
</dd></dl>
|
||
<dl><dd> Starting with ModSecurity 2.7.0 there are a few important
|
||
configuration options
|
||
</dd></dl>
|
||
<ol><li><b>--enable-pcre-jit</b> - Enables JIT support from pcre >=
|
||
8.20 that can improve regex performance.
|
||
</li><li><b>--enable-cache-lua</b> - Enables lua vm caching that can
|
||
improve lua script performance. Difference just appears if ModSecurity
|
||
must run more than one script per transaction.
|
||
</li><li><b>--enable-request-early</b> - On ModSecuricy 2.6 phase one
|
||
has been moved to phase 2 hook, if you want to play around it use this
|
||
option.
|
||
</li></ol>
|
||
<a name="Configuration_Directives" id="Configuration_Directives"></a><h1>
|
||
<span class="mw-headline"> Configuration Directives </span></h1>
|
||
<p>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.
|
||
</p><p>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.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="SecAction" id="SecAction"></a><h2> <span class="mw-headline">
|
||
SecAction </span></h2>
|
||
<p><b>Description:</b> Unconditionally processes the action list it
|
||
receives as the first and only parameter. The syntax of the parameter is
|
||
identical to that of the third parameter of <code>SecRule</code>.
|
||
</p><p><b>Syntax:</b> <code>SecAction "action1,action2,action3,...“</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive is commonly used to set variables and initialize
|
||
persistent collections using the initcol action. For example:
|
||
</p>
|
||
<pre>SecAction nolog,phase:1,initcol:RESOURCE=%{REQUEST_FILENAME}</pre>
|
||
<a name="SecArgumentSeparator" id="SecArgumentSeparator"></a><h2> <span
|
||
class="mw-headline"> SecArgumentSeparator </span></h2>
|
||
<p><b>Description:</b> Specifies which character to use as the separator
|
||
for application/x-www-form- urlencoded content.
|
||
</p><p><b>Syntax:</b> <code>SecArgumentSeparator character</code>
|
||
</p><p><b>Default:</b> &
|
||
</p><p><b>Scope:</b> Main(< 2.7.0), Any(2.7.0)
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive is needed if a backend web application is using a
|
||
nonstandard argument separator. Applications are sometimes (very rarely)
|
||
written to use a semicolon separator. You should not change the default
|
||
setting unless you establish that the application you are working with
|
||
requires a different 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.
|
||
</p>
|
||
<a name="SecAuditEngine" id="SecAuditEngine"></a><h2> <span
|
||
class="mw-headline"> SecAuditEngine </span></h2>
|
||
<p><b>Description:</b> Configures the audit logging engine.
|
||
</p><p><b>Syntax:</b> <code>SecAuditEngine RelevantOnly</code>
|
||
</p><p><b>Default:</b> Off
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>The SecAuditEngine directive is used to configure the audit
|
||
engine, which logs complete transactions. ModSecurity is currently able
|
||
to log most, but not all transactions. Transactions involving errors
|
||
(e.g., 400 and 404 transactions) use a different execution path, which
|
||
ModSecurity does not support.
|
||
</p><p>The possible values for the audit log engine are as follows:
|
||
</p>
|
||
<ul><li><b>On</b>: log all transactions
|
||
</li><li><b>Off</b>: do not log any transactions
|
||
</li><li><b>RelevantOnly</b>: only the log transactions that have
|
||
triggered a warning or an error, or have a status code that is
|
||
considered to be relevant (as determined by the
|
||
SecAuditLogRelevantStatus directive)
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> If you need to change the audit log engine
|
||
configuration on a per-transaction basis (e.g., in response to some
|
||
transaction data), use the ctl action.
|
||
</dd></dl>
|
||
<p>The following example demonstrates how SecAuditEngine is used:
|
||
</p>
|
||
<pre>SecAuditEngine RelevantOnly
|
||
SecAuditLog logs/audit/audit.log
|
||
SecAuditLogParts ABCFHZ
|
||
SecAuditLogType concurrent
|
||
SecAuditLogStorageDir logs/audit
|
||
SecAuditLogRelevantStatus ^(?:5|4(?!04))
|
||
</pre>
|
||
<a name="SecAuditLog" id="SecAuditLog"></a><h2> <span
|
||
class="mw-headline"> SecAuditLog </span></h2>
|
||
<p><b>Description:</b> Defines the path to the main audit log file
|
||
(serial logging format) or the concurrent logging index file (concurrent
|
||
logging format). When used in combination with mlogc (only possible
|
||
with concurrent logging), this directive defines the mlogc location and
|
||
command line.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLog /path/to/audit.log</code>
|
||
</p><p><b>Scope:</b> Any Version: 2.0.0
|
||
</p><p>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
|
||
to send your audit log data off to a remote server you will need to
|
||
deploy the ModSecurity Log Collector (mlogc), like this:
|
||
</p>
|
||
<pre>SecAuditLog "|/path/to/mlogc /path/to/mlogc.conf"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> This audit log file is opened 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.
|
||
</dd></dl>
|
||
<a name="SecAuditLog2" id="SecAuditLog2"></a><h2> <span
|
||
class="mw-headline"> SecAuditLog2 </span></h2>
|
||
<p><b>Description:</b> Defines the path to the secondary audit log index
|
||
file when concurrent logging is enabled. See SecAuditLog for more
|
||
details.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLog2 /path/to/audit.log</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.1.2
|
||
</p><p>The purpose of SecAuditLog2 is to make logging to two remote
|
||
servers possible, which is typically achieved by running two instances
|
||
of the mlogc tool, each with a different configuration (in addition, one
|
||
of the instances will need to be instructed not to delete the files it
|
||
submits). This directive can be used only if SecAuditLog was previously
|
||
configured and only if concurrent logging format is used.
|
||
</p>
|
||
<a name="SecAuditLogDirMode" id="SecAuditLogDirMode"></a><h2> <span
|
||
class="mw-headline"> SecAuditLogDirMode</span></h2>
|
||
<p><b>Description:</b> Configures the mode (permissions) of any
|
||
directories created for the concurrent audit logs, using an octal mode
|
||
value as parameter (as used in chmod).
|
||
</p><p><b>Syntax:</b> <code>SecAuditLogDirMode octal_mode|"default"</code>
|
||
|
||
</p><p><b>Default:</b> 0600
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.10
|
||
</p><p>The default mode for new audit log directories (0600) only grants
|
||
read/write access to the owner (typically the account under which
|
||
Apache is running, for example apache). If access from other accounts is
|
||
needed (e.g., for use with mpm-itk), then you may use this directive to
|
||
grant additional read and/or write privileges. You should use this
|
||
directive with caution to avoid exposing potentially sensitive data to
|
||
unauthorized users. Using the value default as parameter reverts the
|
||
configuration back to the default setting. This feature is not available
|
||
on operating systems not supporting octal file modes.
|
||
</p><p>Example:
|
||
</p>
|
||
<pre>SecAuditLogDirMode 02750</pre>
|
||
<dl><dt> Note </dt><dd> The process umask may still limit the mode
|
||
if it is being more restrictive than the mode set using this directive.
|
||
</dd></dl>
|
||
<a name="SecAuditLogFileMode" id="SecAuditLogFileMode"></a><h2> <span
|
||
class="mw-headline"> SecAuditLogFileMode </span></h2>
|
||
<p><b>Description:</b> Configures the mode (permissions) of any files
|
||
created for concurrent audit logs using an octal mode (as used in
|
||
chmod). See SecAuditLogDirMode for controlling the mode of created audit
|
||
log directories.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLogFileMode octal_mode|"default"</code>
|
||
|
||
</p><p><b>Default:</b> 0600
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.10
|
||
</p><p><b>Example Usage:</b> <code>SecAuditLogFileMode 00640</code>
|
||
</p><p>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 mpm-itk 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.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> The process umask may still limit the mode
|
||
if it is being more restrictive than the mode set using this directive.
|
||
</dd></dl>
|
||
<a name="SecAuditLogParts" id="SecAuditLogParts"></a><h2> <span
|
||
class="mw-headline"> SecAuditLogParts </span></h2>
|
||
<p><b>Description:</b> Defines which parts of each transaction are going
|
||
to be recorded in the audit log. Each part is assigned a single letter;
|
||
when a letter appears in the list then the equivalent part will be
|
||
recorded. See below for the list of all parts.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLogParts PARTLETTERS</code>
|
||
</p><p><b>Example Usage:</b> <code>SecAuditLogParts ABCFHZ</code>
|
||
</p><p><b>Scope:</b> Any Version: 2.0.0
|
||
</p><p><b>Default:</b> ABCFHZ Note
|
||
</p><p>The format of the audit log format is documented in detail in the
|
||
Audit Log Data Format Documentation.
|
||
</p><p>Available audit log parts:
|
||
</p>
|
||
<ul><li>A: Audit log header (mandatory).
|
||
</li><li>B: Request headers.
|
||
</li><li>C: Request body (present only if the request body exists and
|
||
ModSecurity is configured to intercept it).
|
||
</li><li>D: Reserved for intermediary response headers; not implemented
|
||
yet.
|
||
</li><li>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).
|
||
</li><li>F: Final response headers (excluding the Date and Server
|
||
headers, which are always added by Apache in the late stage of content
|
||
delivery).
|
||
</li><li>G: Reserved for the actual response body; not implemented yet.
|
||
</li><li>H: Audit log trailer.
|
||
</li><li>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.
|
||
</li><li>J: This part contains information about the files uploaded
|
||
using multipart/form-data encoding.
|
||
</li><li>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.
|
||
</li><li>Z: Final boundary, signifies the end of the entry (mandatory).
|
||
</li></ul>
|
||
<a name="SecAuditLogRelevantStatus" id="SecAuditLogRelevantStatus"></a><h2>
|
||
<span class="mw-headline"> SecAuditLogRelevantStatus </span></h2>
|
||
<p><b>Description:</b> Configures which response status code is to be
|
||
considered relevant for the purpose of audit logging.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLogRelevantStatus REGEX</code>
|
||
</p><p><b>Example Usage:</b> <code>SecAuditLogRelevantStatus
|
||
"^(?:5|4(?!04))"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Dependencies/Notes:</b> Must have SecAuditEngine set to
|
||
RelevantOnly.
|
||
</p><p>The main purpose of this directive is to allow you to configure
|
||
audit logging for only the transactions that have the status code that
|
||
matches the supplied regular expression. The example provided would log
|
||
all 5xx and 4xx level status codes, except for 404s. Although you could
|
||
achieve the same effect with a rule in phase 5,
|
||
SecAuditLogRelevantStatus is sometimes better, because it continues to
|
||
work even when SecRuleEngine is disabled.
|
||
</p>
|
||
<a name="SecAuditLogStorageDir" id="SecAuditLogStorageDir"></a><h2> <span
|
||
class="mw-headline"> SecAuditLogStorageDir </span></h2>
|
||
<p><b>Description:</b> Configures the directory where concurrent audit
|
||
log entries are to be stored.
|
||
</p><p><b>Syntax</b>: <code>SecAuditLogStorageDir /path/to/storage/dir</code>
|
||
</p><p><b>Example Usage:</b> <code>SecAuditLogStorageDir
|
||
/usr/local/apache/logs/audit </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive is only needed when concurrent audit logging is
|
||
used. The directory must already exist and must be writable by the web
|
||
server user. Audit log entries are created at runtime, after Apache
|
||
switches to a non-root account.
|
||
As with all logging mechanisms, ensure that you specify a file system
|
||
location that has adequate disk space and is not on the main system
|
||
partition.
|
||
</p>
|
||
<a name="SecAuditLogType" id="SecAuditLogType"></a><h2> <span
|
||
class="mw-headline"> SecAuditLogType </span></h2>
|
||
<p><b>Description:</b> Configures the type of audit logging mechanism to
|
||
be used.
|
||
</p><p><b>Syntax:</b> <code>SecAuditLogType Serial|Concurrent </code>
|
||
</p><p><b>Example Usage:</b> <code>SecAuditLogType Serial</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>The possible values are:
|
||
</p>
|
||
<dl><dt> Serial </dt><dd> Audit log entries will be stored in a
|
||
single file, specified by SecAuditLog. This is conve- nient for casual
|
||
use, but it can slow down the server, because only one audit log entry
|
||
can be written to the file at any one time.
|
||
</dd><dt> Concurrent </dt><dd> One file per transaction is used for
|
||
audit logging. This approach is more scalable when heavy logging is
|
||
required (multiple transactions can be recorded in parallel). It is also
|
||
the only choice if you need to use remote logging.
|
||
</dd></dl>
|
||
<a name="SecCacheTransformations" id="SecCacheTransformations"></a><h2> <span
|
||
class="mw-headline"> SecCacheTransformations </span></h2>
|
||
<p><b>Description:</b> Controls the caching of transformations, which
|
||
may speed up the processing of complex rule sets. Caching is off by
|
||
default starting with 2.5.6, when it was deprecated and downgraded back
|
||
to experimental.
|
||
</p><p><b>Syntax:</b> <code>SecCacheTransformations On|Off [options] </code>
|
||
</p><p><b>Example Usage:</b> <code>SecCacheTransformations On
|
||
"minlen:64,maxlen:0" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0; deprecated in 2.5.6.
|
||
</p><p>The first directive parameter can be one of the following:
|
||
</p>
|
||
<ul><li><b>On</b>: Cache transformations (per transaction, per phase)
|
||
allowing identical transforma- tions to be performed only once.
|
||
</li><li><b>Off</b>: Do not cache any transformations, leaving all
|
||
transformations to be performed every time they are needed.
|
||
</li></ul>
|
||
<p>The following options are allowed (multiple options must be
|
||
comma-separated):
|
||
</p>
|
||
<ul><li><b>incremental:on|off</b>: Enabling this option will cache every
|
||
transformation instead of just the final transformation. The default is
|
||
off.
|
||
</li><li><b>maxitems:N</b>: Do not allow more than N transformations to
|
||
be cached. Cache will be disabled once this number is reached. A zero
|
||
value is interpreted as unlimited. This option may be useful to limit
|
||
caching for a form with a large number of variables. The default value
|
||
is 512.
|
||
</li><li><b>minlen:N</b>: Do not cache the transformation if the
|
||
variable’s length is less than N bytes. The default setting is 32.
|
||
</li><li><b>maxlen:N</b>: Do not cache the transformation if the
|
||
variable’s length is more than N bytes. A zero value is interpreted as
|
||
unlimited. The default setting is 1024.
|
||
</li></ul>
|
||
<a name="SecChrootDir" id="SecChrootDir"></a><h2> <span
|
||
class="mw-headline"> SecChrootDir </span></h2>
|
||
<p><b>Description:</b> Configures the directory path that will be used
|
||
to jail the web server process.
|
||
</p><p><b>Syntax:</b> <code>SecChrootDir /path/to/chroot/dir </code>
|
||
</p><p><b>Example Usage:</b> <code>SecChrootDir /chroot </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>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 only static
|
||
files, or running applications using built-in modules. Some problems you
|
||
might encounter with more complex setups:
|
||
</p>
|
||
<ol><li>DNS lookups do not work (this is because this feature requires a
|
||
shared library that is loaded on demand, after chroot takes place).
|
||
</li><li>You cannot send email from PHP, because it wants to use
|
||
sendmail and sendmail re- sides outside the jail.
|
||
</li><li>In some cases, when you separate Apache from its configuration,
|
||
restarts and graceful reloads no longer work.
|
||
</li></ol>
|
||
<p>The best way to use SecChrootDir is the following:
|
||
</p>
|
||
<ol><li>Create /chroot to be your main jail directory.
|
||
</li><li>Create /chroot/opt/apache inside jail.
|
||
</li><li>Create a symlink from /opt/apache to /chroot/opt/apache.
|
||
</li><li>Now install Apache into /chroot/opt/apache.
|
||
</li></ol>
|
||
<p>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.
|
||
</p>
|
||
<a name="SecComponentSignature" id="SecComponentSignature"></a><h2> <span
|
||
class="mw-headline"> SecComponentSignature </span></h2>
|
||
<p><b>Description:</b> Appends component signature to the ModSecurity
|
||
signature.
|
||
</p><p><b>Syntax:</b> <code>SecComponentSignature "COMPONENT_NAME/X.Y.Z
|
||
(COMMENT)" </code>
|
||
</p><p><b>Example usage</b>: <code>SecComponentSignature "core
|
||
ruleset/2.1.3"</code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p><p>This directive should be used to make the presence of significant
|
||
rule sets known. The entire signature will be recorded in the
|
||
transaction audit log.
|
||
</p>
|
||
<a name="SecContentInjection" id="SecContentInjection"></a><h2> <span
|
||
class="mw-headline"> SecContentInjection </span></h2>
|
||
<p><b>Description:</b> Enables content injection using actions append
|
||
and prepend.
|
||
</p><p><b>Syntax:</b> <code>SecContentInjection On|Off </code>
|
||
</p><p><b>Example Usage:</b> <code>SecContentInjection On </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p><p>This directive provides an easy way to control content injection,
|
||
no matter what the rules want to do. It is not necessary to have
|
||
response body buffering enabled in order to use content injection.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> This directive must ben enabled if you want
|
||
to use @rsub + the STREAM_ variables to manipulate live transactional
|
||
data.
|
||
</dd></dl>
|
||
<a name="SecCookieFormat" id="SecCookieFormat"></a><h2> <span
|
||
class="mw-headline"> SecCookieFormat </span></h2>
|
||
<p><b>Description:</b> Selects the cookie format that will be used in
|
||
the current configuration context.
|
||
</p><p><b>Syntax:</b> <code>SecCookieFormat 0|1 </code>
|
||
</p><p><b>Example Usage:</b> <code>SecCookieFormat 0 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>The possible values are:
|
||
</p>
|
||
<ul><li><b>0</b>: Use version 0 (Netscape) cookies. This is what most
|
||
applications use. It is the default value.
|
||
</li><li><b>1</b>: Use version 1 cookies.
|
||
</li></ul>
|
||
<a name="SecDataDir" id="SecDataDir"></a><h2> <span class="mw-headline">
|
||
SecDataDir </span></h2>
|
||
<p><b>Description:</b> Path where persistent data (e.g., IP address
|
||
data, session data, and so on) is to be stored.
|
||
</p><p><b>Syntax:</b> <code>SecDataDir /path/to/dir </code>
|
||
</p><p><b>Example Usage:</b> <code>SecDataDir
|
||
/usr/local/apache/logs/data </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive must be provided before initcol, setsid, and
|
||
setuid can be used. The directory to which the directive points must be
|
||
writable by the web server user.
|
||
</p>
|
||
<a name="SecDebugLog" id="SecDebugLog"></a><h2> <span
|
||
class="mw-headline"> SecDebugLog </span></h2>
|
||
<p><b>Description</b>: Path to the ModSecurity debug log file.
|
||
</p><p><b>Syntax:</b> <code>SecDebugLog /path/to/modsec-debug.log </code>
|
||
</p><p><b>Example Usage:</b> <code>SecDebugLog
|
||
/usr/local/apache/logs/modsec-debug.log </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p>
|
||
<a name="SecDebugLogLevel" id="SecDebugLogLevel"></a><h2> <span
|
||
class="mw-headline"> SecDebugLogLevel </span></h2>
|
||
<p><b>Description:</b> Configures the verboseness of the debug log data.
|
||
|
||
</p><p><b>Syntax</b>: <code>SecDebugLogLevel 0|1|2|3|4|5|6|7|8|9</code>
|
||
</p><p><b>Example Usage:</b> <code>SecDebugLogLevel 4 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>Messages at levels 1–3 are always copied to the Apache error log.
|
||
Therefore you can always use level 0 as the default logging level in
|
||
production if you are very concerned with performance. Having said that,
|
||
the best value to use is 3. Higher logging levels are not recommended
|
||
in production, because the heavy logging affects performance adversely.
|
||
</p><p>The possible values for the debug log level are:
|
||
</p>
|
||
<ul><li>0: no logging
|
||
</li><li>1: errors (intercepted requests) only
|
||
</li><li>2: warnings
|
||
</li><li>3: notices
|
||
</li><li>4: details of how transactions are handled
|
||
</li><li>5: as above, but including information about each piece of
|
||
information handled
|
||
</li><li>9: log everything, including very detailed debugging
|
||
information
|
||
</li></ul>
|
||
<a name="SecDefaultAction" id="SecDefaultAction"></a><h2> <span
|
||
class="mw-headline"> SecDefaultAction </span></h2>
|
||
<p><b>Description</b>: Defines the default list of actions, which will
|
||
be inherited by the rules in the same configuration context.
|
||
</p><p><b>Syntax:</b> <code>SecDefaultAction "action1,action2,action3“ </code>
|
||
</p><p><b>Example Usage:</b> <code>SecDefaultAction
|
||
"phase:2,log,auditlog,deny,status:403“ </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> phase:2,log,auditlog,pass
|
||
</p><p>Every rule following a previous <code>SecDefaultAction</code>
|
||
directive in the same configuration context will inherit its settings
|
||
unless more specific actions are used. Every <code>SecDefaultAction</code>
|
||
directive must specify a disruptive action and a processing phase and
|
||
cannot contain metadata actions.
|
||
</p>
|
||
<dl><dt> Warning </dt><dd> <code>SecDefaultAction</code> is not
|
||
inherited across configuration contexts. (For an example of why this may
|
||
be a problem, read the following ModSecurity Blog entry <a
|
||
href="http://blog.spiderlabs.com/2008/07/three-modsecurity-rule-language-annoyances.html"
|
||
class="external free"
|
||
title="http://blog.spiderlabs.com/2008/07/three-modsecurity-rule-language-annoyances.html"
|
||
rel="nofollow">http://blog.spiderlabs.com/2008/07/three-modsecurity-rule-language-annoyances.html</a>.)
|
||
</dd></dl>
|
||
<a name="SecDisableBackendCompression" id="SecDisableBackendCompression"></a><h2>
|
||
<span class="mw-headline"> SecDisableBackendCompression </span></h2>
|
||
<p><b>Description:</b> Disables backend compression while leaving the
|
||
frontend compression enabled.
|
||
</p><p><b>Syntax:</b> <code>SecDisableBackendCompression On|Off </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.0
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>This directive is necessary in reverse proxy mode when the
|
||
backend servers support response compression, but you wish to inspect
|
||
response bodies. Unless you disable backend compression, ModSecurity
|
||
will only see compressed content, which is not very useful. This
|
||
directive is not necessary in embedded mode, because ModSecurity
|
||
performs inspection before response compression takes place.
|
||
</p>
|
||
<a name="SecEncryptionEngine" id="SecEncryptionEngine"></a><h2> <span
|
||
class="mw-headline"> SecEncryptionEngine </span></h2>
|
||
<p><b>Description:</b> Configures the encryption engine.
|
||
</p><p><b>Syntax:</b> <code>SecEncryptionEngine On|Off</code>
|
||
</p><p><b>Example Usage:</b> <code>SecEncryptionEngine On </code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>The possible values are:
|
||
</p>
|
||
<ul><li><b>On</b>: Encryption engine can process the request/response
|
||
data.
|
||
</li><li><b>Off</b>: Encryption engine will not process any data.
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> Users must enable stream output variables
|
||
and content injection.
|
||
</dd></dl>
|
||
<a name="SecEncryptionKey" id="SecEncryptionKey"></a><h2> <span
|
||
class="mw-headline"> SecEncryptionKey </span></h2>
|
||
<p><b>Description:</b> Define the key that will be used by HMAC.
|
||
</p><p><b>Syntax:</b> <code>SecEncryptionKey rand|TEXT
|
||
KeyOnly|SessionID|RemoteIP</code>
|
||
</p><p><b>Example Usage:</b> <code>SecEncryptionKey "this_is_my_key"
|
||
KeyOnly</code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p>ModSecurity encryption engine will append, if specified, the
|
||
user's session id or remote ip to the key before the MAC operation. If
|
||
the first parameter is "rand" then a random key will be generated and
|
||
used by the engine.
|
||
</p><p><br>
|
||
</p>
|
||
<a name="SecEncryptionParam" id="SecEncryptionParam"></a><h2> <span
|
||
class="mw-headline"> SecEncryptionParam </span></h2>
|
||
<p><b>Description:</b> Define the parameter name that will receive the
|
||
MAC hash.
|
||
</p><p><b>Syntax:</b> <code>SecEncryptionParam TEXT</code>
|
||
</p><p><b>Example Usage:</b> <code>SecEncryptionKey "hmac"</code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p>ModSecurity encryption engine will add a new parameter to
|
||
protected HTML elements containing the MAC hash.
|
||
</p>
|
||
<a name="SecEncryptionMethodRx" id="SecEncryptionMethodRx"></a><h2> <span
|
||
class="mw-headline"> SecEncryptionMethodRx </span></h2>
|
||
<p><b>Description:</b> Configures what kind of HTML data the encryption
|
||
engine should sign based on regular expression.
|
||
</p><p><b>Syntax:</b> <code>SecEncryptionMethodRx TYPE REGEX</code>
|
||
</p><p><b>Example Usage</b>: <code>SecEncryptionMethodRx HashHref
|
||
"product_info|list_product"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.7.0
|
||
</p><p>As a initial support is possible to protect HREF, FRAME, IFRAME
|
||
and FORM ACTION html elements as well response Location header when http
|
||
redirect code are sent.
|
||
</p><p>The possible values for TYPE are:
|
||
</p>
|
||
<ul><li><b>HashHref</b>: Used to sign href= html elements
|
||
</li><li><b>HashFormAction</b>: Used to sign form action= html elements
|
||
</li><li><b>HashIframeSrc</b>: Used to sign iframe src= html elements
|
||
</li><li><b>HashframeSrc</b>: Used to sign frame src= html elements
|
||
</li><li><b>HashLocation</b>: Used to sign Location response header
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> This directive is used to sign the elements
|
||
however user must use the @validateEncryption operator to enforce data
|
||
integrity.
|
||
</dd></dl>
|
||
<p><br>
|
||
</p>
|
||
<a name="SecEncryptionMethodPm" id="SecEncryptionMethodPm"></a><h2> <span
|
||
class="mw-headline"> SecEncryptionMethodPm </span></h2>
|
||
<p><b>Description:</b> Configures what kind of HTML data the encryption
|
||
engine should sign based on string search algoritm.
|
||
</p><p><b>Syntax:</b> <code>SecEncryptionMethodRx TYPE "string1 string2
|
||
string3..."</code>
|
||
</p><p><b>Example Usage</b>: <code>SecEncryptionMethodRx HashHref
|
||
"product_info list_product"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.7.0
|
||
</p><p>As a initial support is possible to protect HREF, FRAME, IFRAME
|
||
and FORM ACTION html elements as well response Location header when http
|
||
redirect code are sent.
|
||
</p><p>The possible values for TYPE are:
|
||
</p>
|
||
<ul><li><b>HashHref</b>: Used to sign href= html elements
|
||
</li><li><b>HashFormAction</b>: Used to sign form action= html elements
|
||
</li><li><b>HashIframeSrc</b>: Used to sign iframe src= html elements
|
||
</li><li><b>HashframeSrc</b>: Used to sign frame src= html elements
|
||
</li><li><b>HashLocation</b>: Used to sign Location response header
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> This directive is used to sign the elements
|
||
however user must use the @validateEncryption operator to enforce data
|
||
integrity.
|
||
</dd></dl>
|
||
<a name="SecGeoLookupDb" id="SecGeoLookupDb"></a><h2> <span
|
||
class="mw-headline"> SecGeoLookupDb </span></h2>
|
||
<p><b>Description</b>: Defines the path to the database that will be
|
||
used for geolocation lookups.
|
||
</p><p><b>Syntax:</b> <code>SecGeoLookupDb /path/to/db </code>
|
||
</p><p><b>Example Usage</b>: <code>SecGeoLookupDb
|
||
/path/to/GeoLiteCity.dat</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p><p>ModSecurity relies on the free geolocation databases (GeoLite
|
||
City and GeoLite Country) that can be obtained from MaxMind <a
|
||
href="http://www.maxmind.com/" class="external autonumber"
|
||
title="http://www.maxmind.com" rel="nofollow">[2]</a>.
|
||
</p>
|
||
<a name="SecGsbLookupDb" id="SecGsbLookupDb"></a><h2> <span
|
||
class="mw-headline"> SecGsbLookupDb </span></h2>
|
||
<p><b>Description</b>: Defines the path to the database that will be
|
||
used for Google Safe Browsing (GSB) lookups.
|
||
</p><p><b>Syntax:</b> <code>SecGsbLookupDb /path/to/db </code>
|
||
</p><p><b>Example Usage</b>: <code>SecGsbLookupDb
|
||
/path/to/GsbMalware.dat</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.0
|
||
</p><p>ModSecurity relies on the free Google Safe Browsing database that
|
||
can be obtained from the Google GSB API <a
|
||
href="http://code.google.com/apis/safebrowsing/" class="external
|
||
autonumber" title="http://code.google.com/apis/safebrowsing/"
|
||
rel="nofollow">[3]</a>.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Deprecated in 2.7.0 after Google dev team
|
||
decided to not allow the database download anymore. After registering
|
||
and obtaining a Safe Browsing API key, you can automatically download
|
||
the GSB using a tool like wget (where <i><b>KEY</b></i> is your own API
|
||
key):
|
||
</dd></dl>
|
||
<p><code>wget <a
|
||
href="http://sb.google.com/safebrowsing/update?client=api&apikey=KEY&version=goog-malware-hash:1:-1"
|
||
class="external free"
|
||
title="http://sb.google.com/safebrowsing/update?client=api&apikey=KEY&version=goog-malware-hash:1:-1"
|
||
rel="nofollow">http://sb.google.com/safebrowsing/update?client=api&apikey=KEY&version=goog-malware-hash:1:-1</a></code>
|
||
</p>
|
||
<a name="SecGuardianLog" id="SecGuardianLog"></a><h2> <span
|
||
class="mw-headline"> SecGuardianLog </span></h2>
|
||
<p><b>Description:</b> Configures an external program that will receive
|
||
the information about every transaction via piped logging.
|
||
</p><p><b>Syntax:</b> <code>SecGuardianLog |/path/to/httpd-guardian </code>
|
||
</p><p><b>Example Usage:</b> <code>SecGuardianLog
|
||
|/usr/local/apache/bin/httpd-guardian </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>Guardian logging is designed to send the information about every
|
||
request to an external program. Because Apache is typically deployed in a
|
||
multiprocess fashion, which makes information sharing between processes
|
||
difficult, the idea is to deploy a single external process to observe
|
||
all requests in a stateful manner, providing additional protection.
|
||
</p><p>Currently the only tool known to work with guardian logging is
|
||
httpd-guardian, which is part of the Apache httpd tools project <a
|
||
href="http://apache-tools.cvs.sourceforge.net/viewvc/apache-tools/apache-tools/"
|
||
class="external autonumber"
|
||
title="http://apache-tools.cvs.sourceforge.net/viewvc/apache-tools/apache-tools/"
|
||
rel="nofollow">[4]</a>. The httpd-guardian tool is designed to defend
|
||
against denial of service attacks. It uses the blacklist tool (from the
|
||
same project) to interact with an iptables-based (on a Linux system) or
|
||
pf-based (on a BSD system) firewall, dynamically blacklisting the
|
||
offending IP addresses. It can also interact with SnortSam <a
|
||
href="http://www.snortsam.net/" class="external autonumber"
|
||
title="http://www.snortsam.net" rel="nofollow">[5]</a>. 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:
|
||
</p>
|
||
<pre>SecGuardianLog |/path/to/httpd-guardian</pre>
|
||
<a name="SecHttpBlKey" id="SecHttpBlKey"></a><h2> <span
|
||
class="mw-headline"> SecHttpBlKey </span></h2>
|
||
<p><b>Description:</b> Configures the user's registered Honeypot Project
|
||
HTTP BL API Key to use with @rbl.
|
||
</p><p><b>Syntax:</b> <code>SecHttpBlKey [12 char access key] </code>
|
||
</p><p><b>Example Usage:</b> <code>SecHttpBlKey whdkfieyhtnf </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.7.0
|
||
</p><p>If the @rbl operator uses the dnsbl.httpbl.org RBL (<a
|
||
href="http://www.projecthoneypot.org/httpbl_api.php" class="external
|
||
free" title="http://www.projecthoneypot.org/httpbl_api.php"
|
||
rel="nofollow">http://www.projecthoneypot.org/httpbl_api.php</a>) you
|
||
must provide an API key. This key is registered to individual users and
|
||
is included within the RBL DNS requests.
|
||
</p>
|
||
<a name="SecInterceptOnError" id="SecInterceptOnError"></a><h2> <span
|
||
class="mw-headline"> SecInterceptOnError </span></h2>
|
||
<p><b>Description:</b> Configures how to respond when rule processing
|
||
fails.
|
||
</p><p><b>Syntax:</b> <code>SecInterceptOnError On|Off </code>
|
||
</p><p><b>Example Usage:</b> <code>SecInterceptOnError On </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.6
|
||
</p><p>When an operator execution fails (ie returns <0), this
|
||
directive configures how to react. When set to "Off", the rule is just
|
||
ignored and the engine will continue executing the rules in phase. When
|
||
set to "On", the rule will be just dropped and no more rules will be
|
||
executed in the same phase, also no interception is made.
|
||
</p>
|
||
<a name="SecMarker" id="SecMarker"></a><h2> <span class="mw-headline">
|
||
SecMarker </span></h2>
|
||
<p><b>Description:</b> Adds a fixed rule marker that can be used as a
|
||
target in a skipAfter action. A SecMarker directive essentially creates a
|
||
rule that does nothing and whose only purpose is to carry the given ID.
|
||
</p><p><b>Syntax:</b> <code>SecMarker ID|TEXT </code>
|
||
</p><p><b>Example Usage</b>: <code>SecMarker 9999 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p><p>The value can be either a number or a text string. The SecMarker
|
||
directive is available to allow you to choose the best way to implement
|
||
a skip-over. Here is an example used from the Core Rule Set:
|
||
</p>
|
||
<pre>SecMarker BEGIN_HOST_CHECK
|
||
|
||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||
"skipAfter:END_HOST_CHECK,phase:2,rev:'2.1.1',t:none,block,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER_HOST',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
|
||
SecRule REQUEST_HEADERS:Host "^$" \
|
||
"phase:2,rev:'2.1.1',t:none,block,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER_HOST',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
|
||
|
||
SecMarker END_HOST_CHECK
|
||
</pre>
|
||
<a name="SecPcreMatchLimit" id="SecPcreMatchLimit"></a><h2> <span
|
||
class="mw-headline"> SecPcreMatchLimit </span></h2>
|
||
<p><b>Description</b>: Sets the match limit in the PCRE library.
|
||
</p><p><b>Syntax:</b> <code>SecPcreMatchLimit value </code>
|
||
</p><p><b>Example Usage</b>: <code>SecPcreMatchLimit 1500 </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version</b>: 2.5.12
|
||
</p><p><b>Default:</b> 1500
|
||
</p><p>The default can be changed when ModSecurity is prepared for
|
||
compilation: the --enable-pcre-match-limit=val configure option will set
|
||
a custom default and the --disable-pcre-match-limit option will revert
|
||
back to the default of the PCRE library.
|
||
For more information, refer to the pcre_extra field in the pcreapi man
|
||
page.
|
||
</p>
|
||
<a name="SecPcreMatchLimitRecursion" id="SecPcreMatchLimitRecursion"></a><h2>
|
||
<span class="mw-headline"> SecPcreMatchLimitRecursion </span></h2>
|
||
<p><b>Description:</b> Sets the match limit recursion in the PCRE
|
||
library.
|
||
</p><p><b>Syntax:</b> <code>SecPcreMatchLimitRecursion value </code>
|
||
</p><p><b>Example Usage:</b> <code>SecPcreMatchLimitRecursion 1500 </code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.5.12
|
||
</p><p><b>Default:</b> 1500
|
||
</p><p>The default can be changed when ModSecurity is prepared for
|
||
compilation: the --enable-pcre-match-limit-recursion=val configure
|
||
option will set a custom default and the
|
||
--disable-pcre-match-limit-recursion option will revert back to the
|
||
default of the PCRE library.
|
||
For more information, refer to the pcre_extra field in the pcreapi man
|
||
page.
|
||
</p>
|
||
<a name="SecPdfProtect" id="SecPdfProtect"></a><h2> <span
|
||
class="mw-headline"> SecPdfProtect </span></h2>
|
||
<p><b>Description:</b> Enables the PDF XSS protection functionality.
|
||
</p><p><b>Syntax:</b> <code>SecPdfProtect On|Off </code>
|
||
</p><p><b>Example Usage:</b> <code>SecPdfProtect On </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0; removed from trunk
|
||
</p><p>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.
|
||
</p>
|
||
<a name="SecPdfProtectMethod" id="SecPdfProtectMethod"></a><h2> <span
|
||
class="mw-headline"> SecPdfProtectMethod </span></h2>
|
||
<p><b>Description</b>: Configure desired protection method to be used
|
||
when requests for PDF files are detected.
|
||
</p><p><b>Syntax:</b> <code>SecPdfProtectMethod method </code>
|
||
</p><p><b>Example Usage</b>: <code>SecPdfProtectMethod TokenRedirection </code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version:</b> 2.5.0; removed from trunk
|
||
</p><p><b>Default:</b> TokenRedirection
|
||
</p><p>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
|
||
works only 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!”).
|
||
</p>
|
||
<a name="SecPdfProtectSecret" id="SecPdfProtectSecret"></a><h2> <span
|
||
class="mw-headline"> SecPdfProtectSecret </span></h2>
|
||
<p><b>Description:</b> Defines the secret that will be used to construct
|
||
one-time tokens.
|
||
</p><p><b>Syntax:</b> <code>SecPdfProtectSecret secret </code>
|
||
</p><p><b>Example Usage:</b> <code>SecPdfProtectSecret
|
||
MyRandomSecretString</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0; removed from trunk
|
||
</p><p>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.
|
||
</p>
|
||
<a name="SecPdfProtectTimeout" id="SecPdfProtectTimeout"></a><h2> <span
|
||
class="mw-headline"> SecPdfProtectTimeout </span></h2>
|
||
<p><b>Description</b>: Defines the token timeout.
|
||
</p><p><b>Syntax:</b> <code>SecPdfProtectTimeout timeout </code>
|
||
</p><p><b>Example Usage</b>: <code>SecPdfProtectTimeout 10 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0; removed from trunk
|
||
</p><p><b>Default:</b> 10
|
||
</p><p>After token expires, it can no longer be used to allow access to a
|
||
PDF file. Request will be allowed through but the PDF will be delivered
|
||
as an attachment.
|
||
</p>
|
||
<a name="SecPdfProtectTokenName" id="SecPdfProtectTokenName"></a><h2> <span
|
||
class="mw-headline"> SecPdfProtectTokenName </span></h2>
|
||
<p><b>Description</b>: Defines the name of the token.
|
||
</p><p><b>Syntax</b>: <code>SecPdfProtectTokenName name </code>
|
||
</p><p><b>Example Usage</b>: <code>SecPdfProtectTokenName PDFTOKEN </code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version</b>: 2.5.0; removed from trunk
|
||
</p><p><b>Default:</b> PDFTOKEN
|
||
</p><p>The only reason you would want to change the name of the token is
|
||
if you wanted to hide the fact that 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.
|
||
</p>
|
||
<a name="SecReadStateLimit" id="SecReadStateLimit"></a><h2> <span
|
||
class="mw-headline"> SecReadStateLimit </span></h2>
|
||
<p><b>Description:</b> Establishes a per-IP address limit of how many
|
||
connections are allowed to be in SERVER_BUSY_READ state.
|
||
</p><p><b>Syntax:</b> <code>SecReadStateLimit LIMIT </code>
|
||
</p><p><b>Example Usage</b>: <code>SecReadStateLimit 50 </code>
|
||
</p><p><b>Scope</b>: Main
|
||
</p><p><b>Version</b>: 2.5.13
|
||
</p><p><b>Default:</b> 0 (no limit)
|
||
</p><p>This measure is effective against Slowloris-style attacks from a
|
||
single IP address, but it may not be as good against modified attacks
|
||
that work by slowly sending request body content. This is because Apache
|
||
to switches state to SERVER_BUSY_WRITE once request headers have been
|
||
read. As an alternative, consider mod_reqtimeout (part of Apache as of
|
||
2.2.15), which is expected be effective against both attack types. See
|
||
Blog post on mitigating slow DoS attacks - <a
|
||
href="http://blog.spiderlabs.com/2010/11/advanced-topic-of-the-week-mitigating-slow-http-dos-attacks.html"
|
||
class="external free"
|
||
title="http://blog.spiderlabs.com/2010/11/advanced-topic-of-the-week-mitigating-slow-http-dos-attacks.html"
|
||
rel="nofollow">http://blog.spiderlabs.com/2010/11/advanced-topic-of-the-week-mitigating-slow-http-dos-attacks.html</a>
|
||
</p>
|
||
<a name="SecSensorId" id="SecSensorId"></a><h2> <span
|
||
class="mw-headline"> SecSensorId </span></h2>
|
||
<p><b>Description:</b> Define a sensor ID that will be present into log
|
||
part H.
|
||
</p><p><b>Syntax:</b> <code>SecSensorId TEXT </code>
|
||
</p><p><b>Example Usage</b>: <code>SecSensorId WAFSensor01 </code>
|
||
</p><p><b>Scope</b>: Main
|
||
</p><p><b>Version</b>: 2.7.0
|
||
</p>
|
||
<a name="SecWriteStateLimit" id="SecWriteStateLimit"></a><h2> <span
|
||
class="mw-headline"> SecWriteStateLimit </span></h2>
|
||
<p><b>Description:</b> Establishes a per-IP address limit of how many
|
||
connections are allowed to be in SERVER_BUSY_WRITE state.
|
||
</p><p><b>Syntax:</b> <code>SecWriteStateLimit LIMIT </code>
|
||
</p><p><b>Example Usage</b>: <code>SecWriteStateLimit 50 </code>
|
||
</p><p><b>Scope</b>: Main
|
||
</p><p><b>Version</b>: 2.6.0
|
||
</p><p><b>Default:</b> 0 (no limit)
|
||
</p><p>This measure is effective against Slow DoS request body attacks.
|
||
</p>
|
||
<a name="SecRequestBodyAccess" id="SecRequestBodyAccess"></a><h2> <span
|
||
class="mw-headline"> SecRequestBodyAccess </span></h2>
|
||
<p><b>Description</b>: Configures whether request bodies will be
|
||
buffered and processed by ModSecurity.
|
||
</p><p><b>Syntax:</b> <code>SecRequestBodyAccess On|Off </code>
|
||
</p><p><b>Example Usage</b>: <code>SecRequestBodyAccess On</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive is required if you want to inspect the data
|
||
transported request bodies (e.g., POST parameters). Request buffering is
|
||
also required in order to make reliable blocking possible. The
|
||
possible values are:
|
||
</p>
|
||
<ul><li>On: buffer request bodies
|
||
</li><li>Off: do not buffer request bodies
|
||
</li></ul>
|
||
<a name="SecRequestBodyInMemoryLimit" id="SecRequestBodyInMemoryLimit"></a><h2>
|
||
<span class="mw-headline"> SecRequestBodyInMemoryLimit </span></h2>
|
||
<p><b>Description</b>: Configures the maximum request body size that
|
||
ModSecurity will store in mem- ory.
|
||
</p><p><b>Syntax:</b> <code>SecRequestBodyInMemoryLimit LIMIT_IN_BYTES </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRequestBodyInMemoryLimit 131072 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> 131072 (128 KB)
|
||
</p><p>When a multipart/form-data request is being processed, once the
|
||
in-memory limit is reached, the request body will start to be streamed
|
||
into a temporary file on disk.
|
||
</p>
|
||
<a name="SecRequestBodyLimit" id="SecRequestBodyLimit"></a><h2> <span
|
||
class="mw-headline"> SecRequestBodyLimit </span></h2>
|
||
<p><b>Description:</b> Configures the maximum request body size
|
||
ModSecurity will accept for buffering.
|
||
</p><p><b>Syntax:</b> <code>SecRequestBodyLimit LIMIT_IN_BYTES </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRequestBodyLimit 134217728 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> 134217728 (131072 KB)
|
||
</p><p>Anything over the limit will be rejected with status code 413
|
||
(Request Entity Too Large). There is a hard limit of 1 GB.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> In ModSecurity 2.5.x and earlier,
|
||
SecRequestBodyLimit works only when used in the main server
|
||
configuration, or a VirtualHost container. In these versions, request
|
||
body limit is enforced immediately after phase 1, but before phase 2
|
||
configuration (i.e. whatever is placed in a Location container) is
|
||
resolved. You can work around this limitation by using a phase 1 rule
|
||
that changes the request body limit dynamically, using the
|
||
ctl:requestBodyLimit action. ModSecurity 2.6.x (currently in the trunk
|
||
only) and better do not have this limitation.
|
||
</dd></dl>
|
||
<a name="SecRequestBodyNoFilesLimit" id="SecRequestBodyNoFilesLimit"></a><h2>
|
||
<span class="mw-headline"> SecRequestBodyNoFilesLimit </span></h2>
|
||
<p><b>Description</b>: Configures the maximum request body size
|
||
ModSecurity will accept for buffering, excluding the size of any files
|
||
being transported in the request. This directive is useful to 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, but because 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.
|
||
</p><p><b>Syntax:</b> <code>SecRequestBodyNoFilesLimit NUMBER_IN_BYTES </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRequestBodyLimit 131072 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version</b>: 2.5.0
|
||
</p><p><b>Default:</b> 1048576 (1 MB)
|
||
</p><p>Generally speaking, the default value is not small enough. 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.
|
||
</p>
|
||
<a name="SecRequestBodyLimitAction" id="SecRequestBodyLimitAction"></a><h2>
|
||
<span class="mw-headline"> SecRequestBodyLimitAction </span></h2>
|
||
<p><b>Description</b>: Controls what happens once a request body limit,
|
||
configured with SecRequestBodyLimit, is encountered
|
||
</p><p><b>Syntax:</b> <code>SecRequestBodyLimitAction
|
||
Reject|ProcessPartial </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRequestBodyLimitAction
|
||
ProcessPartial</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version</b>: 2.6.0
|
||
</p><p>By default, ModSecurity will reject a request body that is longer
|
||
than specified. This is problematic especially when ModSecurity is
|
||
being run in DetectionOnly mode and the intent is to be totally passive
|
||
and not take any disruptive actions against the transaction. With the
|
||
ability to choose what happens once a limit is reached, site
|
||
administrators can choose to inspect only the first part of the request,
|
||
the part that can fit into the desired limit, and let the rest through.
|
||
This is not ideal from a possible evasion issue perspective, however
|
||
it may be acceptable under certain circumstances.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> When the SecRuleEngine is set to
|
||
DetectionOnly, SecRequestBodyLimitAction is automatically set to
|
||
ProcessPartial in order to not cause any disruptions. If you want to
|
||
know if/when a request body size is over your limit, you can create a
|
||
rule to check for the existence of the INBOUND_ERROR_DATA variable.
|
||
</dd></dl>
|
||
<a name="SecResponseBodyLimit" id="SecResponseBodyLimit"></a><h2> <span
|
||
class="mw-headline"> SecResponseBodyLimit </span></h2>
|
||
<p><b>Description:</b> Configures the maximum response body size that
|
||
will be accepted for buffering.
|
||
</p><p><b>Syntax:</b> <code>SecResponseBodyLimit LIMIT_IN_BYTES </code>
|
||
</p><p><b>Example Usage:</b> <code>SecResponseBodyLimit 524228 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default</b>: 524288 (512 KB)
|
||
</p><p>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 selected for buffering. There is a hard limit
|
||
of 1 GB.
|
||
</p>
|
||
<a name="SecResponseBodyLimitAction" id="SecResponseBodyLimitAction"></a><h2>
|
||
<span class="mw-headline"> SecResponseBodyLimitAction </span></h2>
|
||
<p><b>Description:</b> Controls what happens once a response body limit,
|
||
configured with SecResponseBodyLimit, is encountered.
|
||
</p><p><b>Syntax:</b> <code>SecResponseBodyLimitAction
|
||
Reject|ProcessPartial </code>
|
||
</p><p><b>Example Usage:</b> <code>SecResponseBodyLimitAction
|
||
ProcessPartial </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p><p>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
|
||
applies only to cases in which 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.
|
||
</p>
|
||
<a name="SecResponseBodyMimeType" id="SecResponseBodyMimeType"></a><h2> <span
|
||
class="mw-headline"> SecResponseBodyMimeType </span></h2>
|
||
<p><b>Description:</b> Configures which MIME types are to be considered
|
||
for response body buffering.
|
||
</p><p><b>Syntax:</b> <code>SecResponseBodyMimeType MIMETYPE MIMETYPE
|
||
... </code>
|
||
</p><p><b>Example Usage</b>: <code>SecResponseBodyMimeType text/plain
|
||
text/html text/xml</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> text/plain text/html
|
||
</p><p>Multiple SecResponseBodyMimeType directives can be used to add
|
||
MIME types. Use SecResponseBodyMimeTypesClear to clear previously
|
||
configured MIME types and start over.
|
||
</p>
|
||
<a name="SecResponseBodyMimeTypesClear"
|
||
id="SecResponseBodyMimeTypesClear"></a><h2> <span class="mw-headline">
|
||
SecResponseBodyMimeTypesClear </span></h2>
|
||
<p><b>Description:</b> Clears the list of MIME types considered for
|
||
response body buffering, allowing you to start populating the list from
|
||
scratch.
|
||
</p><p><b>Syntax:</b> <code>SecResponseBodyMimeTypesClear </code>
|
||
</p><p><b>Example Usage:</b> <code>SecResponseBodyMimeTypesClear </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p>
|
||
<a name="SecResponseBodyAccess" id="SecResponseBodyAccess"></a><h2> <span
|
||
class="mw-headline"> SecResponseBodyAccess </span></h2>
|
||
<p><b>Description:</b> Configures whether response bodies are to be
|
||
buffered.
|
||
</p><p><b>Syntax:</b> <code>SecResponseBodyAccess On|Off </code>
|
||
</p><p><b>Example Usage:</b> <code>SecResponseBodyAccess On </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>This directive is required if you plan to inspect HTML responses
|
||
and implement response blocking. Possible values are:
|
||
</p>
|
||
<ul><li>On: buffer response bodies (but only if the response MIME type
|
||
matches the list configured with SecResponseBodyMimeType).
|
||
</li><li>Off: do not buffer response bodies.
|
||
</li></ul>
|
||
<a name="SecRule" id="SecRule"></a><h2> <span class="mw-headline">
|
||
SecRule </span></h2>
|
||
<p><b>Description:</b> Creates a rule that will analyze the selected
|
||
variables using the selected operator.
|
||
</p><p><b>Syntax:</b> <code>SecRule VARIABLES OPERATOR [ACTIONS] </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRule ARGS "@rx attack"
|
||
"phase:1,log,deny" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>Every rule must provide one or more variables along with the
|
||
operator that should be used to inspect them. If no actions are
|
||
provided, the default list will be used. (There is always a default
|
||
list, even if one was not explicitly set with SecDefaultAction.) If
|
||
there are actions specified in a rule, they will be merged with the
|
||
default list to form the final actions that will be used. (The actions
|
||
in the rule will overwrite those in the default list.) Refer to
|
||
SecDefaultAction for more information.
|
||
</p>
|
||
<a name="SecRuleInheritance" id="SecRuleInheritance"></a><h2> <span
|
||
class="mw-headline"> SecRuleInheritance </span></h2>
|
||
<p><b>Description:</b> Configures whether the current context will
|
||
inherit the rules from the parent context.
|
||
</p><p><b>Syntax:</b> <code>SecRuleInheritance On|Off </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleInheritance Off </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> On
|
||
</p><p>Sometimes when you create a more specific configuration context
|
||
(for example using the <Location> container), you may wish to use a
|
||
different set of rules than those used in the parent context. By
|
||
setting SecRuleInheritance to Off, you prevent the parent rules to be
|
||
inherited, which allows you to start from scratch. In ModSecurity 2.5.x
|
||
it is not possible to override phase 1 rules from a <Location>
|
||
configuration context. There are no limitations in that respect in the
|
||
current development version (and there won’t be in the next major
|
||
version).
|
||
</p><p>The possible values are:
|
||
</p>
|
||
<ul><li>On: inherit rules from the parent context
|
||
</li><li>Off: do not inherit rules from the parent context
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> 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, under
|
||
Configuration Sections <a
|
||
href="http://httpd.apache.org/docs/2.0/sections.html" class="external
|
||
autonumber" title="http://httpd.apache.org/docs/2.0/sections.html"
|
||
rel="nofollow">[6]</a>. This directive does not affect how configuration
|
||
options are inherited.
|
||
</dd></dl>
|
||
<a name="SecRuleEngine" id="SecRuleEngine"></a><h2> <span
|
||
class="mw-headline"> SecRuleEngine </span></h2>
|
||
<p><b>Description:</b> Configures the rules engine.
|
||
</p><p><b>Syntax:</b> <code>SecRuleEngine On|Off|DetectionOnly</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleEngine On </code>
|
||
</p><p><b>Scope</b>: Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>The possible values are:
|
||
</p>
|
||
<ul><li><b>On</b>: process rules
|
||
</li><li><b>Off</b>: do not process rules
|
||
</li><li><b>DetectionOnly</b>: process rules but never executes any
|
||
disruptive actions (block, deny, drop, allow, proxy and redirect)
|
||
</li></ul>
|
||
<a name="SecRulePerfTime" id="SecRulePerfTime"></a><h2> <span
|
||
class="mw-headline"> SecRulePerfTime </span></h2>
|
||
<p><b>Description:</b> Set a performance threshold for rules. Rules that
|
||
spends too much time will be logged into audit log Part H in the format
|
||
id=usec.
|
||
</p><p><b>Syntax:</b> <code>SecRulePerfTime USECS </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRulePerfTime 1000 </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p>
|
||
<a name="SecRuleRemoveById" id="SecRuleRemoveById"></a><h2> <span
|
||
class="mw-headline"> SecRuleRemoveById </span></h2>
|
||
<p><b>Description:</b> Removes the matching rules from the current
|
||
configuration context.
|
||
</p><p><b>Syntax:</b> <code>SecRuleRemoveById ID ID RANGE ... </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleRemoveByID 1 2 "9000-9010" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive supports multiple parameters, each of which can be
|
||
a rule ID or a range. Parameters that contain spaces must be delimited
|
||
using double quotes.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> <b>This directive must be specified after
|
||
the rule in which it is disabling</b>. This should be used within local
|
||
custom rule files that are processed after third party rule sets.
|
||
Example file - modsecurity_crs_60_customrules.conf.
|
||
</dd></dl>
|
||
<a name="SecRuleRemoveByMsg" id="SecRuleRemoveByMsg"></a><h2> <span
|
||
class="mw-headline"> SecRuleRemoveByMsg </span></h2>
|
||
<p><b>Description:</b> Removes the matching rules from the current
|
||
configuration context.
|
||
</p><p><b>Syntax:</b> <code>SecRuleRemoveByMsg REGEX </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleRemoveByMsg "FAIL" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>Normally, you would use SecRuleRemoveById to remove rules, but
|
||
that requires the rules to have IDs defined. If they don’t, then you can
|
||
remove them with SecRuleRemoveByMsg, which matches a regular expression
|
||
against rule messages.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> This directive must be specified after the
|
||
rule in which it is disabling. This should be used within local custom
|
||
rule files that are processed after third party rule sets. Example file -
|
||
modsecurity_crs_60_customrules.conf.
|
||
</dd></dl>
|
||
<a name="SecRuleRemoveByTag" id="SecRuleRemoveByTag"></a><h2> <span
|
||
class="mw-headline"> SecRuleRemoveByTag </span></h2>
|
||
<p><b>Description:</b> Removes the matching rules from the current
|
||
configuration context.
|
||
</p><p><b>Syntax:</b> <code>SecRuleRemoveByTab REGEX </code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleRemoveByTag "WEB_ATTACK/XSS" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6
|
||
</p><p>Normally, you would use SecRuleRemoveById to remove rules, but
|
||
that requires the rules to have IDs defined. If they don’t, then you can
|
||
remove them with SecRuleRemoveByTag, which matches a regular expression
|
||
against rule tag data. This is useful if you want to disable entire
|
||
groups of rules based on tag data. Example tags used in the OWASP
|
||
ModSecurity CRS include:
|
||
</p>
|
||
<ul><li>AUTOMATION/MALICIOUS
|
||
</li><li>AUTOMATION/MISC
|
||
</li><li>AUTOMATION/SECURITY_SCANNER
|
||
</li><li>LEAKAGE/SOURCE_CODE_ASP_JSP
|
||
</li><li>LEAKAGE/SOURCE_CODE_CF
|
||
</li><li>LEAKAGE/SOURCE_CODE_PHP
|
||
</li><li>WEB_ATTACK/CF_INJECTION
|
||
</li><li>WEB_ATTACK/COMMAND_INJECTION
|
||
</li><li>WEB_ATTACK/FILE_INJECTION
|
||
</li><li>WEB_ATTACK/HTTP_RESPONSE_SPLITTING
|
||
</li><li>WEB_ATTACK/LDAP_INJECTION
|
||
</li><li>WEB_ATTACK/PHP_INJECTION
|
||
</li><li>WEB_ATTACK/REQUEST_SMUGGLING
|
||
</li><li>WEB_ATTACK/SESSION_FIXATION
|
||
</li><li>WEB_ATTACK/SQL_INJECTION
|
||
</li><li>WEB_ATTACK/SSI_INJECTION
|
||
</li><li>WEB_ATTACK/XSS
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> This directive must be specified after the
|
||
rule in which it is disabling. This should be used within local custom
|
||
rule files that are processed after third party rule sets. Example file -
|
||
modsecurity_crs_60_customrules.conf.
|
||
</dd></dl>
|
||
<a name="SecRuleScript" id="SecRuleScript"></a><h2> <span
|
||
class="mw-headline"> SecRuleScript </span></h2>
|
||
<p>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.
|
||
</p><p><b>Syntax:</b> <code>SecRuleScript /path/to/script.lua [ACTIONS]</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleScript "/path/to/file.lua"
|
||
"block"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.0
|
||
</p>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<p>Example script:
|
||
</p>
|
||
<pre>-- Your script must define the main entry
|
||
-- point, as below.
|
||
function main()
|
||
-- Log something at level 1. Normally you shouldn't be
|
||
-- logging anything, especially not at level 1, but this is
|
||
-- just to show you can. Useful for debugging.
|
||
m.log(1, "Hello world!");
|
||
|
||
-- Retrieve one variable.
|
||
local var1 = m.getvar("REMOTE_ADDR");
|
||
|
||
-- Retrieve one variable, applying one transformation function.
|
||
-- The second parameter is a string.
|
||
local var2 = m.getvar("ARGS", "lowercase");
|
||
|
||
-- Retrieve one variable, applying several transformation functions.
|
||
-- The second parameter is now a list. You should note that m.getvar()
|
||
-- requires the use of comma to separate collection names from
|
||
-- variable names. This is because only one variable is returned.
|
||
local var3 = m.getvar("ARGS.p", { "lowercase", "compressWhitespace" } );
|
||
|
||
-- If you want this rule to match return a string
|
||
-- containing the error message. The message must contain the name
|
||
-- of the variable where the problem is located.
|
||
-- return "Variable ARGS:p looks suspicious!"
|
||
|
||
-- Otherwise, simply return nil.
|
||
return nil;
|
||
end
|
||
</pre>
|
||
<p>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.
|
||
</p><p>Example showing use of m.getvars() to retrieve many variables at
|
||
once:
|
||
</p>
|
||
<pre>function main()
|
||
-- Retrieve script parameters.
|
||
local d = m.getvars("ARGS", { "lowercase", "htmlEntityDecode" } );
|
||
|
||
-- Loop through the paramters.
|
||
for i = 1, #d do
|
||
-- Examine parameter value.
|
||
if (string.find(d[i].value, "<script")) then
|
||
-- Always specify the name of the variable where the
|
||
-- problem is located in the error message.
|
||
return ("Suspected XSS in variable " .. d[i].name .. ".");
|
||
end
|
||
end
|
||
|
||
-- Nothing wrong found.
|
||
return nil;
|
||
end
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Go to <a href="http://www.lua.org/"
|
||
class="external free" title="http://www.lua.org/" rel="nofollow">http://www.lua.org/</a>
|
||
to find more about the Lua programming language. The reference manual
|
||
too is available online, at <a href="http://www.lua.org/manual/5.1/"
|
||
class="external free" title="http://www.lua.org/manual/5.1/"
|
||
rel="nofollow">http://www.lua.org/manual/5.1/</a>.
|
||
</dd></dl>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="SecRuleUpdateActionById" id="SecRuleUpdateActionById"></a><h2> <span
|
||
class="mw-headline"> SecRuleUpdateActionById </span></h2>
|
||
<p><b>Description:</b> Updates the action list of the specified rule.
|
||
</p><p><b>Syntax:</b> <code>SecRuleUpdateActionById RULEID[:offset]
|
||
ACTIONLIST</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleUpdateActionById 12345
|
||
"deny,status:403"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.0
|
||
</p><p>This directive will overwrite the action list of the specified
|
||
rule with the actions provided in the second parameter. It has two
|
||
limitations: it cannot be used to change the ID or phase of a rule. Only
|
||
the actions that can appear only once are overwritten. The actions that
|
||
are allowed to appear multiple times in a list, will be appended to the
|
||
end of the list.
|
||
</p>
|
||
<pre>SecRule ARGS attack "phase:2,id:12345,t:lowercase,log,pass,msg:'Message text'"
|
||
SecRuleUpdateActionById 12345 "t:none,t:compressWhitespace,deny,status:403,msg:'New message text'"
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will be as
|
||
follows:
|
||
</p>
|
||
<pre>SecRule ARGS attack "phase:2,id:12345,t:lowercase,t:none,t:compressWhitespace,deny,status:403,msg:'New Message text'"
|
||
</pre>
|
||
<p>The addition of t:none will neutralize any previous transformation
|
||
functions specified (t:lowercase, in the example).
|
||
</p>
|
||
<dl><dt> Note </dt><dd> If the target rule is a chained rule, you
|
||
must currently specify chain in the SecRuleUpdateActionById action list
|
||
as well. This will be fixed in a future version.
|
||
</dd></dl>
|
||
<a name="SecRuleUpdateTargetById" id="SecRuleUpdateTargetById"></a><h2> <span
|
||
class="mw-headline"> SecRuleUpdateTargetById </span></h2>
|
||
<p><b>Description:</b> Updates the target (variable) list of the
|
||
specified rule.
|
||
</p><p><b>Syntax:</b> <code>SecRuleUpdateTargetById RULEID
|
||
TARGET1[,TARGET2,TARGET3] REPLACED_TARGET</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleUpdateTargetById 12345
|
||
"!ARGS:foo"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6
|
||
</p><p>This directive will append (or replace) variables to the current
|
||
target list of the specified rule with the targets provided in the
|
||
second parameter. Starting with 2.7.0 this feature supports id range.
|
||
</p><p><b>Explicitly Appending Targets</b>
|
||
</p><p>This is useful for implementing exceptions where you want to
|
||
externally update a target list to exclude inspection of specific
|
||
variable(s).
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetById 958895 !ARGS:email
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/*|!ARGS:email "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Explicitly Replacing Targets</b>
|
||
</p><p>You can also entirely replace the target list to something more
|
||
appropriate for your environment. For example, lets say you want to
|
||
inspect REQUEST_URI instead of REQUEST_FILENAME, you could do this:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetById 958895 REQUEST_URI REQUEST_FILENAME
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_URI|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Conditionally Appending Targets</b>
|
||
</p><p>You could also do the same by using the ctl action. This is
|
||
useful if you want to only update the targets for a particular URL
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;!ARGS:email"
|
||
</pre>
|
||
<p><b>Conditionally Replacing Targets</b>
|
||
</p><p>You could also replace targets using the ctl action. For
|
||
example, lets say you want to only inspect ARGS for a particular URL:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetById=958895;REQUEST_URI;REQUEST_FILENAME"
|
||
</pre>
|
||
<a name="SecRuleUpdateTargetByMsg" id="SecRuleUpdateTargetByMsg"></a><h2>
|
||
<span class="mw-headline"> SecRuleUpdateTargetByMsg </span></h2>
|
||
<p><b>Description:</b> Updates the target (variable) list of the
|
||
specified rule by rule message.
|
||
</p><p><b>Syntax:</b> <code>SecRuleUpdateTargetByMsg TEXT
|
||
TARGET1[,TARGET2,TARGET3] REPLACED_TARGET</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleUpdateTargetByMsg "Cross-site
|
||
Scripting (XSS) Attack" "!ARGS:foo"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p>This directive will append (or replace) variables to the current
|
||
target list of the specified rule with the targets provided in the
|
||
second parameter.
|
||
</p><p><b>Explicitly Appending Targets</b>
|
||
</p><p>This is useful for implementing exceptions where you want to
|
||
externally update a target list to exclude inspection of specific
|
||
variable(s).
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetByMsg "System Command Injection" !ARGS:email
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/*|!ARGS:email "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Explicitly Replacing Targets</b>
|
||
</p><p>You can also entirely replace the target list to something more
|
||
appropriate for your environment. For example, lets say you want to
|
||
inspect REQUEST_URI instead of REQUEST_FILENAME, you could do this:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetByMsg "System Command Injection" REQUEST_URI REQUEST_FILENAME
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_URI|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Conditionally Appending Targets</b>
|
||
</p><p>You could also do the same by using the ctl action. This is
|
||
useful if you want to only update the targets for a particular URL
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetByMsg='System Command Injection';!ARGS:email"
|
||
</pre>
|
||
<p><b>Conditionally Replacing Targets</b>
|
||
</p><p>You could also replace targets using the ctl action. For
|
||
example, lets say you want to only inspect ARGS for a particular URL:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetByMsg='System Command Injection';REQUEST_URI;REQUEST_FILENAME"
|
||
</pre>
|
||
<a name="SecRuleUpdateTargetByTag" id="SecRuleUpdateTargetByTag"></a><h2>
|
||
<span class="mw-headline"> SecRuleUpdateTargetByTag </span></h2>
|
||
<p><b>Description:</b> Updates the target (variable) list of the
|
||
specified rule by rule tag.
|
||
</p><p><b>Syntax:</b> <code>SecRuleUpdateTargetByTag TEXT
|
||
TARGET1[,TARGET2,TARGET3] REPLACED_TARGET</code>
|
||
</p><p><b>Example Usage:</b> <code>SecRuleUpdateTargetByTag
|
||
"WEB_ATTACK/XSS" "!ARGS:foo"</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p>This directive will append (or replace) variables to the current
|
||
target list of the specified rule with the targets provided in the
|
||
second parameter.
|
||
</p><p><b>Explicitly Appending Targets</b>
|
||
</p><p>This is useful for implementing exceptions where you want to
|
||
externally update a target list to exclude inspection of specific
|
||
variable(s).
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetByTag "WASCTC/WASC-31" !ARGS:email
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/*|!ARGS:email "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Explicitly Replacing Targets</b>
|
||
</p><p>You can also entirely replace the target list to something more
|
||
appropriate for your environment. For example, lets say you want to
|
||
inspect REQUEST_URI instead of REQUEST_FILENAME, you could do this:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}"
|
||
|
||
SecRuleUpdateTargetByTag "WASCTC/WASC-31" REQUEST_URI REQUEST_FILENAME
|
||
</pre>
|
||
<p>The effective resulting rule in the previous example will append the
|
||
target to the end of the variable list as follows:
|
||
</p>
|
||
<pre>SecRule REQUEST_URI|ARGS_NAMES|ARGS|XML:/* "[\;\|\`]\W*?\bmail\b" \
|
||
"phase:2,rev:'2.1.1',capture,t:none,t:htmlEntityDecode,t:compressWhitespace,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'958895',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%
|
||
{tx.0}""
|
||
</pre>
|
||
<p><b>Conditionally Appending Targets</b>
|
||
</p><p>You could also do the same by using the ctl action. This is
|
||
useful if you want to only update the targets for a particular URL
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetByMsg='WASCTC/WASC-31';!ARGS:email"
|
||
</pre>
|
||
<p><b>Conditionally Replacing Targets</b>
|
||
</p><p>You could also replace targets using the ctl action. For
|
||
example, lets say you want to only inspect ARGS for a particular URL:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME "@streq /path/to/file.php" "phase:1,t:none,nolog,pass,ctl:ruleUpdateTargetByMsg='WASCTC/WASC-31';REQUEST_URI;REQUEST_FILENAME"
|
||
</pre>
|
||
<a name="SecServerSignature" id="SecServerSignature"></a><h2> <span
|
||
class="mw-headline"> SecServerSignature </span></h2>
|
||
<p><b>Description:</b> Instructs ModSecurity to change the data
|
||
presented in the "Server:" response header token.
|
||
</p><p><b>Syntax:</b> <code>SecServerSignature "WEB SERVER SOFTWARE"</code>
|
||
</p><p><b>Example Usage:</b> <code>SecServerSignature
|
||
"Microsoft-IIS/6.0"</code>
|
||
</p><p><b>Scope:</b> Main
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>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.
|
||
</p>
|
||
<a name="SecStreamInBodyInspection" id="SecStreamInBodyInspection"></a><h2>
|
||
<span class="mw-headline"> SecStreamInBodyInspection </span></h2>
|
||
<p><b>Description:</b> Configures the ability to use stream inspection
|
||
for inbound request data in a re-allocable buffer. For security reasons
|
||
we are still buffering the stream.
|
||
</p><p><b>Syntax:</b> <code>SecStreamInBodyInspection On|Off</code>
|
||
</p><p><b>Example Usage:</b> <code>SecStreamInBodyInspection On</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.0
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>This feature enables the creation of the STREAM_INPUT_BODY
|
||
variable and is useful for data modification or to match data in raw
|
||
data for any content-types.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> This directive provides full access to
|
||
REQUEST_BODY payload data. It does not include REQUEST_URI or
|
||
REQUEST_HEADER data. Also it provides data to all kind of content types,
|
||
different than REQUEST_BODY.
|
||
</dd></dl>
|
||
<a name="SecStreamOutBodyInspection" id="SecStreamOutBodyInspection"></a><h2>
|
||
<span class="mw-headline"> SecStreamOutBodyInspection </span></h2>
|
||
<p><b>Description:</b> Configures the ability to use stream inspection
|
||
for outbound request data in a re-allocable buffer. For security
|
||
reasons we are still buffering the stream.
|
||
</p><p><b>Syntax:</b> <code>SecStreamOutBodyInspection On|Off</code>
|
||
</p><p><b>Example Usage:</b> <code>SecStreamOutBodyInspection On</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.0
|
||
</p><p><b>Default:</b> Off
|
||
</p><p>This feature enables the creation of the STREAM_OUTPUT_BODY
|
||
variable and is useful when you need to do data modification into
|
||
response body.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> This directive provides access to
|
||
RESPONSE_BODY payload data. It does not include RESPONSE_HEADER data.
|
||
</dd></dl>
|
||
<a name="SecTmpDir" id="SecTmpDir"></a><h2> <span class="mw-headline">
|
||
SecTmpDir </span></h2>
|
||
<p><b>Description:</b> Configures the directory where temporary files
|
||
will be created.
|
||
</p><p><b>Syntax:</b> <code>SecTmpDir /path/to/dir</code>
|
||
</p><p><b>Example Usage:</b> <code>SecTmpDir /tmp</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>The location specified needs to be writable by the Apache user
|
||
process. This is the directory location where ModSecurity will swap data
|
||
to disk if it runs out of memory (more data than what was specified in
|
||
the SecRequestBodyInMemoryLimit directive) during inspection.
|
||
</p>
|
||
<a name="SecUnicodeMapFile" id="SecUnicodeMapFile"></a><h2> <span
|
||
class="mw-headline"> SecUnicodeMapFile </span></h2>
|
||
<p><b>Description:</b> Defines the path to the file that will be used by
|
||
the urlDecodeUni transformation function to map Unicode code points
|
||
during normalization.
|
||
</p><p><b>Syntax:</b> <code>SecUnicodeMapFile /path/to/unicode.mapping</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUnicodeMapFile
|
||
/usr/local/apache/conf/crs/unicode.mapping</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.1
|
||
</p>
|
||
<a name="SecUnicodeCodePage" id="SecUnicodeCodePage"></a><h2> <span
|
||
class="mw-headline"> SecUnicodeCodePage </span></h2>
|
||
<p><b>Description:</b> Defines which Unicode code point will be used by
|
||
the urlDecodeUni transformation function during normalization.
|
||
</p><p><b>Syntax:</b> <code>SecUnicodeCodePage XXXXX</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUnicodeCodePage 20127</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.1
|
||
</p>
|
||
<a name="SecUploadDir" id="SecUploadDir"></a><h2> <span
|
||
class="mw-headline"> SecUploadDir </span></h2>
|
||
<p><b>Description:</b> Configures the directory where intercepted files
|
||
will be stored.
|
||
</p><p><b>Syntax:</b> <code>SecUploadDir /path/to/dir</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUploadDir /tmp</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directory must be on the same filesystem as the temporary
|
||
directory defined with SecTmpDir. This directive is used with
|
||
SecUploadKeepFiles.
|
||
</p>
|
||
<a name="SecUploadFileLimit" id="SecUploadFileLimit"></a><h2> <span
|
||
class="mw-headline"> SecUploadFileLimit </span></h2>
|
||
<p><b>Description:</b> Configures the maximum number of file uploads
|
||
processed in a multipart POST.
|
||
</p><p><b>Syntax:</b> <code>SecUploadFileLimit number</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUploadFileLimit 10</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.5.12
|
||
</p><p>The default is set to 100 files, but you are encouraged to reduce
|
||
this value. Any file over the limit will not be extracted and the
|
||
MULTIPART_FILE_LIMIT_EXCEEDED and MULTIPART_STRICT_ERROR flags will be
|
||
set. To prevent bypassing any file checks, you must check for one of
|
||
these flags.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> If the limit is exceeded, the part name and
|
||
file name will still be recorded in FILES_NAME and FILES, the file size
|
||
will be recorded in FILES_SIZES, but there will be no record in
|
||
FILES_TMPNAMES as a temporary file was not created.
|
||
</dd></dl>
|
||
<a name="SecUploadFileMode" id="SecUploadFileMode"></a><h2> <span
|
||
class="mw-headline"> SecUploadFileMode </span></h2>
|
||
<p><b>Description:</b> Configures the mode (permissions) of any uploaded
|
||
files using an octal mode (as used in chmod).
|
||
</p><p><b>Syntax:</b> <code>SecUploadFileMode octal_mode|"default"</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUploadFileMode 0640</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.1.6
|
||
</p><p>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.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> The process umask may still limit the mode
|
||
if it is being more restrictive than the mode set using this directive.
|
||
</dd></dl>
|
||
<a name="SecUploadKeepFiles" id="SecUploadKeepFiles"></a><h2> <span
|
||
class="mw-headline"> SecUploadKeepFiles </span></h2>
|
||
<p><b>Description:</b> Configures whether or not the intercepted files
|
||
will be kept after transaction is processed.
|
||
</p><p><b>Syntax:</b> <code>SecUploadKeepFiles On|Off|RelevantOnly</code>
|
||
</p><p><b>Example Usage:</b> <code>SecUploadKeepFiles On</code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p>This directive requires the storage directory to be defined
|
||
(using SecUploadDir).
|
||
</p><p>Possible values are:
|
||
</p>
|
||
<ul><li><b>On</b> - Keep uploaded files.
|
||
</li><li><b>Off</b> - Do not keep uploaded files.
|
||
</li><li><b>RelevantOnly</b> - This will keep only those files that
|
||
belong to requests that are deemed relevant.
|
||
</li></ul>
|
||
<a name="SecWebAppId" id="SecWebAppId"></a><h2> <span
|
||
class="mw-headline"> SecWebAppId </span></h2>
|
||
<p><b>Description:</b> Creates an application namespace, allowing for
|
||
separate persistent session and user storage.
|
||
</p><p><b>Syntax:</b> <code>SecWebAppId "NAME" </code>
|
||
</p><p><b>Example Usage:</b> <code>SecWebAppId "WebApp1" </code>
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.0.0
|
||
</p><p><b>Default:</b> default
|
||
</p><p>Application namespaces are used to avoid collisions between
|
||
session IDs and user IDs when multiple applications are deployed on the
|
||
same server. If it isn’t used, a collision between session IDs might
|
||
occur.
|
||
</p>
|
||
<pre><VirtualHost *:80>
|
||
ServerName app1.example.com
|
||
SecWebAppId "App1" ...
|
||
</VirtualHost>
|
||
|
||
<VirtualHost *:80>
|
||
ServerName app2.example.com
|
||
SecWebAppId "App2" ...
|
||
</VirtualHost>
|
||
</pre>
|
||
<p>In the two examples configurations shown, SecWebAppId is being used
|
||
in conjunction with the Apache VirtualHost directives. Applications
|
||
namespace information is also recorded in the audit logs (using the
|
||
WebApp-Info header of the H part).
|
||
</p><p>This directive is used to set collections timeout. For example:
|
||
</p>
|
||
<pre>SecCollectionTimeout 500</pre>
|
||
<a name="SecCollectionTimeout" id="SecCollectionTimeout"></a><h2> <span
|
||
class="mw-headline"> SecCollectionTimeout </span></h2>
|
||
<p><b>Description:</b> Specifies the collections timeout. Default is
|
||
3600 seconds.
|
||
</p><p><b>Syntax:</b> <code>SecCollectionTimeout seconds</code>
|
||
</p><p><b>Default:</b> 3600
|
||
</p><p><b>Scope:</b> Any
|
||
</p><p><b>Version:</b> 2.6.3
|
||
</p>
|
||
<a name="Processing_Phases" id="Processing_Phases"></a><h1> <span
|
||
class="mw-headline"> Processing Phases </span></h1>
|
||
<p>ModSecurity 2.x allows rules to be placed in one of the following
|
||
five phases of the Apache request cycle:
|
||
</p>
|
||
<ul><li>Request headers (REQUEST_HEADERS)
|
||
</li><li>Request body (REQUEST_BODY)
|
||
</li><li>Response headers (RESPONSE_HEADERS)
|
||
</li><li>Response body (RESPONSE_BODY)
|
||
</li><li>Logging (LOGGING)
|
||
</li></ul>
|
||
<p>Below is a diagram of the standard Apache Request Cycle. In the
|
||
diagram, the 5 ModSecurity processing phases are shown.
|
||
</p><p><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=File:Apache_request_cycle-modsecurity.jpg"
|
||
class="image" title="Apache request cycle-modsecurity.jpg"><img alt=""
|
||
src="Reference_Manual_files/600px-Apache_request_cycle-modsecurity.jpg"
|
||
height="459" width="600" border="0"></a>
|
||
</p><p>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:
|
||
</p>
|
||
<pre>SecDefaultAction "log,pass,phase:2"
|
||
SecRule REQUEST_HEADERS:Host "!^$" "deny,phase:1"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The data available in each phase is
|
||
cumulative. This means that as you move onto later phases, you have
|
||
access to more and more data from the transaction.
|
||
</dd><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="Phase_Request_Headers" id="Phase_Request_Headers"></a><h2> <span
|
||
class="mw-headline"> Phase Request Headers </span></h2>
|
||
<p>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).
|
||
</p>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="Phase_Request_Body" id="Phase_Request_Body"></a><h2> <span
|
||
class="mw-headline"> Phase Request Body </span></h2>
|
||
<p>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:
|
||
</p>
|
||
<ul><li><b>application/x-www-form-urlencoded</b> - used to transfer form
|
||
data
|
||
</li><li><b>multipart/form-data</b> - used for file transfers
|
||
</li><li><b>text/xml</b> - used for passing XML data
|
||
</li></ul>
|
||
<p>Other encodings are not used by most web applications.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> In order to access the Request Body phase
|
||
data, you must have SecRequestBodyAccess set to On.
|
||
</dd></dl>
|
||
<a name="Phase_Response_Headers" id="Phase_Response_Headers"></a><h2> <span
|
||
class="mw-headline"> Phase Response Headers </span></h2>
|
||
<p>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).
|
||
</p>
|
||
<a name="Phase_Response_Body" id="Phase_Response_Body"></a><h2> <span
|
||
class="mw-headline"> Phase Response Body </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> In order to access the Response Body phase
|
||
data, you must have SecResponseBodyAccess set to On
|
||
</dd></dl>
|
||
<a name="Phase_Logging" id="Phase_Logging"></a><h2> <span
|
||
class="mw-headline"> Phase Logging </span></h2>
|
||
<p>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
|
||
</p>
|
||
<a name="Variables" id="Variables"></a><h1> <span class="mw-headline">
|
||
Variables </span></h1>
|
||
<p>The following variables are supported in ModSecurity 2.x:
|
||
</p>
|
||
<a name="ARGS" id="ARGS"></a><h2> <span class="mw-headline"> ARGS </span></h2>
|
||
<p>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.
|
||
</p><p>Some variables are actually collections, which are expanded into
|
||
more variables at runtime. The following example will examine all
|
||
request arguments:
|
||
</p><p><code>SecRule ARGS dirty</code>
|
||
</p><p>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):
|
||
</p><p><code>SecRule ARGS:p dirty</code>
|
||
</p><p>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):
|
||
</p><p><code>SecRule ARGS|!ARGS:z dirty</code>
|
||
</p><p>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):
|
||
</p><p><code>SecRule &ARGS !^0$</code>
|
||
</p><p>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_:
|
||
</p><p><code>SecRule ARGS:/^id_/ dirty</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Using ARGS:p will not result in any
|
||
invocations against the operator if argument p does not exist.
|
||
</dd></dl>
|
||
<p>In ModSecurity 1.X, the ARGS variable stood for QUERY_STRING +
|
||
POST_PAYLOAD, whereas now it expands to individual variables.
|
||
</p>
|
||
<a name="ARGS_COMBINED_SIZE" id="ARGS_COMBINED_SIZE"></a><h2> <span
|
||
class="mw-headline"> ARGS_COMBINED_SIZE </span></h2>
|
||
<p>Contains the combined size of all request parameters. Files are
|
||
excluded from the calculation. This variable can be useful, for example,
|
||
to create a rule to ensure that the total size of the argument data is
|
||
below a certain threshold. The following rule detects a request whose
|
||
para- meters are more than 2500 bytes long:
|
||
</p><p><code>SecRule ARGS_COMBINED_SIZE "@gt 2500"</code>
|
||
</p>
|
||
<a name="ARGS_GET" id="ARGS_GET"></a><h2> <span class="mw-headline">
|
||
ARGS_GET </span></h2>
|
||
<p>ARGS_GET is similar to ARGS, but contains only query string
|
||
parameters.
|
||
</p>
|
||
<a name="ARGS_GET_NAMES" id="ARGS_GET_NAMES"></a><h2> <span
|
||
class="mw-headline"> ARGS_GET_NAMES </span></h2>
|
||
<p>ARGS_GET_NAMES is similar to ARGS_NAMES, but contains only the names
|
||
of query string parameters.
|
||
</p>
|
||
<a name="ARGS_NAMES" id="ARGS_NAMES"></a><h2> <span class="mw-headline">
|
||
ARGS_NAMES </span></h2>
|
||
<p>Contains all request parameter names. You can search for specific
|
||
parameter names that you want to inspect. In a positive policy scenario,
|
||
you can also whitelist (using an inverted rule with the exclamation
|
||
mark) only the authorized argument names.
|
||
This example rule allows only two argument names: p and a:
|
||
</p><p><code>SecRule ARGS_NAMES "!^(p|a)$"</code>
|
||
</p>
|
||
<a name="ARGS_POST" id="ARGS_POST"></a><h2> <span class="mw-headline">
|
||
ARGS_POST </span></h2>
|
||
<p>ARGS_POST is similar to ARGS, but only contains arguments from the
|
||
POST body.
|
||
</p>
|
||
<a name="ARGS_POST_NAMES" id="ARGS_POST_NAMES"></a><h2> <span
|
||
class="mw-headline"> ARGS_POST_NAMES </span></h2>
|
||
<p>ARGS_POST_NAMES is similar to ARGS_NAMES, but contains only the names
|
||
of request body parameters.
|
||
</p>
|
||
<a name="AUTH_TYPE" id="AUTH_TYPE"></a><h2> <span class="mw-headline">
|
||
AUTH_TYPE </span></h2>
|
||
<p>This variable holds the authentication method used to validate a
|
||
user, if any of the methods built into HTTP are used. In a reverse-proxy
|
||
deployment, this information will not be available if the
|
||
authentication is handled in the backend web server.
|
||
</p><p><code>SecRule AUTH_TYPE "Basic"</code>
|
||
</p>
|
||
<a name="DURATION" id="DURATION"></a><h2> <span class="mw-headline">
|
||
DURATION </span></h2>
|
||
<p>Contains the number of milliseconds elapsed since the beginning of
|
||
the current transaction. Available starting with 2.6.0.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Starting with ModSecurity 2.7.0 the time is
|
||
microseconds.
|
||
</dd></dl>
|
||
<a name="ENV" id="ENV"></a><h2> <span class="mw-headline"> ENV </span></h2>
|
||
<p>Collection that provides access to environment variables set by
|
||
ModSecurity. Requires a single parameter to specify the name of the
|
||
desired variable.
|
||
</p>
|
||
<pre># Set environment variable
|
||
SecRule REQUEST_FILENAME "printenv" \
|
||
"phase:2,pass,setenv:tag=suspicious"
|
||
|
||
# Inspect environment variable
|
||
SecRule ENV:tag "suspicious"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Use setenv to set environment variables to
|
||
be accessed by Apache.
|
||
</dd></dl>
|
||
<a name="FILES" id="FILES"></a><h2> <span class="mw-headline"> FILES </span></h2>
|
||
<p>Contains a collection of original file names (as they were called on
|
||
the remote user’s filesys- tem). Available only on inspected
|
||
multipart/form-data requests.
|
||
</p><p><code>SecRule FILES "@rx \.conf$"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Only available if files were extracted from
|
||
the request body.
|
||
</dd></dl>
|
||
<a name="FILES_COMBINED_SIZE" id="FILES_COMBINED_SIZE"></a><h2> <span
|
||
class="mw-headline"> FILES_COMBINED_SIZE </span></h2>
|
||
<p>Contains the total size of the files transported in request body.
|
||
Available only on inspected multipart/form-data requests.
|
||
</p><p><code>SecRule FILES_COMBINED_SIZE "@gt 100000"</code>
|
||
</p>
|
||
<a name="FILES_NAMES" id="FILES_NAMES"></a><h2> <span
|
||
class="mw-headline"> FILES_NAMES </span></h2>
|
||
<p>Contains a list of form fields that were used for file upload.
|
||
Available only on inspected multipart/form-data requests.
|
||
</p><p><code>SecRule FILES_NAMES "^upfile$"</code>
|
||
</p>
|
||
<a name="FILES_SIZES" id="FILES_SIZES"></a><h2> <span
|
||
class="mw-headline"> FILES_SIZES </span></h2>
|
||
<p>Contains a list of individual file sizes. Useful for implementing a
|
||
size limitation on individual uploaded files. Available only on
|
||
inspected multipart/form-data requests.
|
||
</p><p><code>SecRule FILES_SIZES "@gt 100"</code>
|
||
</p>
|
||
<a name="FILES_TMPNAMES" id="FILES_TMPNAMES"></a><h2> <span
|
||
class="mw-headline"> FILES_TMPNAMES </span></h2>
|
||
<p>Contains a list of temporary files’ names on the disk. Useful when
|
||
used together with @inspectFile. Available only on inspected
|
||
multipart/form-data requests.
|
||
</p><p><code>SecRule FILES_TMPNAMES "@inspectFile
|
||
/path/to/inspect_script.pl"</code>
|
||
</p>
|
||
<a name="GEO" id="GEO"></a><h2> <span class="mw-headline"> GEO </span></h2>
|
||
<p>GEO is a collection populated by the results of the last @geoLookup
|
||
operator. The collection can be used to match geographical fields looked
|
||
from an IP address or hostname.
|
||
</p><p>Available since ModSecurity 2.5.0.
|
||
</p><p>Fields:
|
||
</p>
|
||
<ul><li>COUNTRY_CODE: Two character country code. EX: US, GB, etc.
|
||
</li><li>COUNTRY_CODE3: Up to three character country code.
|
||
</li><li>COUNTRY_NAME: The full country name.
|
||
</li><li>COUNTRY_CONTINENT: The two character continent that the country
|
||
is located. EX: EU
|
||
</li><li>REGION: The two character region. For US, this is state. For
|
||
Canada, providence, etc.
|
||
</li><li>CITY: The city name if supported by the database.
|
||
</li><li>POSTAL_CODE: The postal code if supported by the database.
|
||
</li><li>LATITUDE: The latitude if supported by the database.
|
||
</li><li>LONGITUDE: The longitude if supported by the database.
|
||
</li><li>DMA_CODE: The metropolitan area code if supported by the
|
||
database. (US only)
|
||
</li><li>AREA_CODE: The phone system area code. (US only)
|
||
</li></ul>
|
||
<p>Example:
|
||
</p>
|
||
<pre>SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat
|
||
...
|
||
SecRule REMOTE_ADDR "@geoLookup" "chain,drop,msg:'Non-GB IP address'"
|
||
SecRule GEO:COUNTRY_CODE "!@streq GB"
|
||
</pre>
|
||
<a name="HIGHEST_SEVERITY" id="HIGHEST_SEVERITY"></a><h2> <span
|
||
class="mw-headline"> HIGHEST_SEVERITY </span></h2>
|
||
<p>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, and so on. A value of 255 indicates
|
||
that no severity has been set.
|
||
</p><p><code>SecRule HIGHEST_SEVERITY "@le 2"
|
||
"phase:2,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Higher severities have a lower numeric
|
||
value.
|
||
</dd></dl>
|
||
<a name="INBOUND_ERROR_DATA" id="INBOUND_ERROR_DATA"></a><h2> <span
|
||
class="mw-headline"> INBOUND_ERROR_DATA </span></h2>
|
||
<p>This variable will be set to 1 when the request body size is above
|
||
the setting configured by SecRequestBodyLimit directive. Your policies
|
||
should always contain a rule to check this variable. 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.
|
||
</p><p>The best way to use this variable is as in the example below:
|
||
</p><p><code>SecRule INBOUND_ERROR_DATA "@eq 1"
|
||
"phase:1,t:none,log,pass,msg:'Request Body Larger than
|
||
SecRequestBodyLimit Setting'"</code>
|
||
</p>
|
||
<a name="MATCHED_VAR" id="MATCHED_VAR"></a><h2> <span
|
||
class="mw-headline"> MATCHED_VAR </span></h2>
|
||
<p>This variable holds the value of the most-recently matched variable.
|
||
It is similar to the TX:0, but it is automatically supported by all
|
||
operators and there is no need to specify the capture action.
|
||
</p>
|
||
<pre>SecRule ARGS pattern chain,deny
|
||
SecRule MATCHED_VAR "further scrutiny"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Be aware that this variable holds data for
|
||
the <i><b>last</b></i> operator match. This means that if there are
|
||
more than one matches, only the last one will be populated. Use
|
||
MATCHED_VARS variable if you want all matches.
|
||
</dd></dl>
|
||
<a name="MATCHED_VARS" id="MATCHED_VARS"></a><h2> <span
|
||
class="mw-headline"> MATCHED_VARS </span></h2>
|
||
<p>Similar to MATCHED_VAR except that it is a collection of <i><b>all
|
||
matches</b></i> for the current operator check.
|
||
</p>
|
||
<pre>SecRule ARGS pattern "chain,deny"
|
||
SecRule MATCHED_VARS "@eq ARGS:param"
|
||
</pre>
|
||
<a name="MATCHED_VAR_NAME" id="MATCHED_VAR_NAME"></a><h2> <span
|
||
class="mw-headline"> MATCHED_VAR_NAME </span></h2>
|
||
<p>This variable holds the full name of the variable that was matched
|
||
against.
|
||
</p>
|
||
<pre>SecRule ARGS pattern "chain,deny"
|
||
SecRule MATCHED_VAR_NAME "@eq ARGS:param"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Be aware that this variable holds data for
|
||
the <i><b>last</b></i> operator match. This means that if there are
|
||
more than one matches, only the last one will be populated. Use
|
||
MATCHED_VARS_NAMES variable if you want all matches.
|
||
</dd></dl>
|
||
<a name="MATCHED_VARS_NAMES" id="MATCHED_VARS_NAMES"></a><h2> <span
|
||
class="mw-headline"> MATCHED_VARS_NAMES </span></h2>
|
||
<p>Similar to MATCHED_VAR_NAME except that it is a collection of <i><b>all
|
||
matches</b></i> for the current operator check.
|
||
</p>
|
||
<pre>SecRule ARGS pattern "chain,deny"
|
||
SecRule MATCHED_VARS_NAMES "@eq ARGS:param"
|
||
</pre>
|
||
<a name="MODSEC_BUILD" id="MODSEC_BUILD"></a><h2> <span
|
||
class="mw-headline"> MODSEC_BUILD </span></h2>
|
||
<p>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:
|
||
</p>
|
||
<pre>SecRule MODSEC_BUILD "!@ge 02050102" "skipAfter:12345"
|
||
SecRule ARGS "@pm some key words" "id:12345,deny,status:500"
|
||
</pre>
|
||
<a name="MULTIPART_CRLF_LF_LINES" id="MULTIPART_CRLF_LF_LINES"></a><h2> <span
|
||
class="mw-headline"> MULTIPART_CRLF_LF_LINES </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="MULTIPART_STRICT_ERROR" id="MULTIPART_STRICT_ERROR"></a><h2> <span
|
||
class="mw-headline"> MULTIPART_STRICT_ERROR </span></h2>
|
||
<p>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 MULTIPART_INVALID_QUOTING
|
||
MULTIPART_INVALID_HEADER_FOLDING MULTIPART_FILE_LIMIT_EXCEEDED. 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.
|
||
</p><p>The best way to use this variable is as in the example below:
|
||
</p>
|
||
<pre>SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
|
||
"phase:2,t:none,log,deny,msg:'Multipart request body \
|
||
failed strict validation: \
|
||
PE %{REQBODY_PROCESSOR_ERROR}, \
|
||
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
|
||
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
|
||
DB %{MULTIPART_DATA_BEFORE}, \
|
||
DA %{MULTIPART_DATA_AFTER}, \
|
||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||
LF %{MULTIPART_LF_LINE}, \
|
||
SM %{MULTIPART_SEMICOLON_MISSING}, \
|
||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||
IQ %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||
FE %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||
</pre>
|
||
<p>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.
|
||
</p>
|
||
<a name="MULTIPART_UNMATCHED_BOUNDARY" id="MULTIPART_UNMATCHED_BOUNDARY"></a><h2>
|
||
<span class="mw-headline"> MULTIPART_UNMATCHED_BOUNDARY </span></h2>
|
||
<p>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.
|
||
</p><p>The best way to use this variable is as in the example below:
|
||
</p>
|
||
<pre>SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
|
||
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||
</pre>
|
||
<p>Change the rule from blocking to logging-only if many false positives
|
||
are encountered.
|
||
</p>
|
||
<a name="PATH_INFO" id="PATH_INFO"></a><h2> <span class="mw-headline">
|
||
PATH_INFO </span></h2>
|
||
<p>Contains the extra request URI information, also known as path info.
|
||
(For example, in the URI /index.php/123, /123 is the path info.)
|
||
Available only in embedded deployments.
|
||
</p><p><code>SecRule PATH_INFO "^/(bin|etc|sbin|opt|usr)"</code>
|
||
</p>
|
||
<a name="PERF_COMBINED" id="PERF_COMBINED"></a><h2> <span
|
||
class="mw-headline"> PERF_COMBINED </span></h2>
|
||
<p>Contains the time, in microseconds, spent in ModSecurity during the
|
||
current transaction. The value in this variable is arrived to by adding
|
||
all the performance variables except PERF_SREAD (the time spent reading
|
||
from persistent storage is already included in the phase measurements).
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_GC" id="PERF_GC"></a><h2> <span class="mw-headline">
|
||
PERF_GC </span></h2>
|
||
<p>Contains the time, in microseconds, spent performing garbage
|
||
collection. Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_LOGGING" id="PERF_LOGGING"></a><h2> <span
|
||
class="mw-headline"> PERF_LOGGING </span></h2>
|
||
<p>Contains the time, in microseconds, spent in audit logging. This
|
||
value is known only after the handling of a transaction is finalized,
|
||
which means that it can only be logged using mod_log_config and
|
||
the %{VARNAME}M syntax. Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_PHASE1" id="PERF_PHASE1"></a><h2> <span
|
||
class="mw-headline"> PERF_PHASE1 </span></h2>
|
||
<p>Contains the time, in microseconds, spent processing phase 1.
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_PHASE2" id="PERF_PHASE2"></a><h2> <span
|
||
class="mw-headline"> PERF_PHASE2 </span></h2>
|
||
<p>Contains the time, in microseconds, spent processing phase 2.
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_PHASE3" id="PERF_PHASE3"></a><h2> <span
|
||
class="mw-headline"> PERF_PHASE3 </span></h2>
|
||
<p>Contains the time, in microseconds, spent processing phase 3.
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_PHASE4" id="PERF_PHASE4"></a><h2> <span
|
||
class="mw-headline"> PERF_PHASE4 </span></h2>
|
||
<p>Contains the time, in microseconds, spent processing phase 4.
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_PHASE5" id="PERF_PHASE5"></a><h2> <span
|
||
class="mw-headline"> PERF_PHASE5 </span></h2>
|
||
<p>Contains the time, in microseconds, spent processing phase 5.
|
||
Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_RULES" id="PERF_RULES"></a><h2> <span class="mw-headline">
|
||
PERF_RULES </span></h2>
|
||
<p>Contains the time of rules, in microseconds. Available starting with
|
||
2.7.
|
||
</p><p><code>SecRule PERF_RULES "@gt 1000" "id:12345,phase:5"</code>
|
||
</p>
|
||
<a name="PERF_SREAD" id="PERF_SREAD"></a><h2> <span class="mw-headline">
|
||
PERF_SREAD </span></h2>
|
||
<p>Contains the time, in microseconds, spent reading from persistent
|
||
storage. Available starting with 2.6.
|
||
</p>
|
||
<a name="PERF_SWRITE" id="PERF_SWRITE"></a><h2> <span
|
||
class="mw-headline"> PERF_SWRITE </span></h2>
|
||
<p>Contains the time, in microseconds, spent writing to persistent
|
||
storage. Available starting with 2.6.
|
||
</p>
|
||
<a name="QUERY_STRING" id="QUERY_STRING"></a><h2> <span
|
||
class="mw-headline"> QUERY_STRING </span></h2>
|
||
<p>Contains the query string part of a request URI. The value in
|
||
QUERY_STRING is always provided raw, without URL decoding taking place.
|
||
</p><p><code>SecRule QUERY_STRING "attack"</code>
|
||
</p>
|
||
<a name="REMOTE_ADDR" id="REMOTE_ADDR"></a><h2> <span
|
||
class="mw-headline"> REMOTE_ADDR </span></h2>
|
||
<p>This variable holds the IP address of the remote client.
|
||
</p><p><code>SecRule REMOTE_ADDR "@ipMatch 192.168.1.101"</code>
|
||
</p>
|
||
<a name="REMOTE_HOST" id="REMOTE_HOST"></a><h2> <span
|
||
class="mw-headline"> REMOTE_HOST </span></h2>
|
||
<p>If the Apache directive HostnameLookups is set to On, then this
|
||
variable will hold the remote hostname resolved through DNS. If the
|
||
directive is set to Off, this variable it will hold the remote IP
|
||
address (same as REMOTE_ADDR). Possible uses for this variable would be
|
||
to deny known bad client hosts or network blocks, or conversely, to
|
||
allow in authorized hosts.
|
||
</p><p><code>SecRule REMOTE_HOST "\.evil\.network\org$"</code>
|
||
</p>
|
||
<a name="REMOTE_PORT" id="REMOTE_PORT"></a><h2> <span
|
||
class="mw-headline"> REMOTE_PORT </span></h2>
|
||
<p>This variable holds information on the source port that the client
|
||
used when initiating the connection to our web server.
|
||
</p><p>In the following example, we are evaluating to see whether the
|
||
REMOTE_PORT is less than 1024, which would indicate that the user is a
|
||
privileged user:
|
||
</p><p><code>SecRule REMOTE_PORT "@lt 1024"</code>
|
||
</p>
|
||
<a name="REMOTE_USER" id="REMOTE_USER"></a><h2> <span
|
||
class="mw-headline"> REMOTE_USER </span></h2>
|
||
<p>This variable holds the username of the authenticated user. If there
|
||
are no password access controls in place (Basic or Digest
|
||
authentication), then this variable will be empty.
|
||
</p><p><code>SecRule REMOTE_USER "^admin$" </code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> In a reverse-proxy deployment, this
|
||
information will not be available if the authentication is
|
||
</dd></dl>
|
||
<p>handled in the backend web server.
|
||
</p>
|
||
<a name="REQBODY_ERROR" id="REQBODY_ERROR"></a><h2> <span
|
||
class="mw-headline"> REQBODY_ERROR </span></h2>
|
||
<p>Contains the status of the request body processor used for request
|
||
body parsing. The values can be 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 do
|
||
their work.
|
||
</p><p><code>SecRule REQBODY_ERROR "@eq 1" deny,phase:2 </code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Your policies must have a rule to check for
|
||
request body processor errors at the very 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.
|
||
</dd></dl>
|
||
<a name="REQBODY_ERROR_MSG" id="REQBODY_ERROR_MSG"></a><h2> <span
|
||
class="mw-headline"> REQBODY_ERROR_MSG </span></h2>
|
||
<p>If there’s been an error during request body parsing, the variable
|
||
will contain the following error message:
|
||
</p><p><code>SecRule REQBODY_ERROR_MSG "failed to parse"</code>
|
||
</p>
|
||
<a name="REQBODY_PROCESSOR" id="REQBODY_PROCESSOR"></a><h2> <span
|
||
class="mw-headline"> REQBODY_PROCESSOR </span></h2>
|
||
<p>Contains the name of the currently used request body processor. The
|
||
possible values are URLENCODED, MULTIPART, and XML.
|
||
</p>
|
||
<pre>SecRule REQBODY_PROCESSOR "^XML$ chain
|
||
SecRule XML "@validateDTD /opt/apache-frontend/conf/xml.dtd"
|
||
</pre>
|
||
<a name="REQUEST_BASENAME" id="REQUEST_BASENAME"></a><h2> <span
|
||
class="mw-headline"> REQUEST_BASENAME </span></h2>
|
||
<p>This variable holds just the filename part of REQUEST_FILENAME (e.g.,
|
||
index.php).
|
||
</p><p><code>SecRule REQUEST_BASENAME "^login\.php$"
|
||
phase:2,t:none,t:lowercase</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Please note that anti-evasion
|
||
transformations are not applied to this variable by default.
|
||
REQUEST_BASENAME will recognise both / and \ as path separators. You
|
||
should understand that the value of this variable depends on what was
|
||
provided in request, and that it does not have to correspond to the
|
||
resource (on disk) that will be used by the web server.
|
||
</dd></dl>
|
||
<a name="REQUEST_BODY" id="REQUEST_BODY"></a><h2> <span
|
||
class="mw-headline"> REQUEST_BODY </span></h2>
|
||
<p>Holds the raw request body. This variable is available only if the
|
||
URLENCODED request body processor was used, which will occur by default
|
||
when the application/x-www-form-urlencoded content type is detected, or
|
||
if the use of the URLENCODED request body parser was forced.
|
||
</p><p><code>SecRule REQUEST_BODY
|
||
"^username=\w{25,}\&password=\w{25,}\&Submit\=login$"</code>
|
||
</p><p>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.
|
||
</p>
|
||
<a name="REQUEST_BODY_LENGTH" id="REQUEST_BODY_LENGTH"></a><h2> <span
|
||
class="mw-headline"> REQUEST_BODY_LENGTH </span></h2>
|
||
<p>Contains the number of bytes read from a request body. Available
|
||
starting with v2.6
|
||
</p>
|
||
<a name="REQUEST_COOKIES" id="REQUEST_COOKIES"></a><h2> <span
|
||
class="mw-headline"> REQUEST_COOKIES </span></h2>
|
||
<p>This variable is a collection of all of request cookies (values
|
||
only). 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.
|
||
</p><p><code>SecRule &REQUEST_COOKIES "@eq 0"</code>
|
||
</p>
|
||
<a name="REQUEST_COOKIES_NAMES" id="REQUEST_COOKIES_NAMES"></a><h2> <span
|
||
class="mw-headline"> REQUEST_COOKIES_NAMES </span></h2>
|
||
<p>This variable is a collection of the names of all request cookies.
|
||
For example, the following rule will trigger if the JSESSIONID cookie is
|
||
not present:
|
||
</p><p><code>SecRule &REQUEST_COOKIES_NAMES:JSESSIONID "@eq 0"</code>
|
||
</p>
|
||
<a name="REQUEST_FILENAME" id="REQUEST_FILENAME"></a><h2> <span
|
||
class="mw-headline"> REQUEST_FILENAME </span></h2>
|
||
<p>This variable holds the relative request URL without the query string
|
||
part (e.g., /index.php).
|
||
</p><p><code>SecRule REQUEST_FILENAME "^/cgi-bin/login\.php$"
|
||
phase:2,t:none,t:normalizePath</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Please note that anti-evasion
|
||
transformations are not used on REQUEST_FILENAME, which means that you
|
||
will have to specify them in the rules that use this variable.
|
||
</dd></dl>
|
||
<a name="REQUEST_HEADERS" id="REQUEST_HEADERS"></a><h2> <span
|
||
class="mw-headline"> REQUEST_HEADERS </span></h2>
|
||
<p>This variable can be used as either a collection of all of the
|
||
request headers or can be used to inspect selected headers (by using the
|
||
REQUEST_HEADERS:Header-Name syntax).
|
||
</p><p><code>SecRule REQUEST_HEADERS:Host "^[\d\.]+$"
|
||
"deny,log,status:400,msg:'Host header is a numeric IP address'"</code>
|
||
</p>
|
||
<a name="REQUEST_HEADERS_NAMES" id="REQUEST_HEADERS_NAMES"></a><h2> <span
|
||
class="mw-headline"> REQUEST_HEADERS_NAMES </span></h2>
|
||
<p>This variable is a collection of the names of all of the request
|
||
headers.
|
||
</p><p><code>SecRule REQUEST_HEADERS_NAMES "^x-forwarded-for"
|
||
"log,deny,status:403,t:lowercase,msg:'Proxy Server Used'"</code>
|
||
</p>
|
||
<a name="REQUEST_LINE" id="REQUEST_LINE"></a><h2> <span
|
||
class="mw-headline"> REQUEST_LINE </span></h2>
|
||
<p>This variable holds the complete request line sent to the server
|
||
(including the request method and HTTP version information).
|
||
</p>
|
||
<pre># Allow only POST, GET and HEAD request methods, as well as only
|
||
# the valid protocol versions
|
||
SecRule REQUEST_LINE "!(^((?:(?:POS|GE)T|HEAD))|HTTP/(0\.9|1\.0|1\.1)$)" "phase:1,log,block,t:none"
|
||
</pre>
|
||
<a name="REQUEST_METHOD" id="REQUEST_METHOD"></a><h2> <span
|
||
class="mw-headline"> REQUEST_METHOD </span></h2>
|
||
<p>This variable holds the request method used in the transaction.
|
||
</p><p><code>SecRule REQUEST_METHOD "^(?:CONNECT|TRACE)$" "t:none"</code>
|
||
</p>
|
||
<a name="REQUEST_PROTOCOL" id="REQUEST_PROTOCOL"></a><h2> <span
|
||
class="mw-headline"> REQUEST_PROTOCOL </span></h2>
|
||
<p>This variable holds the request protocol version information.
|
||
</p><p><code>SecRule REQUEST_PROTOCOL "!^HTTP/(0\.9|1\.0|1\.1)$"</code>
|
||
</p>
|
||
<a name="REQUEST_URI" id="REQUEST_URI"></a><h2> <span
|
||
class="mw-headline"> REQUEST_URI </span></h2>
|
||
<p>This variable holds the full request 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.
|
||
</p><p><code>SecRule REQUEST_URI "attack"
|
||
"phase:1,t:none,t:urlDecode,t:lowercase,t:normalizePath"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Please note that anti-evasion
|
||
transformations are not used on REQUEST_URI, which means that you will
|
||
have to specify them in the rules that use this variable.
|
||
</dd></dl>
|
||
<a name="REQUEST_URI_RAW" id="REQUEST_URI_RAW"></a><h2> <span
|
||
class="mw-headline"> REQUEST_URI_RAW </span></h2>
|
||
<p>Same as REQUEST_URI but will contain the domain name if it was
|
||
provided on the request line (e.g., <a
|
||
href="http://www.example.com/index.php?p=X" class="external free"
|
||
title="http://www.example.com/index.php?p=X" rel="nofollow">http://www.example.com/index.php?p=X</a>).
|
||
</p><p><code>SecRule REQUEST_URI_RAW "http:/"
|
||
"phase:1,t:none,t:urlDecode,t:lowercase,t:normalizePath"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Please note that anti-evasion
|
||
transformations are not used on REQUEST_URI_RAW, which means that you
|
||
will have to specify them in the rules that use this variable.
|
||
</dd></dl>
|
||
<a name="RESPONSE_BODY" id="RESPONSE_BODY"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_BODY </span></h2>
|
||
<p>This variable holds the data for the response body, but only when
|
||
response body buffering is enabled.
|
||
</p><p><code>SecRule RESPONSE_BODY "ODBC Error Code" "phase:4,t:none"</code>
|
||
</p>
|
||
<a name="RESPONSE_CONTENT_LENGTH" id="RESPONSE_CONTENT_LENGTH"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_CONTENT_LENGTH </span></h2>
|
||
<p>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.
|
||
</p>
|
||
<a name="RESPONSE_CONTENT_TYPE" id="RESPONSE_CONTENT_TYPE"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_CONTENT_TYPE </span></h2>
|
||
<p>Response content type. Available only starting with phase 3. The
|
||
value available in this variable is taken directly from the internal
|
||
structures of Apache, which means that it may contain the information
|
||
that is not yet available in response headers. In embedded deployments,
|
||
you should always refer to this variable, rather than to
|
||
RESPONSE_HEADERS:Content-Type.
|
||
</p>
|
||
<a name="RESPONSE_HEADERS" id="RESPONSE_HEADERS"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_HEADERS </span></h2>
|
||
<p>This variable refers to response headers, in the same way as
|
||
REQUEST_HEADERS does to request headers.
|
||
</p><p><code>SecRule RESPONSE_HEADERS:X-Cache "MISS"</code>
|
||
</p><p>This variable may not have access to some headers when running in
|
||
embedded mode. Headers such as Server, Date, Connection, and
|
||
Content-Type could be added just prior to sending the data to the
|
||
client. This data should be available in phase 5 or when deployed in
|
||
proxy mode.
|
||
</p>
|
||
<a name="RESPONSE_HEADERS_NAMES" id="RESPONSE_HEADERS_NAMES"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_HEADERS_NAMES </span></h2>
|
||
<p>This variable is a collection of the response header names.
|
||
</p><p><code>SecRule RESPONSE_HEADERS_NAMES "Set-Cookie"
|
||
"phase:3,t:none"</code>
|
||
</p><p>The same limitations apply as the ones discussed in
|
||
RESPONSE_HEADERS.
|
||
</p>
|
||
<a name="RESPONSE_PROTOCOL" id="RESPONSE_PROTOCOL"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_PROTOCOL </span></h2>
|
||
<p>This variable holds the HTTP response protocol information.
|
||
</p><p><code>SecRule RESPONSE_PROTOCOL "^HTTP\/0\.9" "phase:3,t:none"</code>
|
||
</p>
|
||
<a name="RESPONSE_STATUS" id="RESPONSE_STATUS"></a><h2> <span
|
||
class="mw-headline"> RESPONSE_STATUS </span></h2>
|
||
<p>This variable holds the HTTP response status code:
|
||
</p><p><code>SecRule RESPONSE_STATUS "^[45]" "phase:3,t:none"</code>
|
||
</p><p>This variable may not work as expected in embedded mode, as
|
||
Apache sometimes handles certain requests differently, and without
|
||
invoking ModSecurity (all other modules).
|
||
</p>
|
||
<a name="RULE" id="RULE"></a><h2> <span class="mw-headline"> RULE </span></h2>
|
||
<p>This is a special collection that provides access to the id, rev,
|
||
severity, logdata, and msg fields of the rule that triggered the action.
|
||
It can be used to refer to only the same rule in which it resides.
|
||
</p><p><code>SecRule &REQUEST_HEADERS:Host "@eq 0"
|
||
"log,deny,setvar:tx.varname=%{RULE.id}"</code>
|
||
</p>
|
||
<a name="SCRIPT_BASENAME" id="SCRIPT_BASENAME"></a><h2> <span
|
||
class="mw-headline"> SCRIPT_BASENAME </span></h2>
|
||
<p>This variable holds just the local filename part of SCRIPT_FILENAME.
|
||
</p><p><code>SecRule SCRIPT_BASENAME "^login\.php$"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_FILENAME" id="SCRIPT_FILENAME"></a><h2> <span
|
||
class="mw-headline"> SCRIPT_FILENAME </span></h2>
|
||
<p>This variable holds the full internal path to the script that will be
|
||
used to serve the request.
|
||
</p><p><code>SecRule SCRIPT_FILENAME
|
||
"^/usr/local/apache/cgi-bin/login\.php$"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_GID" id="SCRIPT_GID"></a><h2> <span class="mw-headline">
|
||
SCRIPT_GID </span></h2>
|
||
<p>This variable holds the numerical identifier of the group owner of
|
||
the script.
|
||
</p><p><code>SecRule SCRIPT_GID "!^46$"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_GROUPNAME" id="SCRIPT_GROUPNAME"></a><h2> <span
|
||
class="mw-headline"> SCRIPT_GROUPNAME </span></h2>
|
||
<p>This variable holds the name of the group owner of the script.
|
||
</p><p><code>SecRule SCRIPT_GROUPNAME "!^apache$"</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_MODE" id="SCRIPT_MODE"></a><h2> <span
|
||
class="mw-headline"> SCRIPT_MODE </span></h2>
|
||
<p>This variable holds the script’s permissions mode data (e.g., 644).
|
||
</p>
|
||
<pre># Do not allow scripts that can be written to
|
||
SecRule SCRIPT_MODE "^(2|3|6|7)$"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_UID" id="SCRIPT_UID"></a><h2> <span class="mw-headline">
|
||
SCRIPT_UID </span></h2>
|
||
<p>This variable holds the numerical identifier of the owner of the
|
||
script.
|
||
</p>
|
||
<pre># Do not run any scripts that are owned
|
||
# by Apache (Apache's user id is 46)
|
||
SecRule SCRIPT_UID "!^46$"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SCRIPT_USERNAME" id="SCRIPT_USERNAME"></a><h2> <span
|
||
class="mw-headline"> SCRIPT_USERNAME </span></h2>
|
||
<p>This variable holds the username of the owner of the script.
|
||
</p>
|
||
<pre># Do not run any scripts owned by Apache SecRule
|
||
SCRIPT_USERNAME "^apache$"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Not available in proxy mode.
|
||
</dd></dl>
|
||
<a name="SERVER_ADDR" id="SERVER_ADDR"></a><h2> <span
|
||
class="mw-headline"> SERVER_ADDR </span></h2>
|
||
<p>This variable contains the IP address of the server.
|
||
</p><p><code>SecRule SERVER_ADDR "@ipMatch 192.168.1.100"</code>
|
||
</p>
|
||
<a name="SERVER_NAME" id="SERVER_NAME"></a><h2> <span
|
||
class="mw-headline"> SERVER_NAME </span></h2>
|
||
<p>This variable contains the transaction’s hostname or IP address,
|
||
taken from the request itself (which means that, in principle, it should
|
||
not be trusted).
|
||
</p><p><code>SecRule SERVER_NAME "hostname\.com$"</code>
|
||
</p>
|
||
<a name="SERVER_PORT" id="SERVER_PORT"></a><h2> <span
|
||
class="mw-headline"> SERVER_PORT </span></h2>
|
||
<p>This variable contains the local port that the web server (or reverse
|
||
proxy) is listening on.
|
||
</p><p><code>SecRule SERVER_PORT "^80$"</code>
|
||
</p>
|
||
<a name="SESSION" id="SESSION"></a><h2> <span class="mw-headline">
|
||
SESSION </span></h2>
|
||
<p>This variable is a collection that contains session information. It
|
||
becomes available only after setsid is executed.
|
||
</p><p>The following example shows how to initialize SESSION using
|
||
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:
|
||
</p>
|
||
<pre># Initialize session storage
|
||
SecRule REQUEST_COOKIES:PHPSESSID !^$ "phase:2,nolog,pass,setsid:%{REQUEST_COOKIES.PHPSESSID}"
|
||
|
||
# Increment session score on attack
|
||
SecRule REQUEST_URI "^/cgi-bin/finger$" "phase:2,t:none,t:lowercase,t:normalizePath,pass,setvar:SESSION.score=+10"
|
||
|
||
# Detect too many attacks in a session
|
||
SecRule SESSION:score "@gt 50" "phase:2,pass,setvar:SESSION.blocked=1"
|
||
|
||
# Enforce session block
|
||
SecRule SESSION:blocked "@eq 1" "phase:2,deny,status:403"
|
||
</pre>
|
||
<a name="SESSIONID" id="SESSIONID"></a><h2> <span class="mw-headline">
|
||
SESSIONID </span></h2>
|
||
<p>This variable contains the value set with setsid. See SESSION (above)
|
||
for a complete example.
|
||
</p>
|
||
<a name="STREAM_INPUT_BODY" id="STREAM_INPUT_BODY"></a><h2> <span
|
||
class="mw-headline"> STREAM_INPUT_BODY </span></h2>
|
||
<p>This variable give access to the raw request body content. This
|
||
variable is best used for two use-cases:
|
||
</p>
|
||
<ol><li>For fast pattern matching - using @pm/@pmf to prequalify large
|
||
text strings against any kind of content-type data. This is more
|
||
performant vs. using REQUEST_BODY/ARGS_POST/ARGS_POST_NAMES as it
|
||
happens before ModSecurity parsing in phase:2 variable population.
|
||
</li><li>For data substitution - using @rsub against this variable
|
||
allows you to manipulate live request body data. Example - to remove
|
||
offending payloads or to substitute benign data.
|
||
</li></ol>
|
||
<dl><dt> Note </dt><dd> You must enable the
|
||
SecStreamInBodyInspection directive
|
||
</dd></dl>
|
||
<a name="STREAM_OUTPUT_BODY" id="STREAM_OUTPUT_BODY"></a><h2> <span
|
||
class="mw-headline"> STREAM_OUTPUT_BODY </span></h2>
|
||
<p>This variable give access to the raw response body content. This
|
||
variable is best used for case:
|
||
</p>
|
||
<ol><li>For data substitution - using @rsub against this variable allows
|
||
you to manipulate live request body data. Example - to remove
|
||
offending payloads or to substitute benign data.
|
||
</li></ol>
|
||
<dl><dt> Note </dt><dd> You must enable the
|
||
SecStreamOutBodyInspection directive
|
||
</dd></dl>
|
||
<a name="TIME" id="TIME"></a><h2> <span class="mw-headline"> TIME </span></h2>
|
||
<p>This variable holds a formatted string representing the time
|
||
(hour:minute:second).
|
||
</p><p><code>SecRule TIME "^(([1](8|9))|([2](0|1|2|3))):\d{2}:\d{2}$"</code>
|
||
</p>
|
||
<a name="TIME_DAY" id="TIME_DAY"></a><h2> <span class="mw-headline">
|
||
TIME_DAY </span></h2>
|
||
<p>This variable holds the current date (1–31). The following rule
|
||
triggers on a transaction that’s happening anytime between the 10th and
|
||
20th in a month:
|
||
</p><p><code>SecRule TIME_DAY "^(([1](0|1|2|3|4|5|6|7|8|9))|20)$"</code>
|
||
</p>
|
||
<a name="TIME_EPOCH" id="TIME_EPOCH"></a><h2> <span class="mw-headline">
|
||
TIME_EPOCH </span></h2>
|
||
<p>This variable holds the time in seconds since 1970.
|
||
</p>
|
||
<a name="TIME_HOUR" id="TIME_HOUR"></a><h2> <span class="mw-headline">
|
||
TIME_HOUR </span></h2>
|
||
<p>This variable holds the current hour value (0–23). The following rule
|
||
triggers when a request is made “off hours”:
|
||
</p><p><code>SecRule TIME_HOUR "^(0|1|2|3|4|5|6|[1](8|9)|[2](0|1|2|3))$"</code>
|
||
</p>
|
||
<a name="TIME_MIN" id="TIME_MIN"></a><h2> <span class="mw-headline">
|
||
TIME_MIN </span></h2>
|
||
<p>This variable holds the current minute value (0–59). The following
|
||
rule triggers during the last half hour of every hour:
|
||
</p><p><code>SecRule TIME_MIN "^(3|4|5)"</code>
|
||
</p>
|
||
<a name="TIME_MON" id="TIME_MON"></a><h2> <span class="mw-headline">
|
||
TIME_MON </span></h2>
|
||
<p>This variable holds the current month value (0–11). The following
|
||
rule matches if the month is either November (value 10) or December
|
||
(value 11):
|
||
</p><p><code>SecRule TIME_MON "^1"</code>
|
||
</p>
|
||
<a name="TIME_SEC" id="TIME_SEC"></a><h2> <span class="mw-headline">
|
||
TIME_SEC </span></h2>
|
||
<p>This variable holds the current second value (0–59).
|
||
</p><p><code>SecRule TIME_SEC "@gt 30"</code>
|
||
</p>
|
||
<a name="TIME_WDAY" id="TIME_WDAY"></a><h2> <span class="mw-headline">
|
||
TIME_WDAY </span></h2>
|
||
<p>This variable holds the current weekday value (0–6). The following
|
||
rule triggers only on Satur- day and Sunday:
|
||
</p><p><code>SecRule TIME_WDAY "^(0|6)$"</code>
|
||
</p>
|
||
<a name="TIME_YEAR" id="TIME_YEAR"></a><h2> <span class="mw-headline">
|
||
TIME_YEAR </span></h2>
|
||
<p>This variable holds the current four-digit year value.
|
||
</p><p><code>SecRule TIME_YEAR "^2006$"</code>
|
||
</p>
|
||
<a name="TX" id="TX"></a><h2> <span class="mw-headline"> TX </span></h2>
|
||
<p>This is the transient transaction collection, which is used to store
|
||
pieces of data, create a transaction anomaly score, and so on. The
|
||
variables placed into this collection are available only until the
|
||
transaction is complete.
|
||
</p>
|
||
<pre># Increment transaction attack score on attack
|
||
SecRule ARGS attack "phase:2,nolog,pass,setvar:TX.score=+5"
|
||
|
||
# Block the transactions whose scores are too high
|
||
SecRule TX:SCORE "@gt 20" "phase:2,log,deny"
|
||
</pre>
|
||
<p>Some variable names in the TX collection are reserved and cannot be
|
||
used:
|
||
</p>
|
||
<ul><li>TX:0: the matching value when using the @rx or @pm operator with
|
||
the capture action
|
||
</li><li>TX:1-TX:9: the captured subexpression value when using the @rx
|
||
operator with capturing parens and the capture action
|
||
</li><li>TX:MSC_.*: ModSecurity processing flags
|
||
</li><li>MSC_PCRE_LIMITS_EXCEEDED: Set to nonzero if PCRE match limits
|
||
are exceeded. See SecPcreMatchLimit and SecPcreMatchLimitRecursion for
|
||
more information.
|
||
</li></ul>
|
||
<a name="UNIQUE_ID" id="UNIQUE_ID"></a><h2> <span class="mw-headline">
|
||
UNIQUE_ID </span></h2>
|
||
<p>This variable holds the data created by mod_unique_id <a
|
||
href="http://httpd.apache.org/docs/2.2/mod/mod_unique_id.html"
|
||
class="external autonumber"
|
||
title="http://httpd.apache.org/docs/2.2/mod/mod_unique_id.html"
|
||
rel="nofollow">[7]</a>. This module provides a magic token for each
|
||
request which is guaranteed to be unique across "all" requests under
|
||
very specific conditions. The unique identifier is even unique across
|
||
multiple machines in a properly configured cluster of machines. The
|
||
environment variable UNIQUE_ID is set to the identifier for each
|
||
request. The UNIQUE_ID environment variable is constructed by encoding
|
||
the 112-bit (32-bit IP address, 32 bit pid, 32 bit time stamp, 16 bit
|
||
counter) quadruple using the alphabet [A-Za-z0-9@-] in a manner similar
|
||
to MIME base64 encoding, producing 19 characters.
|
||
</p>
|
||
<a name="URLENCODED_ERROR" id="URLENCODED_ERROR"></a><h2> <span
|
||
class="mw-headline"> URLENCODED_ERROR </span></h2>
|
||
<p>This variable is created when an invalid URL encoding is encountered
|
||
during the parsing of a query string (on every request) or during the
|
||
parsing of an application/x-www-form-urlencoded request body (only on
|
||
the requests that use the URLENCODED request body processor).
|
||
</p>
|
||
<a name="USERID" id="USERID"></a><h2> <span class="mw-headline"> USERID </span></h2>
|
||
<p>This variable contains the value set with setuid.
|
||
</p>
|
||
<pre># Initialize user tracking
|
||
SecAction "nolog,pass,setuid:%{REMOTE_USER}"
|
||
|
||
# Is the current user the administrator?
|
||
SecRule USERID "admin"
|
||
</pre>
|
||
<a name="USERAGENT_IP" id="USERAGENT_IP"></a><h2> <span
|
||
class="mw-headline"> USERAGENT_IP </span></h2>
|
||
<p>This variable is created when running modsecurity with apache2.4 and
|
||
will contains the client ip address set by mod_remoteip in proxied
|
||
connections.
|
||
</p>
|
||
<a name="WEBAPPID" id="WEBAPPID"></a><h2> <span class="mw-headline">
|
||
WEBAPPID </span></h2>
|
||
<p>This variable contains the current application name, which is set in
|
||
configuration using SecWebAppId.
|
||
</p>
|
||
<a name="WEBSERVER_ERROR_LOG" id="WEBSERVER_ERROR_LOG"></a><h2> <span
|
||
class="mw-headline"> WEBSERVER_ERROR_LOG </span></h2>
|
||
<p>Contains zero or more error messages produced by the web server. This
|
||
variable is best accessed from phase 5 (logging).
|
||
</p><p><code>SecRule WEBSERVER_ERROR_LOG "File does not exist"
|
||
"phase:5,t:none,nolog,pass,setvar:TX.score=+5"</code>
|
||
</p>
|
||
<a name="XML" id="XML"></a><h2> <span class="mw-headline"> XML </span></h2>
|
||
<p>Special collection used to interact with the XML parser. It can be
|
||
used standalone as a target for the validateDTD and validateSchema
|
||
operator. Otherwise, it must contain a valid XPath expression, which
|
||
will then be evaluated against a previously parsed XML DOM tree.
|
||
</p>
|
||
<pre>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$" 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"
|
||
</pre>
|
||
<p>The first XPath expression does not use namespaces. It would match
|
||
against payload such as this one:
|
||
</p>
|
||
<pre><employees>
|
||
<employee>
|
||
<name>Fred Jones</name>
|
||
<address location="home">
|
||
<street>900 Aurora Ave.</street>
|
||
<city>Seattle</city>
|
||
<state>WA</state>
|
||
<zip>98115</zip>
|
||
</address>
|
||
<address location="work">
|
||
<street>2011 152nd Avenue NE</street>
|
||
<city>Redmond</city>
|
||
<state>WA</state>
|
||
<zip>98052</zip>
|
||
</address>
|
||
<phone location="work">(425)555-5665</phone>
|
||
<phone location="home">(206)555-5555</phone>
|
||
<phone location="mobile">(206)555-4321</phone>
|
||
</employee>
|
||
</employees>
|
||
</pre>
|
||
<p>The second XPath expression does use namespaces. It would match the
|
||
following payload:
|
||
</p>
|
||
<pre><xq:employees xmlns:xq="http://www.example.com/employees">
|
||
<employee>
|
||
<name>Fred Jones</name>
|
||
<address location="home">
|
||
<street>900 Aurora Ave.</street>
|
||
<city>Seattle</city>
|
||
<state>WA</state>
|
||
<zip>98115</zip>
|
||
</address>
|
||
<address location="work">
|
||
<street>2011 152nd Avenue NE</street>
|
||
<city>Redmond</city>
|
||
<state>WA</state>
|
||
<zip>98052</zip>
|
||
</address>
|
||
<phone location="work">(425)555-5665</phone>
|
||
<phone location="home">(206)555-5555</phone>
|
||
<phone location="mobile">(206)555-4321</phone>
|
||
</employee>
|
||
</xq:employees>
|
||
</pre>
|
||
<p>Note the different namespace used in the second example.
|
||
</p>
|
||
<a name="Transformation_functions" id="Transformation_functions"></a><h1>
|
||
<span class="mw-headline"> Transformation functions </span></h1>
|
||
<p>Transformation functions are used to alter input data before it is
|
||
used in matching (i.e., operator execution). The input data is never
|
||
modified, actually—whenever you request a transformation function to be
|
||
used, ModSecurity will create a copy of the data, transform it, and then
|
||
run the operator against the result.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> There are no default transformation
|
||
functions, as there were in the first generation of ModSecurity (1.x).
|
||
</dd></dl>
|
||
<p>In the following example, the request parameter values are converted
|
||
to lowercase before matching:
|
||
</p><p><code>SecRule ARGS "xp_cmdshell" "t:lowercase"</code>
|
||
</p><p>Multiple transformation actions can be used in the same rule,
|
||
forming a transformation pipeline. The transformations will be performed
|
||
in the order in which they appear in the rule.
|
||
</p><p>In most cases, the order in which transformations are performed
|
||
is very important. In the following example, a series of transformation
|
||
functions is performed to counter evasion. Performing the
|
||
transformations in any other order would allow a skillful attacker to
|
||
evade detection:
|
||
</p><p><code>SecRule ARGS
|
||
"(asfunction|javascript|vbscript|data|mocha|livescript):"
|
||
"t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace"</code>
|
||
</p>
|
||
<dl><dt> Warning </dt><dd> It is currently possible to use
|
||
SecDefaultAction to specify a default list of transformation functions,
|
||
which will be applied to all rules that follow the SecDefaultAction
|
||
directive. However, this practice is not recommended, because it means
|
||
that mistakes are very easy to make. It is recommended that you always
|
||
specify the transformation functions that are needed by a particular
|
||
rule, starting the list with t:none (which clears the possibly inherited
|
||
transformation functions).
|
||
</dd></dl>
|
||
<p>The remainder of this section documents the transformation functions
|
||
currently available in ModSecurity.
|
||
</p>
|
||
<a name="base64Decode" id="base64Decode"></a><h2> <span
|
||
class="mw-headline"> base64Decode </span></h2>
|
||
<p>Decodes a Base64-encoded string.
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:Authorization "^Basic ([a-zA-Z0-9]+=*)$" "phase:1,capture,chain,logdata:%{TX.1}"
|
||
SecRule TX:1 ^(\w+): t:base64Decode,capture,chain
|
||
SecRule TX:1 ^(admin|root|backup)$
|
||
</pre>
|
||
<a name="sqlHexDecode" id="sqlHexDecode"></a><h2> <span
|
||
class="mw-headline"> sqlHexDecode </span></h2>
|
||
<p>Decode sql hex data. Example (0x414243) will be decoded to (ABC).
|
||
Available as of 2.6.3
|
||
</p>
|
||
<a name="base64DecodeExt" id="base64DecodeExt"></a><h2> <span
|
||
class="mw-headline"> base64DecodeExt </span></h2>
|
||
<p>Decodes a Base64-encoded string. Unlike base64Decode, this version
|
||
uses a forgiving implementation, which ignores invalid characters.
|
||
Available as of 2.5.13.
|
||
</p><p>See blog post on Base64Decoding evasion issues on PHP sites - <a
|
||
href="http://blog.spiderlabs.com/2010/04/impedance-mismatch-and-base64.html"
|
||
class="external free"
|
||
title="http://blog.spiderlabs.com/2010/04/impedance-mismatch-and-base64.html"
|
||
rel="nofollow">http://blog.spiderlabs.com/2010/04/impedance-mismatch-and-base64.html</a>
|
||
</p>
|
||
<a name="base64Encode" id="base64Encode"></a><h2> <span
|
||
class="mw-headline"> base64Encode </span></h2>
|
||
<p>Encodes input string using Base64 encoding.
|
||
</p>
|
||
<a name="cmdLine" id="cmdLine"></a><h2> <span class="mw-headline">
|
||
cmdLine </span></h2>
|
||
<dl><dt> Note </dt><dd> This is a community contribution developed
|
||
by Marc Stern <a href="http://www.linkedin.com/in/marcstern"
|
||
class="external autonumber" title="http://www.linkedin.com/in/marcstern"
|
||
rel="nofollow">[8]</a>
|
||
</dd></dl>
|
||
<p>In Windows and Unix, commands may be escaped by different means, such
|
||
as:
|
||
</p>
|
||
<ul><li>c^ommand /c ...
|
||
</li><li>"command" /c ...
|
||
</li><li>command,/c ...
|
||
</li><li>backslash in the middle of a Unix command
|
||
</li></ul>
|
||
<p>The cmdLine transformation function avoids this problem by
|
||
manipulating the variable contend in the following ways:
|
||
</p>
|
||
<ul><li>deleting all backslashes [\]
|
||
</li><li>deleting all double quotes ["]
|
||
</li><li>deleting all sigle quotes [']
|
||
</li><li>deleting all carets [^]
|
||
</li><li>deleting spaces before a slash [/]
|
||
</li><li>deleting spaces before an open parentesis [(]
|
||
</li><li>replacing all commas [,] and semicolon [;] into a space
|
||
</li><li>replacing all multiple spaces (including tab, newline, etc.)
|
||
into one space
|
||
</li><li>transform all characters to lowercase
|
||
</li></ul>
|
||
<p><b>Example Usage:</b>
|
||
</p>
|
||
<pre>SecRule ARGS "(?:command(?:.com)?|cmd(?:.exe)?)(?:/.*)?/[ck]" "phase:2,t:none, t:cmdLine"
|
||
</pre>
|
||
<a name="compressWhitespace" id="compressWhitespace"></a><h2> <span
|
||
class="mw-headline"> compressWhitespace </span></h2>
|
||
<p>Converts any of the whitespace characters (0x20, \f, \t, \n, \r, \v,
|
||
0xa0) to spaces (ASCII 0x20), compressing multiple consecutive space
|
||
characters into one.
|
||
</p>
|
||
<a name="cssDecode" id="cssDecode"></a><h2> <span class="mw-headline">
|
||
cssDecode </span></h2>
|
||
<p>Decodes characters encoded using the CSS 2.x escape rules <a
|
||
href="http://www.w3.org/TR/CSS2/" class="external text"
|
||
title="http://www.w3.org/TR/CSS2/" rel="nofollow">syndata.html#characters</a>.
|
||
This function uses only up to two bytes in the decoding process,
|
||
meaning that it is useful to uncover ASCII characters encoded using CSS
|
||
encoding (that wouldn’t normally be encoded), or to counter evasion,
|
||
which is a combination of a backslash and non-hexadecimal characters
|
||
(e.g., ja\vascript is equivalent to javascript).
|
||
</p>
|
||
<a name="escapeSeqDecode" id="escapeSeqDecode"></a><h2> <span
|
||
class="mw-headline"> escapeSeqDecode </span></h2>
|
||
<p>Decodes ANSI C escape sequences: \a, \b, \f, \n, \r, \t, \v, \\, \?,
|
||
\', \", \xHH (hexadecimal), \0OOO (octal). Invalid encodings are left in
|
||
the output.
|
||
</p>
|
||
<a name="hexDecode" id="hexDecode"></a><h2> <span class="mw-headline">
|
||
hexDecode </span></h2>
|
||
<p>Decodes a string that has been encoded using the same algorithm as
|
||
the one used in hexEncode (see following entry).
|
||
</p>
|
||
<a name="hexEncode" id="hexEncode"></a><h2> <span class="mw-headline">
|
||
hexEncode </span></h2>
|
||
<p>Encodes string (possibly containing binary characters) by replacing
|
||
each input byte with two hexadecimal characters. For example, xyz is
|
||
encoded as 78797a.
|
||
</p>
|
||
<a name="htmlEntityDecode" id="htmlEntityDecode"></a><h2> <span
|
||
class="mw-headline"> htmlEntityDecode </span></h2>
|
||
<p>Decodes the characters encoded as HTML entities. The following
|
||
variants are supported:
|
||
</p>
|
||
<ul><li>&#xHH and &#xHH; (where H is any hexadecimal number)
|
||
</li><li>&#DDD and &#DDD; (where D is any decimal number)
|
||
</li><li>&quotand"
|
||
</li><li>&nbspand
|
||
</li><li>&ltand<
|
||
</li><li>&gtand>
|
||
</li></ul>
|
||
<p>This function always converts one HTML entity into one byte, possibly
|
||
resulting in a loss of information (if the entity refers to a character
|
||
that cannot be represented with the single byte). It is thus useful to
|
||
uncover bytes that would otherwise not need to be encoded, but it cannot
|
||
do anything meaningful with the characters from the range above 0xff.
|
||
</p>
|
||
<a name="jsDecode" id="jsDecode"></a><h2> <span class="mw-headline">
|
||
jsDecode </span></h2>
|
||
<p>Decodes JavaScript escape sequences. If a \uHHHH code is in the range
|
||
of FF01-FF5E (the full width ASCII codes), then the higher byte is used
|
||
to detect and adjust the lower byte. Otherwise, only the lower byte
|
||
will be used and the higher byte zeroed (leading to possible loss of
|
||
information).
|
||
</p>
|
||
<a name="length" id="length"></a><h2> <span class="mw-headline"> length </span></h2>
|
||
<p>Looks up the length of the input string in bytes, placing it (as
|
||
string) in output. For example, if it gets ABCDE on input, this
|
||
transformation function will return 5 on output.
|
||
</p>
|
||
<a name="lowercase" id="lowercase"></a><h2> <span class="mw-headline">
|
||
lowercase </span></h2>
|
||
<p>Converts all characters to lowercase using the current C locale.
|
||
</p>
|
||
<a name="md5" id="md5"></a><h2> <span class="mw-headline"> md5 </span></h2>
|
||
<p>Calculates an MD5 hash from the data in input. The computed hash is
|
||
in a raw binary form and may need encoded into text to be printed (or
|
||
logged). Hash functions are commonly used in combination with hexEncode
|
||
(for example: t:md5,t:hexEncode).
|
||
</p>
|
||
<a name="none" id="none"></a><h2> <span class="mw-headline"> none </span></h2>
|
||
<p>Not an actual transformation function, but an instruction to
|
||
ModSecurity to remove all transformation functions associated with the
|
||
current rule.
|
||
</p>
|
||
<a name="normalisePath" id="normalisePath"></a><h2> <span
|
||
class="mw-headline"> normalisePath </span></h2>
|
||
<p>Removes multiple slashes, directory self-references, and directory
|
||
back-references (except when at the beginning of the input) from input
|
||
string.
|
||
</p>
|
||
<a name="normalisePathWin" id="normalisePathWin"></a><h2> <span
|
||
class="mw-headline"> normalisePathWin </span></h2>
|
||
<p>Same as normalisePath, but first converts backslash characters to
|
||
forward slashes.
|
||
</p>
|
||
<a name="parityEven7bit" id="parityEven7bit"></a><h2> <span
|
||
class="mw-headline"> parityEven7bit </span></h2>
|
||
<p>Calculates even parity of 7-bit data replacing the 8th bit of each
|
||
target byte with the calculated parity bit.
|
||
</p>
|
||
<a name="parityOdd7bit" id="parityOdd7bit"></a><h2> <span
|
||
class="mw-headline"> parityOdd7bit </span></h2>
|
||
<p>Calculates odd parity of 7-bit data replacing the 8th bit of each
|
||
target byte with the calculated parity bit.
|
||
</p>
|
||
<a name="parityZero7bit" id="parityZero7bit"></a><h2> <span
|
||
class="mw-headline"> parityZero7bit </span></h2>
|
||
<p>Calculates zero parity of 7-bit data replacing the 8th bit of each
|
||
target byte with a zero-parity bit, which allows inspection of even/odd
|
||
parity 7-bit data as ASCII7 data.
|
||
</p>
|
||
<a name="removeNulls" id="removeNulls"></a><h2> <span
|
||
class="mw-headline"> removeNulls </span></h2>
|
||
<p>Removes all NUL bytes from input.
|
||
</p>
|
||
<a name="removeWhitespace" id="removeWhitespace"></a><h2> <span
|
||
class="mw-headline"> removeWhitespace </span></h2>
|
||
<p>Removes all whitespace characters from input.
|
||
</p>
|
||
<a name="replaceComments" id="replaceComments"></a><h2> <span
|
||
class="mw-headline"> replaceComments </span></h2>
|
||
<p>Replaces each occurrence of a C-style comment (/* ... */) with a
|
||
single space (multiple consecutive occurrences of which will not be
|
||
compressed). Unterminated comments will also be replaced with a space
|
||
(ASCII 0x20). However, a standalone termination of a comment (*/) will
|
||
not be acted upon.
|
||
</p>
|
||
<a name="removeCommentsChar" id="removeCommentsChar"></a><h2> <span
|
||
class="mw-headline"> removeCommentsChar </span></h2>
|
||
<p>Removes common comments chars (/*, */, --, #).
|
||
</p>
|
||
<a name="removeComments" id="removeComments"></a><h2> <span
|
||
class="mw-headline"> removeComments </span></h2>
|
||
<p>Removes each occurrence of comment (/* ... */, --, #). Multiple
|
||
consecutive occurrences of which will not be compressed.
|
||
</p>
|
||
<a name="replaceNulls" id="replaceNulls"></a><h2> <span
|
||
class="mw-headline"> replaceNulls </span></h2>
|
||
<p>Replaces NUL bytes in input with space characters (ASCII 0x20).
|
||
</p>
|
||
<a name="urlDecode" id="urlDecode"></a><h2> <span class="mw-headline">
|
||
urlDecode </span></h2>
|
||
<p>Decodes a URL-encoded input string. Invalid encodings (i.e., the ones
|
||
that use non-hexadecimal characters, or the ones that are at the end of
|
||
string and have one or two bytes missing) are not converted, but no
|
||
error is raised. To detect invalid encodings, use the
|
||
@validateUrlEncoding operator on the input data first. The
|
||
transformation function should not be used against variables that have
|
||
already been URL-decoded (such as request parameters) unless it is your
|
||
intention to perform URL decoding twice!
|
||
</p>
|
||
<a name="urlDecodeUni" id="urlDecodeUni"></a><h2> <span
|
||
class="mw-headline"> urlDecodeUni </span></h2>
|
||
<p>Like urlDecode, but with support for the Microsoft-specific %u
|
||
encoding. If the code is in the range of FF01-FF5E (the full-width ASCII
|
||
codes), then the higher byte is used to detect and adjust the lower
|
||
byte. Otherwise, only the lower byte will be used and the higher byte
|
||
zeroed.
|
||
</p>
|
||
<a name="urlEncode" id="urlEncode"></a><h2> <span class="mw-headline">
|
||
urlEncode </span></h2>
|
||
<p>Encodes input string using URL encoding.
|
||
</p>
|
||
<a name="sha1" id="sha1"></a><h2> <span class="mw-headline"> sha1 </span></h2>
|
||
<p>Calculates a SHA1 hash from the input string. The computed hash is in
|
||
a raw binary form and may need encoded into text to be printed (or
|
||
logged). Hash functions are commonly used in combination with hexEncode
|
||
(for example, t:sha1,t:hexEncode).
|
||
</p>
|
||
<a name="trimLeft" id="trimLeft"></a><h2> <span class="mw-headline">
|
||
trimLeft </span></h2>
|
||
<p>Removes whitespace from the left side of the input string.
|
||
</p>
|
||
<a name="trimRight" id="trimRight"></a><h2> <span class="mw-headline">
|
||
trimRight </span></h2>
|
||
<p>Removes whitespace from the right side of the input string.
|
||
</p>
|
||
<a name="trim" id="trim"></a><h2> <span class="mw-headline"> trim </span></h2>
|
||
<p>Removes whitespace from both the left and right sides of the input
|
||
string.
|
||
</p>
|
||
<a name="Actions" id="Actions"></a><h1> <span class="mw-headline">
|
||
Actions </span></h1>
|
||
<p>Each action belongs to one of five groups:
|
||
</p>
|
||
<ul><li><b>Disruptive actions</b> - 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).
|
||
</li></ul>
|
||
<dl><dt> Note </dt><dd> <b>Disruptive actions will NOT be executed
|
||
if the SecRuleEngine is set to DetectionOnly</b>. If you are creating
|
||
exception/whitelisting rules that use the allow action, you should also
|
||
add the ctl:ruleEngine=On action to execute the action.
|
||
</dd></dl>
|
||
<ul><li> <b>Non-disruptive action</b>s - 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.
|
||
</li><li> <b>Flow actions</b> - These actions affect the rule flow (for
|
||
example skip or skipAfter).
|
||
</li><li> <b>Meta-data actions</b> - Meta-data actions are used to
|
||
provide more information about rules. Examples include id, rev, severity
|
||
and msg.
|
||
</li><li> <b>Data actions</b> - 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).
|
||
</li></ul>
|
||
<a name="accuracy" id="accuracy"></a><h2> <span class="mw-headline">
|
||
accuracy </span></h2>
|
||
<p><b>Description:</b> Specifies the relative accuracy level of the rule
|
||
related to false positives/negatives. The value is a string based on a
|
||
numeric scale (1-9 where 9 is very strong and 1 has many false
|
||
positives).
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bgetparentfolder\b" \
|
||
"phase:2,ver:'CRS/2.2.4,accuracy:'9',maturity:'9',capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,ctl:auditLogParts=+E,block,msg:'Cross-site Scripting (XSS) Attack',id:'958016',tag:'WEB_ATTACK/XSS',tag:'WASCTC/WASC-8',tag:'WASCTC/WASC-22',tag:'OWASP_TOP_10/A2',tag:'OWASP_AppSensor/IE1',tag:'PCI/6.5.1',logdata:'% \
|
||
{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"
|
||
</pre>
|
||
<a name="allow" id="allow"></a><h2> <span class="mw-headline"> allow </span></h2>
|
||
<p><b>Description:</b> Stops rule processing on a successful match and
|
||
allows the transaction to proceed.
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p>Example:
|
||
</p>
|
||
<pre># Allow unrestricted access from 192.168.1.100
|
||
SecRule REMOTE_ADDR "^192\.168\.1\.100$" phase:1,nolog,allow
|
||
</pre>
|
||
<p><br>
|
||
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:
|
||
</p>
|
||
<ol><li>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.)
|
||
</li><li>If used with parameter "phase", allow will cause the engine to
|
||
stop processing the current phase. Other phases will continue as normal.
|
||
</li><li>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.
|
||
</li></ol>
|
||
<p>Examples:
|
||
</p>
|
||
<pre># Do not process request but process response.
|
||
SecAction phase:1,allow:request
|
||
|
||
# Do not process transaction (request and response).
|
||
SecAction phase:1,allow
|
||
</pre>
|
||
<p>If you want to allow a response through, put a rule in phase
|
||
RESPONSE_HEADERS and simply use allow on its own:
|
||
</p>
|
||
<pre># Allow response through.
|
||
SecAction phase:3,allow
|
||
</pre>
|
||
<a name="append" id="append"></a><h2> <span class="mw-headline"> append </span></h2>
|
||
<p><b>Description</b>: Appends text given as parameter to the end of
|
||
response body. Content injection must be en- abled (using the
|
||
SecContentInjection directive). No content type checks are made, which
|
||
means that before using any of the content injection actions, you must
|
||
check whether the content type of the response is adequate for
|
||
injection.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Processing Phases:</b> 3 and 4.
|
||
</p><p>Example:
|
||
</p>
|
||
<pre>SecRule RESPONSE_CONTENT_TYPE "^text/html" "nolog,pass,append:'<hr>Footer'"</pre>
|
||
<dl><dt> Warning </dt><dd> Although macro expansion is allowed in
|
||
the additional content, you are strongly cau- tioned against inserting
|
||
user-defined data fields into output. Doing so would create a cross-site
|
||
scripting vulnerability.
|
||
</dd></dl>
|
||
<a name="auditlog" id="auditlog"></a><h2> <span class="mw-headline">
|
||
auditlog </span></h2>
|
||
<p><b>Description:</b> Marks the transaction for logging in the audit
|
||
log.
|
||
</p><p><b>Action Group</b>: Non-disruptive
|
||
</p><p>Example:
|
||
</p><p><code>SecRule REMOTE_ADDR "^192\.168\.1\.100$"
|
||
auditlog,phase:1,allow</code>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> The auditlog action is now explicit if log
|
||
is already specified.
|
||
</dd></dl>
|
||
<a name="block" id="block"></a><h2> <span class="mw-headline"> block </span></h2>
|
||
<p><b>Description:</b> Performs the disruptive action defined by the
|
||
previous SecDefaultAction.
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p>This action is essentially a placeholder that is intended to be
|
||
used by rule writers to request a blocking action, but without
|
||
specifying how the blocking is to be done. The idea is that such
|
||
decisions are best left to rule users, as well as to allow users, to
|
||
override blocking if they so desire.
|
||
In future versions of ModSecurity, more control and functionality will
|
||
be added to define "how" to block.
|
||
</p><p>Examples:
|
||
</p>
|
||
<pre># Specify how blocking is to be done
|
||
SecDefaultAction phase:2,deny,status:403,log,auditlog
|
||
|
||
# Detect attacks where we want to block
|
||
SecRule ARGS attack1 phase:2,block
|
||
|
||
# Detect attacks where we want only to warn
|
||
SecRule ARGS attack2 phase:2,pass
|
||
</pre>
|
||
<p>It is possible to use the SecRuleUpdateActionById directive to
|
||
override how a rule handles blocking. This is useful in three cases:
|
||
</p>
|
||
<ol><li>If a rule has blocking hard-coded, and you want it to use the
|
||
policy you determine
|
||
</li><li>If a rule was written to block, but you want it to only warn
|
||
</li><li>If a rule was written to only warn, but you want it to block
|
||
</li></ol>
|
||
<p>The following example demonstrates the first case, in which the
|
||
hard-coded block is removed in favor of the user-controllable block:
|
||
</p>
|
||
<pre># Specify how blocking is to be done
|
||
SecDefaultAction phase:2,deny,status:403,log,auditlog
|
||
|
||
# Detect attacks and block
|
||
SecRule ARGS attack1 phase:2,id:1,deny
|
||
|
||
# Change how rule ID 1 blocks
|
||
SecRuleUpdateActionById 1 block
|
||
</pre>
|
||
<a name="capture" id="capture"></a><h2> <span class="mw-headline">
|
||
capture </span></h2>
|
||
<p><b>Description:</b> When used together with the regular expression
|
||
operator (@rx), the capture action will create copies of the regular
|
||
expression captures and place them into the transaction variable
|
||
collection.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p>Example:
|
||
</p>
|
||
<pre>SecRule REQUEST_BODY "^username=(\w{25,})" phase:2,capture,t:none,chain
|
||
SecRule TX:1 "(?:(?:a(dmin|nonymous)))"
|
||
</pre>
|
||
<p>Up to 10 captures will be copied on a successful pattern match, each
|
||
with a name consisting of a digit from 0 to 9. The TX.0 variable always
|
||
contains the entire area that the regular expression matched. All the
|
||
other variables contain the captured values, in the order in which the
|
||
capturing parentheses appear in the regular expression.
|
||
</p>
|
||
<a name="chain" id="chain"></a><h2> <span class="mw-headline"> chain </span></h2>
|
||
<p><b>Description:</b> Chains the current rule with the rule that
|
||
immediately follows it, creating a rule chain. Chained rules allow for
|
||
more complex processing logic.
|
||
</p><p><b>Action Group:</b> Flow
|
||
</p><p>Example:
|
||
</p>
|
||
<pre># Refuse to accept POST requests that do not contain Content-Length header.
|
||
# (Do note that this rule should be preceded by a rule
|
||
# that verifies only valid request methods are used.)
|
||
SecRule REQUEST_METHOD "^POST$" phase:1,chain,t:none
|
||
SecRule &REQUEST_HEADERS:Content-Length "@eq 0" t:none
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Rule chains allow you to simulate logical
|
||
AND. The disruptive actions specified in the first portion of the
|
||
chained rule will be triggered only if all of the variable checks return
|
||
positive hits. If any one aspect of a chained rule comes back negative,
|
||
then the entire rule chain will fail to match. Also note that
|
||
disruptive actions, execution phases, metadata actions (id, rev, msg),
|
||
skip, and skipAfter actions can be specified only by the chain starter
|
||
rule.
|
||
</dd></dl>
|
||
<p>The following directives can be used in rule chains:
|
||
</p>
|
||
<ul><li>SecAction
|
||
</li><li>SecRule
|
||
</li><li>SecRuleScript
|
||
</li></ul>
|
||
<p>Special rules control the usage of actions in chained rules:
|
||
</p>
|
||
<ul><li>Any actions that affect the rule flow (i.e., the disruptive
|
||
actions, skip and skipAfter) can be used only in the chain starter. They
|
||
will be executed only if the entire chain matches.
|
||
</li><li>Non-disruptive rules can be used in any rule; they will be
|
||
executed if the rule that contains them matches and not only when the
|
||
entire chain matches.
|
||
</li><li>The metadata actions (e.g., id, rev, msg) can be used only in
|
||
the chain starter.
|
||
</li></ul>
|
||
<a name="ctl" id="ctl"></a><h2> <span class="mw-headline"> ctl </span></h2>
|
||
<p><b>Description</b>: Changes ModSecurity configuration on transient,
|
||
per-transaction basis. Any changes made using this action will affect
|
||
only the transaction in which the action is executed. The default
|
||
configuration, as well as the other transactions running in parallel,
|
||
will be unaffected.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Parse requests with Content-Type "text/xml" as XML
|
||
SecRule REQUEST_CONTENT_TYPE ^text/xml "nolog,pass,ctl:requestBodyProcessor=XML"
|
||
</pre>
|
||
<p>The following configuration options are supported:
|
||
</p>
|
||
<ol><li><b>auditEngine</b>
|
||
</li><li><b>auditLogParts</b>
|
||
</li><li><b>debugLogLevel</b>
|
||
</li><li><b>forceRequestBodyVariable</b>
|
||
</li><li><b>requestBodyAccess</b>
|
||
</li><li><b>requestBodyLimit</b>
|
||
</li><li><b>requestBodyProcessor</b>
|
||
</li><li><b>responseBodyAccess</b>
|
||
</li><li><b>responseBodyLimit</b>
|
||
</li><li><b>ruleEngine</b>
|
||
</li><li><b>ruleRemoveById</b> - since this action us triggered at run
|
||
time, it should be specified <b>before</b> the rule in which it is
|
||
disabling.
|
||
</li><li><b>ruleUpdateTargetById</b>
|
||
</li><li><b>ruleUpdateTargetByMsg</b>
|
||
</li><li><b>ruleUpdateTargetByTag</b>
|
||
</li><li><b>ruleRemoveByMsg</b>
|
||
</li><li><b>encryptionEngine</b>
|
||
</li><li><b>encryptionEnforcement</b>
|
||
</li></ol>
|
||
<p>With the exception of the requestBodyProcessor and
|
||
forceRequestBodyVariable settings, each configuration option corresponds
|
||
to one configuration directive and the usage is identical.
|
||
</p><p>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 body, 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 is processed as XML, you will
|
||
be able to use the XML-related features to inspect it.
|
||
</p><p>Request body processors will not interrupt a transaction if an
|
||
error occurs during parsing. Instead, they will set the 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.
|
||
</p>
|
||
<a name="deny" id="deny"></a><h2> <span class="mw-headline"> deny </span></h2>
|
||
<p><b>Description:</b> Stops rule processing and intercepts transaction.
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p>Example:
|
||
<code>SecRule REQUEST_HEADERS:User-Agent "nikto" "log,deny,msg:'Nikto
|
||
Scanners Identified'"</code>
|
||
</p>
|
||
<a name="deprecatevar" id="deprecatevar"></a><h2> <span
|
||
class="mw-headline"> deprecatevar </span></h2>
|
||
<p><b>Description</b>: Decrements numerical value over time, which makes
|
||
sense only applied to the variables stored in persistent storage.
|
||
</p><p><b>Action Group:</b> Non-Disruptive
|
||
</p><p>Example: The following example will decrement the counter by 60
|
||
every 300 seconds.
|
||
</p>
|
||
<pre>SecAction phase:5,nolog,pass,deprecatevar:SESSION.score=60/300
|
||
</pre>
|
||
<p>Counter values are always positive, meaning that the value will never
|
||
go below zero. Unlike expirevar, the deprecate action must be executed
|
||
on every request.
|
||
</p>
|
||
<a name="drop" id="drop"></a><h2> <span class="mw-headline"> drop </span></h2>
|
||
<p><b>Description:</b> Initiates an immediate close of the TCP
|
||
connection by sending a FIN packet.
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p><b>Example:</b> 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.
|
||
</p>
|
||
<pre>SecAction phase:1,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'"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> This action is currently not available on
|
||
Windows based builds.
|
||
</dd></dl>
|
||
<p>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"
|
||
</p>
|
||
<a name="exec" id="exec"></a><h2> <span class="mw-headline"> exec </span></h2>
|
||
<p><b>Description:</b> 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.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Run external program on rule match
|
||
SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,t:none,t:lowercase,t:normalizePath,block,\ exec:/usr/local/apache/bin/test.sh"
|
||
|
||
# Run Lua script on rule match
|
||
SecRule ARGS:p attack "phase:2,block,exec:/usr/local/apache/conf/exec.lua"
|
||
</pre>
|
||
<p>The exec action is executed independently from any disruptive actions
|
||
specified. 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 a multithreaded deployment. The script you execute must
|
||
write something (anything) to stdout; if it doesn’t, ModSecurity will
|
||
assume that the script failed, and will record the failure.
|
||
</p>
|
||
<a name="expirevar" id="expirevar"></a><h2> <span class="mw-headline">
|
||
expirevar </span></h2>
|
||
<p><b>Description:</b> Configures a collection variable to expire after
|
||
the given time period (in seconds).
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_COOKIES:JSESSIONID "!^$" "nolog,phase:1,pass,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"
|
||
</pre>
|
||
<p>You should use the 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 will be reset.
|
||
</p>
|
||
<a name="id" id="id"></a><h2> <span class="mw-headline"> id </span></h2>
|
||
<p><b>Description</b>: Assigns a unique ID to the rule or chain in which
|
||
it appears. Starting with ModSecurity 2.7 this action is mandatory and
|
||
must be numeric.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule &REQUEST_HEADERS:Host "@eq 0" "log,id:60008,severity:2,msg:'Request Missing a Host Header'"
|
||
</pre>
|
||
<p>These are the reserved ranges:
|
||
</p>
|
||
<ul><li>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
|
||
</li><li>100,000–199,999: reserved for internal use of the engine, to
|
||
assign to rules that do not have explicit IDs
|
||
</li><li>200,000–299,999: reserved for rules published at
|
||
modsecurity.org
|
||
</li><li>300,000–399,999: reserved for rules published at gotroot.com
|
||
</li><li>400,000–419,999: unused (available for reservation)
|
||
</li><li>420,000–429,999: reserved for ScallyWhack <a
|
||
href="http://projects.otaku42.de/wiki/Scally-Whack" class="external
|
||
autonumber" title="http://projects.otaku42.de/wiki/Scally-Whack"
|
||
rel="nofollow">[9]</a>
|
||
</li><li>430,000–439,999: reserved for rules published by Flameeyes <a
|
||
href="http://www.flameeyes.eu/projects/modsec" class="external
|
||
autonumber" title="http://www.flameeyes.eu/projects/modsec"
|
||
rel="nofollow">[10]</a>
|
||
</li><li>440.000-599,999: unused (available for reservation)
|
||
</li><li>600,000-699,999: reserved for use by Akamai <a
|
||
href="http://www.akamai.com/html/solutions/waf.html" class="external
|
||
autonumber" title="http://www.akamai.com/html/solutions/waf.html"
|
||
rel="nofollow">[11]</a>
|
||
</li><li>700,000–799,999: reserved for Ivan Ristic
|
||
</li><li>900,000–999,999: reserved for the OWASP ModSecurity Core Rule
|
||
Set <a
|
||
href="http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project"
|
||
class="external autonumber"
|
||
title="http://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project"
|
||
rel="nofollow">[12]</a> project
|
||
</li><li>1,000,000-1,999,999: unused (available for reservation)
|
||
</li><li>2,000,000-2,999,999: reserved for rules from Trustwave's
|
||
SpiderLabs Research team
|
||
</li><li>3,000,000 and above: unused (available for reservation)
|
||
</li></ul>
|
||
<a name="initcol" id="initcol"></a><h2> <span class="mw-headline">
|
||
initcol </span></h2>
|
||
<p><b>Description:</b> Initializes a named persistent collection, either
|
||
by loading data from storage or by creating a new collection in memory.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b> The following example initiates IP address
|
||
tracking, which is best done in phase 1:
|
||
</p>
|
||
<pre>SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR}
|
||
</pre>
|
||
<p>Collections are loaded into memory on-demand, when the initcol action
|
||
is executed. A collection will be persisted only if a change was made
|
||
to it in the course of transaction processing.
|
||
</p><p>See the "Persistant Storage" section for further details.
|
||
</p>
|
||
<a name="log" id="log"></a><h2> <span class="mw-headline"> log </span></h2>
|
||
<p><b>Description:</b> Indicates that a successful match of the rule
|
||
needs to be logged.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecAction phase:1,pass,initcol:ip=%{REMOTE_ADDR},log
|
||
</pre>
|
||
<p>This action will log matches to the Apache error log file and the
|
||
ModSecurity audit log.
|
||
</p>
|
||
<a name="logdata" id="logdata"></a><h2> <span class="mw-headline">
|
||
logdata </span></h2>
|
||
<p><b>Description:</b> Logs a data fragment as part of the alert
|
||
message.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule ARGS:p "@rx <script>" "phase:2,log,pass,logdata:%{MATCHED_VAR}"
|
||
</pre>
|
||
<p>The logdata information appears in the error and/or audit log files.
|
||
Macro expansion is performed, so you may use variable names such
|
||
as %{TX.0} or %{MATCHED_VAR}. The information is properly
|
||
escaped for use with logging of binary data.
|
||
</p>
|
||
<a name="maturity" id="maturity"></a><h2> <span class="mw-headline">
|
||
maturity </span></h2>
|
||
<p><b>Description:</b> Specifies the relative maturity level of the rule
|
||
related to the length of time a rule has been public and the amount of
|
||
testing it has received. The value is a string based on a numeric scale
|
||
(1-9 where 9 is extensively tested and 1 is a brand new experimental
|
||
rule).
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bgetparentfolder\b" \
|
||
"phase:2,ver:'CRS/2.2.4,accuracy:'9',maturity:'9',capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,ctl:auditLogParts=+E,block,msg:'Cross-site Scripting (XSS) Attack',id:'958016',tag:'WEB_ATTACK/XSS',tag:'WASCTC/WASC-8',tag:'WASCTC/WASC-22',tag:'OWASP_TOP_10/A2',tag:'OWASP_AppSensor/IE1',tag:'PCI/6.5.1',logdata:'% \
|
||
{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"
|
||
</pre>
|
||
<a name="msg" id="msg"></a><h2> <span class="mw-headline"> msg </span></h2>
|
||
<p><b>Description:</b> Assigns a custom message to the rule or chain in
|
||
which it appears. The message will be logged along with every alert.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule &REQUEST_HEADERS:Host "@eq 0" "log,id:60008,severity:2,msg:'Request Missing a Host Header'"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The msg information appears in the error
|
||
and/or audit log files and is not sent back to the client in response
|
||
headers.
|
||
</dd></dl>
|
||
<a name="multiMatch" id="multiMatch"></a><h2> <span class="mw-headline">
|
||
multiMatch </span></h2>
|
||
<p><b>Description:</b> If enabled, ModSecurity will perform multiple
|
||
operator invocations for every target, before and after every
|
||
anti-evasion transformation is performed.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule ARGS "attack" "phase1,log,deny,t:removeNulls,t:lowercase,multiMatch"
|
||
</pre>
|
||
<p>Normally, variables are inspected only once per rule, and only after
|
||
all transformation functions have been completed. With multiMatch,
|
||
variables are checked against the operator before and after every
|
||
transformation function that changes the input.
|
||
</p>
|
||
<a name="noauditlog" id="noauditlog"></a><h2> <span class="mw-headline">
|
||
noauditlog </span></h2>
|
||
<p><b>Description:</b> Indicates that a successful match of the rule
|
||
should not be used as criteria to determine whether the transaction
|
||
should be logged to the audit log.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" allow,noauditlog
|
||
</pre>
|
||
<p>If the SecAuditEngine is set to On, all of the transactions will be
|
||
logged. If it is set to RelevantOnly, then you can control the logging
|
||
with the noauditlog action.
|
||
</p><p>The noauditlog action affects only the current rule. If you
|
||
prevent audit logging in one rule only, a match in another rule will
|
||
still cause audit logging to take place. If you want to prevent audit
|
||
logging from taking place, regardless of whether any rule matches, use
|
||
ctl:auditEngine=Off.
|
||
</p>
|
||
<a name="nolog" id="nolog"></a><h2> <span class="mw-headline"> nolog </span></h2>
|
||
<p><b>Description:</b> Prevents rule matches from appearing in both the
|
||
error and audit logs.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" allow,nolog
|
||
</pre>
|
||
<p>Although nolog implies noauditlog, you can override the former by
|
||
using nolog,auditlog.
|
||
</p>
|
||
<a name="pass" id="pass"></a><h2> <span class="mw-headline"> pass </span></h2>
|
||
<p><b>Description:</b> Continues processing with the next rule in spite
|
||
of a successful match.
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" "log,pass"
|
||
</pre>
|
||
<p>When using pass with a SecRule with multiple targets, all variables
|
||
will be inspected and all non-disruptive actions trigger for every
|
||
match. In the following example, the TX.test variable will be
|
||
incremented once for every request parameter:
|
||
</p>
|
||
<pre># Set TX.test to zero
|
||
SecAction "phase:2,nolog,pass,setvar:TX.test=0"
|
||
|
||
# Increment TX.test for every request parameter
|
||
SecRule ARGS "test" "phase:2,log,pass,setvar:TX.test=+1"
|
||
</pre>
|
||
<a name="pause" id="pause"></a><h2> <span class="mw-headline"> pause </span></h2>
|
||
<p><b>Description:</b> Pauses transaction processing for the specified
|
||
number of milliseconds. Starting with ModSecurity 2.7 this feature also
|
||
supports macro expansion.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" "log,deny,status:403,pause:5000"
|
||
</pre>
|
||
<dl><dt> Warning </dt><dd> This feature can be of limited benefit
|
||
for slowing down brute force authentication attacks, but use with care.
|
||
If you are under a denial of service attack, the pause feature may make
|
||
matters worse, as it will cause an entire Apache worker (process or
|
||
thread, depending on the deployment mode) to sit idle until the pause is
|
||
completed.
|
||
</dd></dl>
|
||
<a name="phase" id="phase"></a><h2> <span class="mw-headline"> phase </span></h2>
|
||
<p><b>Description</b>: Places the rule or chain into one of five
|
||
available processing phases. It can also be used in SecDefaultAction to
|
||
establish the rule defaults.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Initialize IP address tracking in phase 1
|
||
SecAction phase:1,nolog,pass,initcol:IP=%{REMOTE_ADDR}
|
||
</pre>
|
||
<p>Starting in ModSecurity version v2.7 there are aliases for some phase
|
||
numbers:
|
||
</p>
|
||
<ul><li><b>2 - request</b>
|
||
</li><li><b>4 - response</b>
|
||
</li><li><b>5 - logging</b>
|
||
</li></ul>
|
||
<p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" "phase:request,log,deny"
|
||
</pre>
|
||
<dl><dt> Warning </dt><dd> Keep in mind that if you specify the
|
||
incorrect phase, the variable used in the rule may not yet be available.
|
||
This could lead to a false negative situation where your variable and
|
||
operator may be correct, but it misses malicious data because you
|
||
specified the wrong phase.
|
||
</dd></dl>
|
||
<a name="prepend" id="prepend"></a><h2> <span class="mw-headline">
|
||
prepend </span></h2>
|
||
<p><b>Description:</b> Prepends the text given as parameter to response
|
||
body. Content injection must be enabled (using the SecContentInjection
|
||
directive). No content type checks are made, which means that before
|
||
using any of the content injection actions, you must check whether the
|
||
content type of the response is adequate for injection.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Processing Phases:</b> 3 and 4.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule RESPONSE_CONTENT_TYPE ^text/html \ "phase:3,nolog,pass,prepend:'Header<br>'"
|
||
</pre>
|
||
<dl><dt> Warning </dt><dd> Although macro expansion is allowed in
|
||
the injected content, you are strongly cautioned against inserting user
|
||
defined data fields int output. Doing so would create a cross-site
|
||
scripting vulnerability.
|
||
</dd></dl>
|
||
<a name="proxy" id="proxy"></a><h2> <span class="mw-headline"> proxy </span></h2>
|
||
<p><b>Description:</b> Intercepts the current transaction by forwarding
|
||
the request to another web server using the proxy backend. The
|
||
forwarding is carried out transparently to the HTTP client (i.e.,
|
||
there’s no external redirection taking place).
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" log,proxy:http://honeypothost/
|
||
</pre>
|
||
<p>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 web server, and especially in combination with IP address or
|
||
session tracking.
|
||
</p>
|
||
<a name="redirect" id="redirect"></a><h2> <span class="mw-headline">
|
||
redirect </span></h2>
|
||
<p><b>Description:</b> Intercepts transaction by issuing an external
|
||
(client-visible) redirection to the given location..
|
||
</p><p><b>Action Group:</b> Disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_HEADERS:User-Agent "Test" "phase:1,log,redirect:http://www.example.com/failed.html"
|
||
</pre>
|
||
<p>If the status action is present on the same rule, and its value can
|
||
be used for a redirection (i.e., is one of the following: 301, 302, 303,
|
||
or 307), the value will be used for the redirection status code.
|
||
Otherwise, status code 302 will be used.
|
||
</p>
|
||
<a name="rev" id="rev"></a><h2> <span class="mw-headline"> rev </span></h2>
|
||
<p><b>Description:</b> Specifies rule revision. It is useful in
|
||
combination with the id action to provide an indication that a rule has
|
||
been changed.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "(?:(?:[\;\|\`]\W*?\bcc|\b(wget|curl))\b|\/cc(?:[\'\"\|\;\`\-\s]|$))" \
|
||
"phase:2,rev:'2.1.3',capture,t:none,t:normalisePath,t:lowercase,ctl:auditLogParts=+E,block,msg:'System Command Injection',id:'950907',tag:'WEB_ATTACK/COMMAND_INJECTION',tag:'WASCTC/WASC-31',tag:'OWASP_TOP_10/A1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.command_injection_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/COMMAND_INJECTION-%{matched_var_name}=%{tx.0},skipAfter:END_COMMAND_INJECTION1"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="sanitiseArg" id="sanitiseArg"></a><h2> <span
|
||
class="mw-headline"> sanitiseArg </span></h2>
|
||
<p><b>Description:</b> Prevents sensitive request parameter data from
|
||
being logged to audit log. Each byte of the named parameter(s) is
|
||
replaced with an asterisk.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Never log passwords
|
||
SecAction "nolog,phase:2,sanitiseArg:password,sanitiseArg:newPassword,sanitiseArg:oldPassword"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The sanitize actions affect only the data
|
||
as it is logged to audit log. High-level debug logs may contain
|
||
sensitive data. Apache access log may contain sensitive data placed in
|
||
the request URI.
|
||
</dd></dl>
|
||
<a name="sanitiseMatched" id="sanitiseMatched"></a><h2> <span
|
||
class="mw-headline"> sanitiseMatched </span></h2>
|
||
<p><b>Description:</b> Prevents the matched variable (request argument,
|
||
request header, or response header) from being logged to audit log. Each
|
||
byte of the named parameter(s) is replaced with an asterisk.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b> 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.
|
||
</p>
|
||
<pre>SecRule ARGS_NAMES password nolog,pass,sanitiseMatched
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The sanitize actions affect only the data
|
||
as it is logged to audit log. High-level debug logs may contain
|
||
sensitive data. Apache access log may contain sensitive data placed in
|
||
the request URI.
|
||
</dd></dl>
|
||
<a name="sanitiseMatchedBytes" id="sanitiseMatchedBytes"></a><h2> <span
|
||
class="mw-headline"> sanitiseMatchedBytes </span></h2>
|
||
<p><b>Description:</b> Prevents the matched string in a variable from
|
||
being logged to audit log. Each or a range of bytes of the named
|
||
parameter(s) is replaced with an asterisk.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b> This action can be used to sanitise arbitrary
|
||
transaction elements when they match a condition. For example, the
|
||
example below will sanitise the credit card number.
|
||
</p>
|
||
<ul><li>sanitiseMatchedBytes -- This would x out only the bytes that
|
||
matched.
|
||
</li><li>sanitiseMatchedBytes:1/4 -- This would x out the bytes that
|
||
matched, but keep the first byte and last 4 bytes
|
||
</li></ul>
|
||
<pre># Detect credit card numbers in parameters and
|
||
# prevent them from being logged to audit log
|
||
SecRule ARGS "@verifyCC \d{13,16}" "phase:2,nolog,capture,pass,msg:'Potential credit card number in request',sanitiseMatchedBytes"
|
||
SecRule RESPONSE_BODY "@verifyCC \d{13,16}" "phase:4,t:none,log,capture,block,msg:'Potential credit card number is response body',sanitiseMatchedBytes:0/4"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The sanitize actions affect only the data
|
||
as it is logged to audit log. High-level debug logs may contain
|
||
sensitive data. Apache access log may contain sensitive data placed in
|
||
the request URI. You must use capture action with sanitiseMatchedBytes,
|
||
so the operator must support capture action. ie: @rx, @verifyCC.
|
||
</dd></dl>
|
||
<a name="sanitiseRequestHeader" id="sanitiseRequestHeader"></a><h2> <span
|
||
class="mw-headline"> sanitiseRequestHeader </span></h2>
|
||
<p><b>Description:</b> Prevents a named request header from being logged
|
||
to audit log. Each byte of the named request header is replaced with an
|
||
asterisk..
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b> This will sanitise the data in the Authorization
|
||
header.
|
||
</p>
|
||
<pre>SecAction "phase:1,nolog,pass,sanitiseRequestHeader:Authorization"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The sanitize actions affect only the data
|
||
as it is logged to audit log. High-level debug logs may contain
|
||
sensitive data. Apache access log may contain sensitive data placed in
|
||
the request URI.
|
||
</dd></dl>
|
||
<a name="sanitiseResponseHeader" id="sanitiseResponseHeader"></a><h2> <span
|
||
class="mw-headline"> sanitiseResponseHeader </span></h2>
|
||
<p><b>Description:</b> Prevents a named response header from being
|
||
logged to audit log. Each byte of the named response header is replaced
|
||
with an asterisk.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b> This will sanitise the Set-Cookie data sent to
|
||
the client.
|
||
</p>
|
||
<pre>SecAction "phase:3,nolog,pass,sanitiseResponseHeader:Set-Cookie"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> The sanitize actions affect only the data
|
||
as it is logged to audit log. High-level debug logs may contain
|
||
sensitive data. Apache access log may contain sensitive data placed in
|
||
the request URI.
|
||
</dd></dl>
|
||
<a name="severity" id="severity"></a><h2> <span class="mw-headline">
|
||
severity </span></h2>
|
||
<p><b>Description:</b> Assigns severity to the rule in which it is used.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_METHOD "^PUT$" "id:340002,rev:1,severity:CRITICAL,msg:'Restricted HTTP function'"
|
||
</pre>
|
||
<p>Severity values in ModSecurity follows the numeric scale of syslog
|
||
(where 0 is the most severe). The data below is used by the OWASP
|
||
ModSecurity Core Rule Set (CRS):
|
||
</p>
|
||
<ul><li><b>0 - EMERGENCY</b>: is generated from correlation of anomaly
|
||
scoring data where there is an inbound attack and an outbound leakage.
|
||
</li><li><b>1 - ALERT</b>: is generated from correlation where there is
|
||
an inbound attack and an outbound application level error.
|
||
</li><li><b>2 - CRITICAL</b>: Anomaly Score of 5. Is the highest
|
||
severity level possible without correlation. It is normally generated
|
||
by the web attack rules (40 level files).
|
||
</li><li><b>3 - ERROR</b>: Error - Anomaly Score of 4. Is generated
|
||
mostly from outbound leakage rules (50 level files).
|
||
</li><li><b>4 - WARNING</b>: Anomaly Score of 3. Is generated by
|
||
malicious client rules (35 level files).
|
||
</li><li><b>5 - NOTICE</b>: Anomaly Score of 2. Is generated by the
|
||
Protocol policy and anomaly files.
|
||
</li><li><b>6 - INFO</b>
|
||
</li><li><b>7 - DEBUG</b>
|
||
</li></ul>
|
||
<p>It is possible to specify severity levels using either the numerical
|
||
values or the text values, but you should always specify severity levels
|
||
using the text values, because it is difficult to remember what a
|
||
number stands for. The use of the numerical values is deprecated as of
|
||
version 2.5.0 and may be removed in one of the subsequent major updates.
|
||
</p>
|
||
<a name="setuid" id="setuid"></a><h2> <span class="mw-headline"> setuid </span></h2>
|
||
<p><b>Description:</b> Special-purpose action that initializes the USER
|
||
collection using the username provided as parameter.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule ARGS:username ".*" "phase:2,t:none,pass,nolog,noauditlog,capture,setvar:session.username=%{TX.0},setuid:%{TX.0}"
|
||
</pre>
|
||
<p>After initialization takes place, the variable USERID will be
|
||
available for use in the subsequent rules. This action understands
|
||
application namespaces (configured using SecWebAppId), and will use one
|
||
if it is configured.
|
||
</p>
|
||
<a name="setrsc" id="setrsc"></a><h2> <span class="mw-headline"> setrsc </span></h2>
|
||
<p><b>Description:</b> Special-purpose action that initializes the
|
||
RESOURCE collection using a key provided as parameter.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecAction "phase:1,pass,id:3,log,setrsc:'abcd1234'"
|
||
</pre>
|
||
<p>This action understands application namespaces (configured using
|
||
SecWebAppId), and will use one if it is configured.
|
||
</p>
|
||
<a name="setsid" id="setsid"></a><h2> <span class="mw-headline"> setsid </span></h2>
|
||
<p><b>Description:</b> Special-purpose action that initializes the
|
||
SESSION collection using the session token provided as parameter.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Initialise session variables using the session cookie value
|
||
SecRule REQUEST_COOKIES:PHPSESSID !^$ "chain,nolog,pass,setsid:%{REQUEST_COOKIES.PHPSESSID}"
|
||
</pre>
|
||
<p>Note
|
||
</p><p>After the initialization takes place, the variable SESSIONID will
|
||
be available for use in the subsequent rules. This action understands
|
||
application namespaces (configured using SecWebAppId), and will use one
|
||
if it is configured.
|
||
</p>
|
||
<a name="setenv" id="setenv"></a><h2> <span class="mw-headline"> setenv </span></h2>
|
||
<p><b>Description:</b> Creates, removes, and updates environment
|
||
variables that can be accessed by Apache.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Examples:</b>
|
||
</p>
|
||
<pre>SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "(?i:(j?sessionid|(php)?sessid|(asp|jserv|jw)?session[-_]?(id)?|cf(id|token)|sid))" "phase:3,t:none,pass,nolog,setvar:tx.sessionid=%{matched_var}"
|
||
SecRule TX:SESSIONID "!(?i:\;? ?httponly;?)" "phase:3,t:none,setenv:httponly_cookie=%{matched_var},pass,log,auditlog,msg:'AppDefect: Missing HttpOnly Cookie Flag.'"
|
||
|
||
Header set Set-Cookie "%{httponly_cookie}e; HTTPOnly" env=httponly_cookie
|
||
</pre>
|
||
<a name="setvar" id="setvar"></a><h2> <span class="mw-headline"> setvar </span></h2>
|
||
<p><b>Description:</b> Creates, removes, or updates a variable. Variable
|
||
names are case-insensitive.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Examples:</b>
|
||
To create a variable and set its value to 1 (usually used for setting
|
||
flags), use: <code>setvar:TX.score</code>
|
||
</p><p>To create a variable and initialize it at the same time, use: <code>setvar:TX.score=10</code>
|
||
</p><p>To remove a variable prefix the name with exclamation mark, use: <code>setvar:!TX.score</code>
|
||
</p><p>To increase or decrease variable value, use + and - characters in
|
||
front of a numerical value: <code>setvar:TX.score=+5</code>
|
||
</p><p>Example from OWASP CRS:
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bsys\.user_catalog\b" \
|
||
"phase:2,rev:'2.1.3',capture,t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,t:replaceComments,t:compressWhiteSpace,ctl:auditLogParts=+E, \
|
||
block,msg:'Blind SQL Injection Attack',id:'959517',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1', \
|
||
tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score}, \
|
||
setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
|
||
</pre>
|
||
<a name="skip" id="skip"></a><h2> <span class="mw-headline"> skip </span></h2>
|
||
<p><b>Description:</b> Skips one or more rules (or chains) on successful
|
||
match.
|
||
</p><p><b>Action Group:</b> Flow
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Require Accept header, but not from access from the localhost
|
||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,skip:1"
|
||
|
||
# This rule will be skipped over when REMOTE_ADDR is 127.0.0.1
|
||
SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny,msg:'Request Missing an Accept Header'"
|
||
</pre>
|
||
<p>The skip action works only within the current processing phase and
|
||
not necessarily in the order in which the rules appear in the
|
||
configuration file. If you place a phase 2 rule after a phase 1 rule
|
||
that uses skip, it will not skip over the phase 2 rule. It will skip
|
||
over the next phase 1 rule that follows it in the phase.
|
||
</p>
|
||
<a name="skipAfter" id="skipAfter"></a><h2> <span class="mw-headline">
|
||
skipAfter </span></h2>
|
||
<p>Description: Skips one or more rules (or chains) on a successful
|
||
match, resuming rule execution with the first rule that follows the rule
|
||
(or marker created by SecMarker) with the provided ID.
|
||
</p><p><b>Action Group:</b> Flow
|
||
</p><p><b>Example:</b> The following rules implement the same logic as
|
||
the skip example, but using skipAfter:
|
||
</p>
|
||
<pre># Require Accept header, but not from access from the localhost
|
||
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,skipAfter:IGNORE_LOCALHOST"
|
||
|
||
# This rule will be skipped over when REMOTE_ADDR is 127.0.0.1
|
||
SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny,msg:'Request Missing an Accept Header'"
|
||
SecMarker IGNORE_LOCALHOST
|
||
</pre>
|
||
<p>Example from the OWASP ModSecurity CRS:
|
||
</p>
|
||
<pre>SecMarker BEGIN_HOST_CHECK
|
||
|
||
SecRule &REQUEST_HEADERS:Host "@eq 0" \
|
||
"skipAfter:END_HOST_CHECK,phase:2,rev:'2.1.3',t:none,block,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER_HOST',tag:'WASCTC/WASC-21', \
|
||
tag:'OWASP_TOP_10/A7',tag:'PCI/6.5.10',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score}, \
|
||
setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
|
||
|
||
SecRule REQUEST_HEADERS:Host "^$" \
|
||
"phase:2,rev:'2.1.3',t:none,block,msg:'Request Missing a Host Header',id:'960008',tag:'PROTOCOL_VIOLATION/MISSING_HEADER_HOST',tag:'WASCTC/WASC-21',tag:'OWASP_TOP_10/A7', \
|
||
tag:'PCI/6.5.10',severity:'5',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.protocol_violation_score=+%{tx.notice_anomaly_score}, \
|
||
setvar:tx.%{rule.id}-PROTOCOL_VIOLATION/MISSING_HEADER-%{matched_var_name}=%{matched_var}"
|
||
|
||
SecMarker END_HOST_CHECK
|
||
</pre>
|
||
<p>The skipAfter action works only within the current processing phase
|
||
and not necessarily the order in which the rules appear in the
|
||
configuration file. If you place a phase 2 rule after a phase 1 rule
|
||
that uses skip, it will not skip over the phase 2 rule. It will skip
|
||
over the next phase 1 rule that follows it in the phase.
|
||
</p>
|
||
<a name="status" id="status"></a><h2> <span class="mw-headline"> status </span></h2>
|
||
<p><b>Description:</b> Specifies the response status code to use with
|
||
actions deny and redirect.
|
||
</p><p><b>Action Group:</b> Data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Deny with status 403
|
||
SecDefaultAction "phase:1,log,deny,status:403"
|
||
</pre>
|
||
<p>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.
|
||
</p>
|
||
<a name="t" id="t"></a><h2> <span class="mw-headline"> t </span></h2>
|
||
<p><b>Description:</b> This action is used to specify the transformation
|
||
pipeline to use to transform the value of each variable used in the
|
||
rule before matching.
|
||
</p><p><b>Action Group:</b> Non-disruptive
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule ARGS "(asfunction|javascript|vbscript|data|mocha|livescript):" "t:none,t:htmlEntityDecode,t:lowercase,t:removeNulls,t:removeWhitespace"
|
||
</pre>
|
||
<p>Any transformation functions that you specify in a SecRule will be
|
||
added to the previous ones specified in SecDefaultAction. It is
|
||
recommended that you always use t:none in your rules, which prevents
|
||
them depending on the default configuration.
|
||
</p>
|
||
<a name="tag" id="tag"></a><h2> <span class="mw-headline"> tag </span></h2>
|
||
<p><b>Description:</b> Assigns a tag (category) to a rule or a chain.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bgetparentfolder\b" \
|
||
"phase:2,rev:'2.1.3',capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,ctl:auditLogParts=+E,block,msg:'Cross-site Scripting (XSS) Attack',id:'958016',tag:'WEB_ATTACK/XSS',tag:'WASCTC/WASC-8',tag:'WASCTC/WASC-22',tag:'OWASP_TOP_10/A2',tag:'OWASP_AppSensor/IE1',tag:'PCI/6.5.1',logdata:'% \
|
||
{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"
|
||
</pre>
|
||
<p>The tag information appears along with other rule metadata. The
|
||
purpose of the tagging mechanism to allow easy automated categorization
|
||
of events. Multiple tags can be specified on the same rule. Use forward
|
||
slashes to create a hierarchy of categories (as in the example). Since
|
||
ModSecurity 2.6.0 tag supports macro expansion.
|
||
</p>
|
||
<a name="ver" id="ver"></a><h2> <span class="mw-headline"> ver </span></h2>
|
||
<p><b>Description:</b> Specifies the rule set version.
|
||
</p><p><b>Action Group:</b> Meta-data
|
||
</p><p><b>Version:</b> 2.7
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "\bgetparentfolder\b" \
|
||
"phase:2,ver:'CRS/2.2.4,capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,ctl:auditLogParts=+E,block,msg:'Cross-site Scripting (XSS) Attack',id:'958016',tag:'WEB_ATTACK/XSS',tag:'WASCTC/WASC-8',tag:'WASCTC/WASC-22',tag:'OWASP_TOP_10/A2',tag:'OWASP_AppSensor/IE1',tag:'PCI/6.5.1',logdata:'% \
|
||
{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}"
|
||
</pre>
|
||
<a name="xmlns" id="xmlns"></a><h2> <span class="mw-headline"> xmlns </span></h2>
|
||
<p><b>Description:</b> Configures an XML namespace, which will be used
|
||
in the execution of XPath expressions.
|
||
</p><p><b>Action Group:</b> Data
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>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
|
||
</pre>
|
||
<a name="Operators" id="Operators"></a><h1> <span class="mw-headline">
|
||
Operators </span></h1>
|
||
<p>This section documents the operators currently available in
|
||
ModSecurity.
|
||
</p>
|
||
<a name="beginsWith" id="beginsWith"></a><h2> <span class="mw-headline">
|
||
beginsWith </span></h2>
|
||
<p><b>Description:</b> Returns true if the parameter string is found at
|
||
the beginning of the input. Macro expansion is performed on the
|
||
parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect request line that does not begin with "GET"
|
||
SecRule REQUEST_LINE "!@beginsWith GET"
|
||
</pre>
|
||
<a name="contains" id="contains"></a><h2> <span class="mw-headline">
|
||
contains </span></h2>
|
||
<p><b>Description:</b> Returns true if the parameter string is found
|
||
anywhere in the input. Macro expansion is performed on the parameter
|
||
string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect ".php" anywhere in the request line
|
||
SecRule REQUEST_LINE "@contains .php"
|
||
</pre>
|
||
<a name="endsWith" id="endsWith"></a><h2> <span class="mw-headline">
|
||
endsWith </span></h2>
|
||
<p><b>Description:</b> Returns true if the parameter string is found at
|
||
the end of the input. Macro expansion is performed on the parameter
|
||
string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect request line that does not end with "HTTP/1.1"
|
||
SecRule REQUEST_LINE "!@endsWith HTTP/1.1"
|
||
</pre>
|
||
<a name="eq" id="eq"></a><h2> <span class="mw-headline"> eq </span></h2>
|
||
<p><b>Description:</b> Performs numerical comparison and returns true if
|
||
the input value is equal to the provided parameter. Macro expansion is
|
||
performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect exactly 15 request headers
|
||
SecRule &REQUEST_HEADERS_NAMES "@eq 15"
|
||
</pre>
|
||
<a name="ge" id="ge"></a><h2> <span class="mw-headline"> ge </span></h2>
|
||
<p><b>Description:</b> Performs numerical comparison and returns true if
|
||
the input value is greater than or equal to the provided parameter.
|
||
Macro expansion is performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect 15 or more request headers
|
||
SecRule &REQUEST_HEADERS_NAMES "@ge 15"
|
||
</pre>
|
||
<a name="geoLookup" id="geoLookup"></a><h2> <span class="mw-headline">
|
||
geoLookup </span></h2>
|
||
<p><b>Description:</b> Performs a geolocation lookup using the IP
|
||
address in input against the geolocation database previously configured
|
||
using SecGeoLookupDb. If the lookup is successful, the obtained
|
||
information is captured in the GEO collection.
|
||
</p><p><b>Example:</b>
|
||
The geoLookup operator matches on success and is thus best used in
|
||
combination with nolog,pass. If you wish to block on a failed lookup
|
||
(which may be over the top, depending on how accurate the geolocation
|
||
database is), the following example demonstrates how best to do it:
|
||
</p>
|
||
<pre># Configure geolocation database
|
||
SecGeoLookupDb /path/to/GeoLiteCity.dat
|
||
...
|
||
# Lookup IP address
|
||
SecRule REMOTE_ADDR "@geoLookup" "phase:1,nolog,pass"
|
||
|
||
# Block IP address for which geolocation failed
|
||
SecRule &GEO "@eq 0" "phase:1,deny,msg:'Failed to lookup IP'"
|
||
</pre>
|
||
<p>See the GEO variable for an example and more information on various
|
||
fields available.
|
||
</p>
|
||
<a name="gsbLookup" id="gsbLookup"></a><h2> <span class="mw-headline">
|
||
gsbLookup </span></h2>
|
||
<p><b>Description:</b> Performs a local lookup of Google's Safe Browsing
|
||
using URLs in input against the GSB database previously configured
|
||
using SecGsbLookupDb. When combined with capture operator it will save
|
||
the matched url into tx.0 variable.
|
||
</p><p><b>Syntax:</b> <code>SecRule TARGET "@gsbLookup REGEX" ACTIONS</code>
|
||
</p><p><b>Version:</b> 2.6
|
||
</p><p><b>Example:</b>
|
||
The gsbLookup operator matches on success and is thus best used in
|
||
combination with a block or redirect action. If you wish to block on
|
||
successful lookups, the following example demonstrates how best to do
|
||
it:
|
||
</p>
|
||
<pre># Configure Google Safe Browsing database
|
||
SecGsbLookupDb /path/to/GsbMalware.dat
|
||
...
|
||
# Check response bodies for malicious links
|
||
SecRule RESPONSE_BODY "@gsbLookup =\"https?\:\/\/(.*?)\"" "phase:4,capture,log,block,msg:'Bad url detected in RESPONSE_BODY (Google Safe Browsing Check)',logdata:'http://www.google.com/safebrowsing/diagnostic?site=%{tx.0}'"
|
||
</pre>
|
||
<a name="gt" id="gt"></a><h2> <span class="mw-headline"> gt </span></h2>
|
||
<p><b>Description:</b> Performs numerical comparison and returns true if
|
||
the input value is greater than the operator parameter. Macro expansion
|
||
is performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect more than 15 headers in a request
|
||
SecRule &REQUEST_HEADERS_NAMES "@gt 15"
|
||
</pre>
|
||
<a name="inspectFile" id="inspectFile"></a><h2> <span
|
||
class="mw-headline"> inspectFile </span></h2>
|
||
<p><b>Description:</b> Executes an external program for every variable
|
||
in the target list. The contents of the variable is provided to the
|
||
script as the first parameter on the command line. The program must be
|
||
specified as the first parameter to the operator. As of version 2.5.0,
|
||
if the supplied program filename is not absolute, it is treated as
|
||
relative to the directory in which the configuration file resides. Also
|
||
as of version 2.5.0, if the filename is determined to be a Lua script
|
||
(based on its .lua extension), the script will be processed by the
|
||
internal Lua engine. Internally processed scripts will often run faster
|
||
(there is no process creation overhead) and have full access to the
|
||
transaction context of ModSecurity.
|
||
</p><p>The @inspectFile operator was initially designed for file
|
||
inspection (hence the name), but it can also be used in any situation
|
||
that requires decision making using external logic.
|
||
</p><p>The OWASP ModSecurity Core Rule Set (CRS) includes a utility
|
||
script in the /util directory called runav.pl <a
|
||
href="http://mod-security.svn.sourceforge.net/viewvc/mod-security/crs/trunk/util/"
|
||
class="external autonumber"
|
||
title="http://mod-security.svn.sourceforge.net/viewvc/mod-security/crs/trunk/util/"
|
||
rel="nofollow">[13]</a> that allows the file approval mechanism to
|
||
integrate with the ClamAV virus scanner. This is especially handy to
|
||
prevent viruses and exploits from entering the web server through file
|
||
upload.
|
||
</p>
|
||
<pre>#!/usr/bin/perl
|
||
#
|
||
# runav.pl
|
||
# Copyright (c) 2004-2011 Trustwave
|
||
#
|
||
# This script is an interface between ModSecurity and its
|
||
# ability to intercept files being uploaded through the
|
||
# web server, and ClamAV
|
||
|
||
|
||
$CLAMSCAN = "clamscan";
|
||
|
||
if ($#ARGV != 0) {
|
||
print "Usage: modsec-clamscan.pl <filename>\n";
|
||
exit;
|
||
}
|
||
|
||
my ($FILE) = shift @ARGV;
|
||
|
||
$cmd = "$CLAMSCAN --stdout --disable-summary $FILE";
|
||
$input = `$cmd`;
|
||
$input =~ m/^(.+)/;
|
||
$error_message = $1;
|
||
|
||
$output = "0 Unable to parse clamscan output [$1]";
|
||
|
||
if ($error_message =~ m/: Empty file\.?$/) {
|
||
$output = "1 empty file";
|
||
}
|
||
elsif ($error_message =~ m/: (.+) ERROR$/) {
|
||
$output = "0 clamscan: $1";
|
||
}
|
||
elsif ($error_message =~ m/: (.+) FOUND$/) {
|
||
$output = "0 clamscan: $1";
|
||
}
|
||
elsif ($error_message =~ m/: OK$/) {
|
||
$output = "1 clamscan: OK";
|
||
}
|
||
|
||
print "$output\n";
|
||
|
||
</pre>
|
||
<p><b>Example:</b> Using the runav.pl script:
|
||
</p>
|
||
<pre># Execute external program to validate uploaded files
|
||
SecRule FILES_TMPNAMES "@inspectFile /path/to/util/runav.pl"
|
||
</pre>
|
||
<p>Example of using Lua script (placed in the same directory as the
|
||
configuration file):
|
||
</p>
|
||
<pre>SecRule FILES_TMPNANMES "@inspectFile inspect.lua"
|
||
</pre>
|
||
<p>The contents of inspect.lua:
|
||
</p>
|
||
<pre>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.
|
||
local f = io.open(filename, "rb");
|
||
local d = f:read(10);
|
||
f:close();
|
||
|
||
-- Return null if there is no reason to believe there is ansything
|
||
-- wrong with the file (no match). Returning any text will be taken
|
||
-- to mean a match should be trigerred.
|
||
return null;
|
||
end
|
||
</pre>
|
||
<p><b>Reference:</b> <a
|
||
href="http://blog.spiderlabs.com/2010/10/advanced-topic-of-the-week-preventing-malicious-pdf-file-uploads.html"
|
||
class="external free"
|
||
title="http://blog.spiderlabs.com/2010/10/advanced-topic-of-the-week-preventing-malicious-pdf-file-uploads.html"
|
||
rel="nofollow">http://blog.spiderlabs.com/2010/10/advanced-topic-of-the-week-preventing-malicious-pdf-file-uploads.html</a>
|
||
</p>
|
||
<a name="ipMatch" id="ipMatch"></a><h2> <span class="mw-headline">
|
||
ipMatch </span></h2>
|
||
<p><b>Description:</b> Performs a fast ipv4 or ipv6 match of REMOTE_ADDR
|
||
variable data. Can handle the following formats:
|
||
</p>
|
||
<ul><li>Full IPv4 Address - 192.168.1.100
|
||
</li><li>Network Block/CIDR Address - 192.168.1.0/24
|
||
</li><li>Full IPv6 Address - 2001:db8:85a3:8d3:1319:8a2e:370:7348
|
||
</li><li>Network Block/CIDR Address -
|
||
2001:db8:85a3:8d3:1319:8a2e:370:0/24
|
||
</li></ul>
|
||
<p><b>Examples:</b>
|
||
</p><p>Individual Address:
|
||
</p>
|
||
<pre>SecRule REMOTE_ADDR "@ipMatch 192.168.1.100"
|
||
</pre>
|
||
<p>Multiple Addresses w/network block:
|
||
</p>
|
||
<pre>SecRule REMOTE_ADDR "@ipMatch 192.168.1.100,192.168.1.50,10.10.50.0/24"
|
||
</pre>
|
||
<a name="ipMatchF" id="ipMatchF"></a><h2> <span class="mw-headline">
|
||
ipMatchF </span></h2>
|
||
<p>short alias for ipMatchFromFile
|
||
</p>
|
||
<a name="ipMatchFromFile" id="ipMatchFromFile"></a><h2> <span
|
||
class="mw-headline"> ipMatchFromFile </span></h2>
|
||
<p><b>Description:</b> Performs a fast ipv4 or ipv6 match of REMOTE_ADDR
|
||
variable, loading data from a file. Can handle the following formats:
|
||
</p>
|
||
<ul><li>Full IPv4 Address - 192.168.1.100
|
||
</li><li>Network Block/CIDR Address - 192.168.1.0/24
|
||
</li><li>Full IPv6 Address - 2001:db8:85a3:8d3:1319:8a2e:370:7348
|
||
</li><li>Network Block/CIDR Address -
|
||
2001:db8:85a3:8d3:1319:8a2e:370:0/24
|
||
</li></ul>
|
||
<p><b>Examples:</b>
|
||
</p>
|
||
<pre>SecRule REMOTE_ADDR "@ipMatch ips.txt"
|
||
</pre>
|
||
<p>The file ips.txt may contain:
|
||
</p>
|
||
<pre>192.168.0.1
|
||
172.16.0.0/16
|
||
10.0.0.0/8
|
||
</pre>
|
||
<a name="le" id="le"></a><h2> <span class="mw-headline"> le </span></h2>
|
||
<p><b>Description:</b> Performs numerical comparison and returns true if
|
||
the input value is less than or equal to the operator parameter. Macro
|
||
expansion is performed on the parameter string before comparison.
|
||
</p><p><b>Example</b>:
|
||
</p>
|
||
<pre># Detect 15 or fewer headers in a request
|
||
SecRule &REQUEST_HEADERS_NAMES "@le 15"
|
||
</pre>
|
||
<a name="lt" id="lt"></a><h2> <span class="mw-headline"> lt </span></h2>
|
||
<p><b>Description:</b> Performs numerical comparison and returns true if
|
||
the input value is less than to the operator parameter. Macro expansion
|
||
is performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect fewer than 15 headers in a request
|
||
SecRule &REQUEST_HEADERS_NAMES "@lt 15"
|
||
</pre>
|
||
<a name="pm" id="pm"></a><h2> <span class="mw-headline"> pm </span></h2>
|
||
<p><b>Description:</b> Performs a case-insensitive match of the provided
|
||
phrases against the desired input value. The operator uses a set-based
|
||
matching algorithm (Aho-Corasick), which means that it will match any
|
||
number of keywords in parallel. When matching of a large number of
|
||
keywords is needed, this operator performs much better than a regular
|
||
expression.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect suspicious client by looking at the user agent identification
|
||
SecRule REQUEST_HEADERS:User-Agent "@pm WebZIP WebCopier Webster WebStripper ... SiteSnagger ProWebWalker CheeseBot"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> Starting on ModSecurity v2.6.0 this
|
||
operator supports a snort/suricata content style. ie: "@pm A|42|C|44|F".
|
||
</dd></dl>
|
||
<a name="pmf" id="pmf"></a><h2> <span class="mw-headline"> pmf </span></h2>
|
||
<p>Short alias for pmFromFile.
|
||
</p>
|
||
<a name="pmFromFile" id="pmFromFile"></a><h2> <span class="mw-headline">
|
||
pmFromFile </span></h2>
|
||
<p><b>Description:</b> Performs a case-insensitive match of the provided
|
||
phrases against the desired input value. The operator uses a set-based
|
||
matching algorithm (Aho-Corasick), which means that it will match any
|
||
number of keywords in parallel. When matching of a large number of
|
||
keywords is needed, this operator performs much better than a regular
|
||
expression.
|
||
</p><p>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.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect suspicious user agents using the keywords in
|
||
# the files /path/to/blacklist1 and blacklist2 (the latter
|
||
# must be placed in the same folder as the configuration file)
|
||
SecRule REQUEST_HEADERS:User-Agent "@pm /path/to/blacklist1 blacklist2"
|
||
</pre>
|
||
<p>Notes:
|
||
</p>
|
||
<ol><li>Files must contain exactly one phrase per line. End of line
|
||
markers (both LF and CRLF) will be stripped from each phrase and any
|
||
whitespace trimmed from both the beginning and the end. Empty lines and
|
||
comment lines (those beginning with the # character) will be ignored.
|
||
</li><li>To allow easier inclusion of phrase files with rule sets,
|
||
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.
|
||
</li><li>The @pm operator phrases do not support metacharacters.
|
||
</li><li>Because this operator does not check for boundaries when
|
||
matching, false positives are possible in some cases. For example, if
|
||
you want to use @pm for IP address matching, the phrase 1.2.3.4 will
|
||
potentially match more than one IP address (e.g., it will also match
|
||
1.2.3.40 or 1.2.3.41). To avoid the false positives, you can use your
|
||
own boundaries in phrases. For example, use /1.2.3.4/ instead of just
|
||
1.2.3.4. Then, in your rules, also add the boundaries where appropriate.
|
||
You will find a complete example in the example.
|
||
</li></ol>
|
||
<pre># Prepare custom REMOTE_ADDR variable
|
||
SecAction "phase:1,nolog,pass,setvar:tx.REMOTE_ADDR=/%{REMOTE_ADDR}/"
|
||
|
||
# Check if REMOTE_ADDR is blacklisted
|
||
SecRule TX:REMOTE_ADDR "@pmFromFile blacklist.txt" "phase:1,deny,msg:'Blacklisted IP address'"
|
||
</pre>
|
||
<p>The file blacklist.txt may contain:
|
||
</p>
|
||
<pre># ip-blacklist.txt contents:
|
||
# NOTE: All IPs must be prefixed/suffixed with "/" as the rules
|
||
# will add in this character as a boundary to ensure
|
||
# the entire IP is matched.
|
||
# SecAction "phase:1,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'"
|
||
/1.2.3.4/
|
||
/5.6.7.8/
|
||
</pre>
|
||
<dl><dt> Warning </dt><dd> Before ModSecurity 2.5.12, the
|
||
@pmFromFile operator understood only the LF line endings and did not
|
||
trim the whitespace from phrases. If you are using an older version of
|
||
ModSecurity, you should take care when editing the phrase files to avoid
|
||
using the undesired characters in patterns.e files should be one phrase
|
||
per line. End of line markers will be stripped from the phrases (LF and
|
||
CRLF), and whitespace is trimmed from both sides of the phrases. Empty
|
||
lines and comment lines (beginning with a '#') are ignored. 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.
|
||
</dd></dl>
|
||
<p><br>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Starting on ModSecurity v2.6.0 this
|
||
operator supports a snort/suricata content style. ie: "A|42|C|44|F".
|
||
</dd></dl>
|
||
<a name="rbl" id="rbl"></a><h2> <span class="mw-headline"> rbl </span></h2>
|
||
<p><b>Description:</b> Looks up the input value in the RBL (real-time
|
||
block list) given as parameter. The parameter can be an IPv4 address or a
|
||
hostname.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre>SecRule REMOTE_ADDR "@rbl sbl-xbl.spamhaus.org" "phase:1,t:none,pass,nolog,auditlog,msg:'RBL Match for SPAM Source',tag:'AUTOMATION/MALICIOUS',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.automation_score=+%{tx.warning_anomaly_score},setvar:tx.anomaly_score=+%{tx.warning_anomaly_score}, \
|
||
setvar:tx.%{rule.id}-AUTOMATION/MALICIOUS-%{matched_var_name}=%{matched_var},setvar:ip.spammer=1,expirevar:ip.spammer=86400,setvar:ip.previous_rbl_check=1,expirevar:ip.previous_rbl_check=86400,skipAfter:END_RBL_CHECK"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> If the RBL used is dnsbl.httpbl.org
|
||
(Honeypot Project RBL) then the SecHttpBlKey directive must specify the
|
||
user's registered API key.
|
||
</dd><dt> Note </dt><dd> If the RBL used is either multi.uribl.com
|
||
or zen.spamhaus.org combined RBLs, it is possible to also parse the
|
||
return codes in the last octet of the DNS response to identify which
|
||
specific RBL the IP was found in.
|
||
</dd></dl>
|
||
<a name="rsub" id="rsub"></a><h2> <span class="mw-headline"> rsub </span></h2>
|
||
<p><b>Description</b>: Performs regular expression data substitution
|
||
when applied to either the STREAM_INPUT_BODY or STREAM_OUTPUT_BODY
|
||
variables. This operator also supports macro expansion. Starting with
|
||
ModSecurity 2.7.0 this operator supports the syntax |hex| allowing users
|
||
to use special chars like \n \r
|
||
</p><p><b>Syntax:</b> <code>@rsub s/regex/str/[id]</code>
|
||
</p><p><b>Examples:</b>
|
||
Removing HTML Comments from response bodies:
|
||
</p>
|
||
<pre>SecStreamOutBodyInspection On
|
||
SecRule STREAM_OUTPUT_BODY "@rsub s/<!--.*?-->/ /" "phase:4,t:none,nolog,pass"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> If you plan to manipulate live data by
|
||
using @rsub with the STREAM_ variables, you must also enable
|
||
SecContentInjection directive.
|
||
</dd></dl>
|
||
<p>Regular expressions are handled by the PCRE library <a
|
||
href="http://www.pcre.org/" class="external autonumber"
|
||
title="http://www.pcre.org" rel="nofollow">[14]</a>. ModSecurity
|
||
compiles its regular expressions with the following settings:
|
||
</p>
|
||
<ol><li>The entire input is treated as a single line, even when there
|
||
are newline characters present.
|
||
</li><li>All matches are case-sensitive. If you wish to perform
|
||
case-insensitive matching, you can either use the lowercase
|
||
transformation function or force case-insensitive matching by prefixing
|
||
the regular expression pattern with the (?i) modifier (a PCRE feature;
|
||
you will find many similar features in the PCRE documentation). Also a
|
||
flag [d] should be used if you want to escape the regex string chars
|
||
when use macro expansion.
|
||
</li><li>The PCRE_DOTALL and PCRE_DOLLAR_ENDONLY flags are set during
|
||
compilation, meaning that a single dot will match any character,
|
||
including the newlines, and a $ end anchor will not match a trailing
|
||
newline character.
|
||
</li></ol>
|
||
<p>Regular expressions are a very powerful tool. You are strongly
|
||
advised to read the PCRE documentation to get acquainted with its
|
||
features.
|
||
</p>
|
||
<a name="rx" id="rx"></a><h2> <span class="mw-headline"> rx </span></h2>
|
||
<p><b>Description</b>: Performs a regular expression match of the
|
||
pattern provided as parameter. <b>This is the default operator; the
|
||
rules that do not explicitly specify an operator default to @rx</b>.
|
||
</p><p><b>Examples:</b>
|
||
</p>
|
||
<pre># Detect Nikto
|
||
SecRule REQUEST_HEADERS:User-Agent "@rx nikto" phase:1,t:lowercase
|
||
|
||
# Detect Nikto with a case-insensitive pattern
|
||
SecRule REQUEST_HEADERS:User-Agent "@rx (?i)nikto" phase:1,t:none
|
||
|
||
# Detect Nikto with a case-insensitive pattern
|
||
SecRule REQUEST_HEADERS:User-Agent "(?i)nikto"
|
||
</pre>
|
||
<p>Regular expressions are handled by the PCRE library <a
|
||
href="http://www.pcre.org/" class="external autonumber"
|
||
title="http://www.pcre.org" rel="nofollow">[15]</a>. ModSecurity
|
||
compiles its regular expressions with the following settings:
|
||
</p>
|
||
<ol><li>The entire input is treated as a single line, even when there
|
||
are newline characters present.
|
||
</li><li>All matches are case-sensitive. If you wish to perform
|
||
case-insensitive matching, you can either use the lowercase
|
||
transformation function or force case-insensitive matching by prefixing
|
||
the regular expression pattern with the (?i) modifier (a PCRE feature;
|
||
you will find many similar features in the PCRE documentation).
|
||
</li><li>The PCRE_DOTALL and PCRE_DOLLAR_ENDONLY flags are set during
|
||
compilation, meaning that a single dot will match any character,
|
||
including the newlines, and a $ end anchor will not match a trailing
|
||
newline character.
|
||
</li></ol>
|
||
<p>Regular expressions are a very powerful tool. You are strongly
|
||
advised to read the PCRE documentation to get acquainted with its
|
||
features.
|
||
</p>
|
||
<a name="streq" id="streq"></a><h2> <span class="mw-headline"> streq </span></h2>
|
||
<p><b>Description:</b> Performs a string comparison and returns true if
|
||
the parameter string is identical to the input string. Macro expansion
|
||
is performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect request parameters "foo" that do not # contain "bar", exactly.
|
||
SecRule ARGS:foo "!@streq bar"
|
||
</pre>
|
||
<a name="strmatch" id="strmatch"></a><h2> <span class="mw-headline">
|
||
strmatch </span></h2>
|
||
<p><b>Description:</b> Performs a string match of the provided word
|
||
against the desired input value. The operator uses the pattern matching
|
||
Boyer-Moore-Horspool algorithm, which means that it is a single pattern
|
||
matching operator. This operator performs much better than a regular
|
||
expression.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect suspicious client by looking at the user agent identification
|
||
SecRule REQUEST_HEADERS:User-Agent "@strmatch WebZIP"
|
||
</pre>
|
||
<p><br>
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Starting on ModSecurity v2.6.0 this
|
||
operator supports a snort/suricata content style. ie: "@strmatch
|
||
A|42|C|44|F".
|
||
</dd></dl>
|
||
<a name="validateByteRange" id="validateByteRange"></a><h2> <span
|
||
class="mw-headline"> validateByteRange </span></h2>
|
||
<p><b>Description:</b> Validates that the byte values used in input fall
|
||
into the range specified by the operator parameter. This operator
|
||
matches on an input value that contains bytes that are not in the
|
||
specified range.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Enforce very strict byte range for request parameters (only
|
||
# works for the applications that do not use the languages other
|
||
# than English).
|
||
SecRule ARGS "@validateByteRange 10, 13, 32-126"
|
||
</pre>
|
||
<p>The validateByteRange is most useful when used to detect the presence
|
||
of NUL bytes, which don’t have a legitimate use, but which are often
|
||
used as an evasion technique.
|
||
</p>
|
||
<pre># Do not allow NUL bytes
|
||
SecRule ARGS "@validateByteRange 1-255"
|
||
</pre>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<p>validateByteRange is similar to the ModSecurity 1.X
|
||
SecFilterForceByteRange Directive however since it works in a rule
|
||
context, it has the following differences:
|
||
</p>
|
||
<ul><li>You can specify a different range for different variables.
|
||
</li><li>It has an "event" context (id, msg....)
|
||
</li><li>It is executed in the flow of rules rather than being a built
|
||
in pre-check.
|
||
</li></ul>
|
||
<a name="validateDTD" id="validateDTD"></a><h2> <span
|
||
class="mw-headline"> validateDTD </span></h2>
|
||
<p><b>Description:</b> Validates the XML DOM tree against the supplied
|
||
DTD. The DOM tree must have been built previously using the XML request
|
||
body processor. This operator matches when the validation fails.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Parse the request bodies that contain XML
|
||
SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML"
|
||
|
||
# Validate XML payload against DTD
|
||
SecRule XML "@validateDTD /path/to/xml.dtd" "phase:2,deny,msg:'Failed DTD validation'"
|
||
</pre>
|
||
<a name="validateEncryption" id="validateEncryption"></a><h2> <span
|
||
class="mw-headline"> validateEncryption </span></h2>
|
||
<p><b>Description:</b> Validates REQUEST_URI that contains data
|
||
protected by the encryption engine.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Validates requested URI that matches a regular expression.
|
||
SecRule REQUEST_URI "@validateEncryption "product_info|product_list" "phase:1,deny,id:123456"
|
||
</pre>
|
||
<a name="validateSchema" id="validateSchema"></a><h2> <span
|
||
class="mw-headline"> validateSchema </span></h2>
|
||
<p><b>Description:</b> Validates the XML DOM tree against the supplied
|
||
XML Schema. The DOM tree must have been built previously using the XML
|
||
request body processor. This operator matches when the validation fails.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Parse the request bodies that contain XML
|
||
SecRule REQUEST_HEADERS:Content-Type ^text/xml$ "phase:1,nolog,pass,t:lowercase,ctl:requestBodyProcessor=XML"
|
||
|
||
# Validate XML payload against DTD
|
||
SecRule XML "@validateSchema /path/to/xml.xsd" "phase:2,deny,msg:'Failed DTD validation'"
|
||
</pre>
|
||
<a name="validateUrlEncoding" id="validateUrlEncoding"></a><h2> <span
|
||
class="mw-headline"> validateUrlEncoding </span></h2>
|
||
<p><b>Description</b>: Validates the URL-encoded characters in the
|
||
provided input string.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Validate URL-encoded characters in the request URI
|
||
SecRule REQUEST_URI_RAW "@validateUrlEncoding"
|
||
</pre>
|
||
<p>ModSecurity will automatically decode the URL-encoded characters in
|
||
request parameters, which means that there is little sense in applying
|
||
the @validateUrlEncoding operator to them —that is, unless you know that
|
||
some of the request parameters were URL-encoded more than once. Use
|
||
this operator against raw input, or against the input that you know is
|
||
URL-encoded. For example, some applications will URL-encode cookies,
|
||
although that’s not in the standard. Because it is not in the standard,
|
||
ModSecurity will neither validate nor decode such encodings.
|
||
</p>
|
||
<a name="validateUtf8Encoding" id="validateUtf8Encoding"></a><h2> <span
|
||
class="mw-headline"> validateUtf8Encoding </span></h2>
|
||
<p><b>Description:</b> Check whether the input is a valid UTF-8 string.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Make sure all request parameters contain only valid UTF-8
|
||
SecRule ARGS "@validateUtf8Encoding"
|
||
</pre>
|
||
<p>The @validateUtf8Encoding operator detects the following problems:
|
||
</p>
|
||
<dl><dt> Not enough bytes </dt><dd> UTF-8 supports two-, three-,
|
||
four-, five-, and six-byte encodings. ModSecurity will locate cases when
|
||
one or more bytes is/are missing from a character.
|
||
</dd><dt> Invalid characters </dt><dd> The two most significant
|
||
bits in most characters should be fixed to 0x80. Some attack techniques
|
||
use different values as an evasion technique.
|
||
</dd><dt> Overlong characters </dt><dd> ASCII characters are mapped
|
||
directly into UTF-8, which means that an ASCII character is one UTF-8
|
||
character at the same time. However, in UTF-8 many ASCII characters can
|
||
also be encoded with two, three, four, five, and six bytes. This is no
|
||
longer legal in the newer versions of Unicode, but many older
|
||
implementations still support it. The use of overlong UTF-8 characters
|
||
is common for evasion.
|
||
</dd></dl>
|
||
<dl><dt> Notes </dt><dd>
|
||
</dd></dl>
|
||
<ul><li>Most, but not all applications use UTF-8. If you are dealing
|
||
with an application that does, validating that all request parameters
|
||
are valid UTF-8 strings is a great way to prevent a number of evasion
|
||
techniques that use the assorted UTF-8 weaknesses. False positives are
|
||
likely if you use this operator in an application that does not use
|
||
UTF-8.
|
||
</li><li>Many web servers will also allow UTF-8 in request URIs. If
|
||
yours does, you can verify the request URI using @validateUtf8Encoding.
|
||
</li></ul>
|
||
<a name="verifyCC" id="verifyCC"></a><h2> <span class="mw-headline">
|
||
verifyCC </span></h2>
|
||
<p><b>Description:</b> Detects credit card numbers in input. This
|
||
operator will first use the supplied regular expression to perform an
|
||
initial match, following up with the Luhn algorithm calculation to
|
||
minimize false positives.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect credit card numbers in parameters and
|
||
# prevent them from being logged to audit log
|
||
SecRule ARGS "@verifyCC \d{13,16}" "phase:2,nolog,pass,msg:'Potential credit card number',sanitiseMatched"
|
||
</pre>
|
||
<a name="verifyCPF" id="verifyCPF"></a><h2> <span class="mw-headline">
|
||
verifyCPF </span></h2>
|
||
<p><b>Description:</b> Detects CPF numbers (Brazilian social number) in
|
||
input. This operator will first use the supplied regular expression to
|
||
perform an initial match, following up with an algorithm calculation to
|
||
minimize false positives.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect CPF numbers in parameters and
|
||
# prevent them from being logged to audit log
|
||
SecRule ARGS "@verifyCPF /^([0-9]{3}\.){2}[0-9]{3}-[0-9]{2}$/" "phase:2,nolog,pass,msg:'Potential CPF number',sanitiseMatched"
|
||
</pre>
|
||
<a name="verifySSN" id="verifySSN"></a><h2> <span class="mw-headline">
|
||
verifySSN </span></h2>
|
||
<p><b>Description:</b> Detects US social security numbers (SSN) in
|
||
input. This operator will first use the supplied regular expression to
|
||
perform an initial match, following up with an SSN algorithm calculation
|
||
to minimize false positives.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect social security numbers in parameters and
|
||
# prevent them from being logged to audit log
|
||
SecRule ARGS "@verifySSN \d{3}-?\d{2}-?\d{4}" "phase:2,nolog,pass,msg:'Potential social security number',sanitiseMatched"
|
||
</pre>
|
||
<p><b>Version:</b> 2.6
|
||
</p><p><b>SSN Format</b>:
|
||
</p><p>A Social Security number is broken up into 3 sections:
|
||
</p>
|
||
<ul><li>Area (3 digits)
|
||
</li><li>Group (2 digits)
|
||
</li><li>Serial (4 digits)
|
||
</li></ul>
|
||
<p><b>verifySSN checks:</b>
|
||
</p>
|
||
<ul><li>Must have 9 digits
|
||
</li><li>Cannot be a sequence number (ie,, 123456789, 012345678)
|
||
</li><li>Cannot be a repetition sequence number ( ie 11111111 ,
|
||
222222222)
|
||
</li><li>Cannot have area and/or group and/or serial zeroed sequences
|
||
</li><li>Area code must be less than 740
|
||
</li><li>Area code must be different then 666
|
||
</li></ul>
|
||
<a name="within" id="within"></a><h2> <span class="mw-headline"> within </span></h2>
|
||
<p><b>Description:</b> Returns true if the input value is found anywhere
|
||
within the parameter value (the opposite of @contains). Macro expansion
|
||
is performed on the parameter string before comparison.
|
||
</p><p><b>Example:</b>
|
||
</p>
|
||
<pre># Detect request methods other than GET, POST and HEAD SecRule REQUEST_METHOD "!@within GET,POST,HEAD"
|
||
</pre>
|
||
<a name="Macro_Expansion" id="Macro_Expansion"></a><h1> <span
|
||
class="mw-headline"> Macro Expansion </span></h1>
|
||
<p>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.
|
||
</p><p>Format:
|
||
</p>
|
||
<pre>%{VARIABLE}
|
||
%{COLLECTION.VARIABLE}
|
||
</pre>
|
||
<p>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.
|
||
</p><p>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.
|
||
</p>
|
||
<a name="Persistant_Storage" id="Persistant_Storage"></a><h1> <span
|
||
class="mw-headline"> Persistant Storage </span></h1>
|
||
<p>At this time it is only possible to havefive collections in which
|
||
data is stored persistantly (i.e. data available to multiple requests).
|
||
These are: GLOBAL, RESOURCE, IP, SESSION and USER.
|
||
</p><p>Every collection contains several built-in variables that are
|
||
available and are read-only unless otherwise specified:
|
||
</p>
|
||
<ol><li><b>CREATE_TIME</b> - date/time of the creation of the
|
||
collection.
|
||
</li><li><b>IS_NEW</b> - set to 1 if the collection is new (not yet
|
||
persisted) otherwise set to 0.
|
||
</li><li><b>KEY</b> - the value of the initcol variable (the client's IP
|
||
address in the example).
|
||
</li><li><b>LAST_UPDATE_TIME</b> - date/time of the last update to the
|
||
collection.
|
||
</li><li><b>TIMEOUT</b> - 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).
|
||
</li><li><b>UPDATE_COUNTER</b> - how many times the collection has been
|
||
updated since creation.
|
||
</li><li><b>UPDATE_RATE</b> - is the average rate updates per minute
|
||
since creation.
|
||
</li></ol>
|
||
<p>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),
|
||
global data or resource-specific data, use action initcol.
|
||
</p>
|
||
<dl><dt> Note </dt><dd> Persistent collections can only be
|
||
initialized once per transaction.
|
||
</dd></dl>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<dl><dt> Note </dt><dd> 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.
|
||
</dd></dl>
|
||
<a name="Miscellaneous_Topics" id="Miscellaneous_Topics"></a><h1> <span
|
||
class="mw-headline"> Miscellaneous Topics </span></h1>
|
||
<a name="Impedance_Mismatch" id="Impedance_Mismatch"></a><h2> <span
|
||
class="mw-headline"> Impedance Mismatch </span></h2>
|
||
<p>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.
|
||
</p><p>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.
|
||
</p>
|
||
<a name="Impedance_Mismatch_with_PHP_Apps"
|
||
id="Impedance_Mismatch_with_PHP_Apps"></a><h3> <span class="mw-headline">
|
||
Impedance Mismatch with PHP Apps </span></h3>
|
||
<ol><li>When writing rules to protect PHP applications you need to pay
|
||
attention to the following facts:
|
||
</li><li>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.
|
||
</li><li>Whitespace at the beginning of parameter names is ignored.
|
||
(This is very dangerous if you are writing rules to target specific
|
||
named variables.)
|
||
</li><li>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.)
|
||
</li><li>Cookies can be treated as request parameters.
|
||
</li><li>The discussion about variable names applies equally to the
|
||
cookie names.
|
||
</li><li>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).
|
||
</li><li>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.
|
||
</li><li>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.
|
||
</li><li>PHP will also automatically create nested arrays for you. For
|
||
example "p[x][y]=1" results in a total of three variables.
|
||
</li></ol>
|
||
<a name="A_Recommended_Base_Configuration"
|
||
id="A_Recommended_Base_Configuration"></a><h1> <span class="mw-headline">
|
||
A Recommended Base Configuration </span></h1>
|
||
<p>The following is a recommended configuration file which handles the
|
||
main ModSecurity directives/setting. These are the items that the Admin
|
||
should handle and configure for their own site. These settings should
|
||
not be including within 3rd party rules files.
|
||
</p>
|
||
<pre># -- Rule engine initialization ----------------------------------------------
|
||
|
||
# Enable ModSecurity, attaching it to every transaction. Use detection
|
||
# only to start with, because that minimises the chances of post-installation
|
||
# disruption.
|
||
#
|
||
SecRuleEngine DetectionOnly
|
||
|
||
|
||
# -- Request body handling ---------------------------------------------------
|
||
|
||
# Allow ModSecurity to access request bodies. If you don't, ModSecurity
|
||
# won't be able to see any POST parameters, which opens a large security
|
||
# hole for attackers to exploit.
|
||
#
|
||
SecRequestBodyAccess On
|
||
|
||
|
||
# Enable XML request body parser.
|
||
# Initiate XML Processor in case of xml content-type
|
||
#
|
||
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
|
||
"phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
|
||
|
||
|
||
# Maximum request body size we will accept for buffering. If you support
|
||
# file uploads then the value given on the first line has to be as large
|
||
# as the largest file you are willing to accept. The second value refers
|
||
# to the size of data, with files excluded. You want to keep that value as
|
||
# low as practical.
|
||
#
|
||
SecRequestBodyLimit 13107200
|
||
SecRequestBodyNoFilesLimit 131072
|
||
|
||
# Store up to 128 KB of request body data in memory. When the multipart
|
||
# parser reachers this limit, it will start using your hard disk for
|
||
# storage. That is slow, but unavoidable.
|
||
#
|
||
SecRequestBodyInMemoryLimit 131072
|
||
|
||
# What do do if the request body size is above our configured limit.
|
||
# Keep in mind that this setting will automatically be set to ProcessPartial
|
||
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
|
||
# disruptions when initially deploying ModSecurity.
|
||
#
|
||
SecRequestBodyLimitAction Reject
|
||
|
||
# Verify that we've correctly processed the request body.
|
||
# As a rule of thumb, when failing to process a request body
|
||
# you should reject the request (when deployed in blocking mode)
|
||
# or log a high-severity alert (when deployed in detection-only mode).
|
||
#
|
||
SecRule REQBODY_ERROR "!@eq 0" \
|
||
"phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
|
||
|
||
# By default be strict with what we accept in the multipart/form-data
|
||
# request body. If the rule below proves to be too strict for your
|
||
# environment consider changing it to detection-only. You are encouraged
|
||
# _not_ to remove it altogether.
|
||
#
|
||
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
|
||
"phase:2,t:none,log,deny,status:44,msg:'Multipart request body \
|
||
failed strict validation: \
|
||
PE %{REQBODY_PROCESSOR_ERROR}, \
|
||
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
|
||
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
|
||
DB %{MULTIPART_DATA_BEFORE}, \
|
||
DA %{MULTIPART_DATA_AFTER}, \
|
||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||
LF %{MULTIPART_LF_LINE}, \
|
||
SM %{MULTIPART_SEMICOLON_MISSING}, \
|
||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||
IH %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||
|
||
# Did we see anything that might be a boundary?
|
||
#
|
||
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
|
||
"phase:2,t:none,log,deny,status:44,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||
|
||
# PCRE Tuning
|
||
# We want to avoid a potential RegEx DoS condition
|
||
#
|
||
SecPcreMatchLimit 1000
|
||
SecPcreMatchLimitRecursion 1000
|
||
|
||
# Some internal errors will set flags in TX and we will need to look for these.
|
||
# All of these are prefixed with "MSC_". The following flags currently exist:
|
||
#
|
||
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
|
||
#
|
||
SecRule TX:/^MSC_/ "!@streq 0" \
|
||
"phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
|
||
|
||
|
||
# -- Response body handling --------------------------------------------------
|
||
|
||
# Allow ModSecurity to access response bodies.
|
||
# You should have this directive enabled in order to identify errors
|
||
# and data leakage issues.
|
||
#
|
||
# Do keep in mind that enabling this directive does increases both
|
||
# memory consumption and response latency.
|
||
#
|
||
SecResponseBodyAccess On
|
||
|
||
# Which response MIME types do you want to inspect? You should adjust the
|
||
# configuration below to catch documents but avoid static files
|
||
# (e.g., images and archives).
|
||
#
|
||
SecResponseBodyMimeType text/plain text/html text/xml
|
||
|
||
# Buffer response bodies of up to 512 KB in length.
|
||
SecResponseBodyLimit 524288
|
||
|
||
# What happens when we encounter a response body larger than the configured
|
||
# limit? By default, we process what we have and let the rest through.
|
||
# That's somewhat less secure, but does not break any legitimate pages.
|
||
#
|
||
SecResponseBodyLimitAction ProcessPartial
|
||
|
||
|
||
# -- Filesystem configuration ------------------------------------------------
|
||
|
||
# The location where ModSecurity stores temporary files (for example, when
|
||
# it needs to handle a file upload that is larger than the configured limit).
|
||
#
|
||
# This default setting is chosen due to all systems have /tmp available however,
|
||
# this is less than ideal. It is recommended that you specify a location that's private.
|
||
#
|
||
SecTmpDir /tmp/
|
||
|
||
# The location where ModSecurity will keep its persistent data. This default setting
|
||
# is chosen due to all systems have /tmp available however, it
|
||
# too should be updated to a place that other users can't access.
|
||
#
|
||
SecDataDir /tmp/
|
||
|
||
|
||
# -- File uploads handling configuration -------------------------------------
|
||
|
||
# The location where ModSecurity stores intercepted uploaded files. This
|
||
# location must be private to ModSecurity. You don't want other users on
|
||
# the server to access the files, do you?
|
||
#
|
||
#SecUploadDir /opt/modsecurity/var/upload/
|
||
|
||
# By default, only keep the files that were determined to be unusual
|
||
# in some way (by an external inspection script). For this to work you
|
||
# will also need at least one file inspection rule.
|
||
#
|
||
#SecUploadKeepFiles RelevantOnly
|
||
|
||
# Uploaded files are by default created with permissions that do not allow
|
||
# any other user to access them. You may need to relax that if you want to
|
||
# interface ModSecurity to an external program (e.g., an anti-virus).
|
||
#
|
||
#SecUploadFileMode 0600
|
||
|
||
|
||
# -- Debug log configuration -------------------------------------------------
|
||
|
||
# The default debug log configuration is to duplicate the error, warning
|
||
# and notice messages from the error log.
|
||
#
|
||
#SecDebugLog /opt/modsecurity/var/log/debug.log
|
||
#SecDebugLogLevel 3
|
||
|
||
|
||
# -- Audit log configuration -------------------------------------------------
|
||
|
||
# Log the transactions that are marked by a rule, as well as those that
|
||
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
|
||
# level response status codes).
|
||
#
|
||
SecAuditEngine RelevantOnly
|
||
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
|
||
|
||
# Log everything we know about a transaction.
|
||
SecAuditLogParts ABIJDEFHKZ
|
||
|
||
# Use a single file for logging. This is much easier to look at, but
|
||
# assumes that you will use the audit log only ocassionally.
|
||
#
|
||
SecAuditLogType Serial
|
||
SecAuditLog /var/log/modsec_audit.log
|
||
|
||
# Specify the path for concurrent audit logging.
|
||
#SecAuditLogStorageDir /opt/modsecurity/var/audit/
|
||
|
||
|
||
# -- Miscellaneous -----------------------------------------------------------
|
||
|
||
# Use the most commonly used application/x-www-form-urlencoded parameter
|
||
# separator. There's probably only one application somewhere that uses
|
||
# something else so don't expect to change this value.
|
||
#
|
||
SecArgumentSeparator &
|
||
|
||
# Settle on version 0 (zero) cookies, as that is what most applications
|
||
# use. Using an incorrect cookie version may open your installation to
|
||
# evasion attacks (against the rules that examine named cookies).
|
||
#
|
||
SecCookieFormat 0
|
||
</pre>
|
||
|
||
<!--
|
||
NewPP limit report
|
||
Preprocessor node count: 801/1000000
|
||
Post-expand include size: 0/2097152 bytes
|
||
Template argument size: 0/2097152 bytes
|
||
Expensive parser function count: 0/100
|
||
-->
|
||
|
||
<!-- Saved in parser cache with key p_mod-security_mediawiki:pcache:idhash:12-0!1!0!!en!2!edit=0!printable=1 and timestamp 20120606075807 -->
|
||
<div class="printfooter">
|
||
Retrieved from "<a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual">http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual</a>"</div>
|
||
<!-- end content -->
|
||
<div class="visualClear"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="column-one">
|
||
<div id="p-cactions" class="portlet">
|
||
<h5>Views</h5>
|
||
<div class="pBody">
|
||
<ul>
|
||
|
||
<li id="ca-nstab-main" class="selected"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual"
|
||
title="View the content page [alt-shift-c]" accesskey="c">Page</a></li>
|
||
<li id="ca-talk" class="new"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Talk:Reference_Manual&action=edit&redlink=1"
|
||
title="Discussion about the content page [alt-shift-t]" accesskey="t">Discussion</a></li>
|
||
<li id="ca-viewsource"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual&action=edit"
|
||
title="This page is protected.
|
||
You can view its source [alt-shift-e]" accesskey="e">View source</a></li>
|
||
<li id="ca-history"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual&action=history"
|
||
title="Past revisions of this page [alt-shift-h]" accesskey="h">History</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="portlet" id="p-personal">
|
||
<h5>Personal tools</h5>
|
||
<div class="pBody">
|
||
<table style="height: 4px;" rules="none" border="0" cellpadding="0"
|
||
cellspacing="0"></table>
|
||
<ul>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div class="portlet" id="p-logo">
|
||
<a style="background-image:
|
||
url("/apps/mediawiki/mod-security/nfs/project/m/mo/mod-security/7/70/MediaWikiSidebarLogo.png");"
|
||
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Main_Page"
|
||
title="Visit the main page [alt-shift-z]" accesskey="z"></a>
|
||
</div>
|
||
<script type="text/javascript"> if (window.isMSIE55) fixalpha(); </script>
|
||
<div class="generated-sidebar portlet" id="p-navigation">
|
||
<h5>Navigation</h5>
|
||
<div class="pBody">
|
||
<ul>
|
||
<li id="n-mainpage-description"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Main_Page">Main
|
||
Page</a></li>
|
||
<li id="n-portal"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=mod-security:Community_Portal"
|
||
title="About the project, what you can do, where to find things">Community
|
||
portal</a></li>
|
||
<li id="n-currentevents"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=mod-security:Current_events"
|
||
title="Find background information on current events">Current events</a></li>
|
||
<li id="n-recentchanges"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:RecentChanges"
|
||
title="The list of recent changes in the wiki [alt-shift-r]"
|
||
accesskey="r">Recent changes</a></li>
|
||
<li id="n-randompage"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:Random"
|
||
title="Load a random page [alt-shift-x]" accesskey="x">Random page</a></li>
|
||
<li id="n-help"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Help:Contents"
|
||
title="The place to find out">Help</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="p-search" class="portlet">
|
||
<h5><label for="searchInput">Search</label></h5>
|
||
<div id="searchBody" class="pBody">
|
||
<form action="/apps/mediawiki/mod-security/index.php" id="searchform"><div>
|
||
<input name="title" value="Special:Search" type="hidden">
|
||
<input id="searchInput" name="search" title="Search mod-security
|
||
[alt-shift-f]" accesskey="f" type="text">
|
||
<input name="go" class="searchButton" id="searchGoButton" value="Go"
|
||
title="Go to a page with this exact name if exists" type="submit">
|
||
|
||
<input name="fulltext" class="searchButton" id="mw-searchButton"
|
||
value="Search" title="Search the pages for this text" type="submit">
|
||
</div></form>
|
||
</div>
|
||
</div>
|
||
<div class="portlet" id="p-tb">
|
||
<h5>Toolbox</h5>
|
||
<div class="pBody">
|
||
<ul>
|
||
<li id="t-whatlinkshere"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:WhatLinksHere/Reference_Manual"
|
||
title="List of all wiki pages that link here [alt-shift-j]"
|
||
accesskey="j">What links here</a></li>
|
||
<li id="t-recentchangeslinked"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:RecentChangesLinked/Reference_Manual"
|
||
title="Recent changes in pages linked from this page [alt-shift-k]"
|
||
accesskey="k">Related changes</a></li>
|
||
<li id="t-specialpages"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Special:SpecialPages"
|
||
title="List of all special pages [alt-shift-q]" accesskey="q">Special
|
||
pages</a></li>
|
||
<li id="t-print"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual&printable=yes&printable=yes"
|
||
rel="alternate" title="Printable version of this page [alt-shift-p]"
|
||
accesskey="p">Printable version</a></li> <li id="t-permalink"><a
|
||
href="http://sourceforge.net/apps/mediawiki/mod-security/index.php?title=Reference_Manual&oldid=500"
|
||
title="Permanent link to this revision of the page">Permanent link</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div><!-- end of the left (by default at least) column -->
|
||
<div class="visualClear"></div>
|
||
<div id="footer">
|
||
<div id="f-poweredbyico"><a href="http://www.mediawiki.org/"><img
|
||
src="Reference_Manual_files/poweredby_mediawiki_88x31.png" alt="Powered
|
||
by MediaWiki"></a></div>
|
||
<ul id="f-list">
|
||
<li id="lastmod"> This page was last modified on 5 June 2012, at
|
||
18:32.</li>
|
||
<li id="viewcount">This page has been accessed 130,057 times.</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/javascript">if (window.runOnloadHook) runOnloadHook();</script>
|
||
<!-- Served in 0.178 secs. -->
|
||
|
||
|
||
<script type="text/javascript">
|
||
pageTracker._trackPageview();
|
||
</script>
|
||
</body></html> |