mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Redo build system to properly use autotools and avoid compilation with apxs util.
This commit is contained in:
91
tests/regression/rule/00-basics.t
Normal file
91
tests/regression/rule/00-basics.t
Normal file
@@ -0,0 +1,91 @@
|
||||
### Tests for basic rule components
|
||||
|
||||
# SecAction
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecAction (override default)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 4
|
||||
SecAction "nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
||||
# SecRule
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRule (no action)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 5
|
||||
SecDefaultAction "phase:2,deny,status:403"
|
||||
SecRule ARGS:test "value"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: /, 1 ],
|
||||
debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,deny,status:403"$/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRule (action)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 5
|
||||
SecDefaultAction "phase:2,pass"
|
||||
SecRule ARGS:test "value" "deny,status:403"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: /, 1 ],
|
||||
debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,deny,status:403"$/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRule (chain)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 5
|
||||
SecDefaultAction "phase:2,log,noauditlog,pass,tag:foo"
|
||||
SecRule ARGS:test "value" "chain,phase:2,deny,status:403"
|
||||
SecRule &ARGS "\@eq 1" "chain,setenv:tx.foo=bar"
|
||||
SecRule REQUEST_METHOD "\@streq GET"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: /, 1 ],
|
||||
debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,log,noauditlog,tag:foo,chain,deny,status:403"\r?\n.*Rule [0-9a-f]+: SecRule "&ARGS" "\@eq 1" "chain,setenv:tx.foo=bar"\r?\n.*Rule [0-9a-f]+: SecRule "REQUEST_METHOD" "\@streq GET"\r?\n/s, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value",
|
||||
),
|
||||
},
|
4
tests/regression/rule/00-inheritance.t
Normal file
4
tests/regression/rule/00-inheritance.t
Normal file
@@ -0,0 +1,4 @@
|
||||
### Tests for rule inheritance
|
||||
|
||||
### TODO:
|
||||
# SecRuleInheritance
|
63
tests/regression/rule/00-script.t
Normal file
63
tests/regression/rule/00-script.t
Normal file
@@ -0,0 +1,63 @@
|
||||
### Test for SecRuleScript
|
||||
|
||||
# Lua
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleScript (lua absolute nomatch)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 1
|
||||
SecRuleScript "$ENV{CONF_DIR}/test.lua" "phase:2,deny"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/Lua script matched\./, 1 ],
|
||||
debug => [ qr/Test message\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleScript (lua relative nomatch)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 1
|
||||
SecRuleScript "test.lua" "phase:2,deny"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/Lua script matched\./, 1 ],
|
||||
debug => [ qr/Test message\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleScript (lua relative match)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 1
|
||||
SecRuleScript "match.lua" "phase:2,deny"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 2\)\. Lua script matched\./, 1 ],
|
||||
debug => [ qr/Test message\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
419
tests/regression/rule/10-xml.t
Normal file
419
tests/regression/rule/10-xml.t
Normal file
@@ -0,0 +1,419 @@
|
||||
### Test for XML operator rules
|
||||
|
||||
### Validate Scheme
|
||||
# OK
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateSchema (validate ok)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Successfully validated payload against Schema/s, 1 ],
|
||||
-debug => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
|
||||
-error => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
|
||||
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<q1:getInput xmlns:q1="http://DefaultNamespace">
|
||||
<id xsi:type="xsd:string">12123</id>
|
||||
</q1:getInput>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Failed attribute value
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateSchema (validate attribute value failed)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" \\
|
||||
"phase:2,deny,log,auditlog,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*'badval' is not a valid value of the local atomic type.*Schema validation failed/s, 1 ],
|
||||
-debug => [ qr/Successfully validated payload against Schema|\n\r?\n/, 1 ],
|
||||
audit => [ qr/^Message: Element.*'badval' is not a valid value of the local atomic type\.\nMessage:/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
|
||||
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:mustUnderstand="badval" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<q1:getInput xmlns:q1="http://DefaultNamespace">
|
||||
<id xsi:type="xsd:string">12123</id>
|
||||
</q1:getInput>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Failed validation
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateSchema (validate failed)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*element is not expected/s, 1 ],
|
||||
-debug => [ qr/XML parser error|Failed to load/, 1 ],
|
||||
-error => [ qr/XML parser error|Failed to load/, 1 ],
|
||||
audit => [ qr/^Message: Element.*This element is not expected.*\nMessage:/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
|
||||
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:xBody soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<q1:getInput xmlns:q1="http://DefaultNamespace">
|
||||
<id xsi:type="xsd:string">12123</id>
|
||||
</q1:getInput>
|
||||
</soap:xBody>
|
||||
</soap:Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Bad XML
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateSchema (bad XML)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ],
|
||||
-debug => [ qr/Failed to load|Successfully validated/, 1 ],
|
||||
-error => [ qr/Failed to load|Successfully validated/, 1 ],
|
||||
audit => [ qr/^Message: .*Failed parsing document.*\nMessage:/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelop xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
|
||||
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<q1:getInput xmlns:q1="http://DefaultNamespace">
|
||||
<id xsi:type="xsd:string">12123</id>
|
||||
</q1:getInput>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Bad schema
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateSchema (bad schema)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope-bad.xsd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Failed to parse the XML resource.*Failed to load Schema/s, 1 ],
|
||||
audit => [ qr/^Message: .*Failed to parse the XML resource.*\nMessage: Rule processing failed/m, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
|
||||
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<q1:getInput xmlns:q1="http://DefaultNamespace">
|
||||
<id xsi:type="xsd:string">12123</id>
|
||||
</q1:getInput>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
|
||||
# Validate DTD
|
||||
# OK
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateDTD (validate ok)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Successfully validated payload against DTD/s, 1 ],
|
||||
-debug => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
|
||||
-error => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
|
||||
<Envelope>
|
||||
<Body>
|
||||
<getInput>
|
||||
<id type="string">12123</id>
|
||||
</getInput>
|
||||
</Body>
|
||||
</Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Failed validation
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateDTD (validate failed)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*content does not follow the DTD/s, 1 ],
|
||||
-debug => [ qr/XML parser error|Failed to load/, 1 ],
|
||||
-error => [ qr/XML parser error|Failed to load/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
|
||||
<Envelope>
|
||||
<xBody>
|
||||
<getInput>
|
||||
<id type="string">12123</id>
|
||||
</getInput>
|
||||
</xBody>
|
||||
</Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Bad XML
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateDTD (bad XML)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ],
|
||||
-debug => [ qr/Failed to load|Successfully validated/, 1 ],
|
||||
-error => [ qr/Failed to load|Successfully validated/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
|
||||
<Envelop>
|
||||
<Body>
|
||||
<getInput>
|
||||
<id type="string">12123</id>
|
||||
</getInput>
|
||||
</Body>
|
||||
</Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
# Bad DTD
|
||||
{
|
||||
type => "rule",
|
||||
comment => "validateDTD (bad DTD)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
|
||||
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
|
||||
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
|
||||
SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope-bad.dtd" \\
|
||||
"phase:2,deny,id:12345"
|
||||
),
|
||||
match_log => {
|
||||
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Failed to load DTD/s, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
[
|
||||
"Content-Type" => "text/xml",
|
||||
],
|
||||
normalize_raw_request_data(
|
||||
q(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
|
||||
<Envelope>
|
||||
<Body>
|
||||
<getInput>
|
||||
<id type="string">12123</id>
|
||||
</getInput>
|
||||
</Body>
|
||||
</Envelope>
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
176
tests/regression/rule/20-exceptions.t
Normal file
176
tests/regression/rule/20-exceptions.t
Normal file
@@ -0,0 +1,176 @@
|
||||
### Tests for rule exceptions
|
||||
|
||||
# SecRuleRemoveById
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleRemoveById (single)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1"
|
||||
SecRuleRemoveById 1
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Starting phase REQUEST_HEADERS\..*This phase consists of 0 rule.*Starting phase RESPONSE_HEADERS\./s, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleRemoveById (multiple)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:2"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:3"
|
||||
SecRuleRemoveById 1 2 3
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Starting phase REQUEST_HEADERS\..*This phase consists of 0 rule.*Starting phase RESPONSE_HEADERS\./s, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleRemoveById (range)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:2"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:3"
|
||||
SecRuleRemoveById 1-3
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Starting phase REQUEST_HEADERS\..*This phase consists of 0 rule.*Starting phase RESPONSE_HEADERS\./s, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleRemoveById (multiple + range)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:2"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:3"
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:4"
|
||||
SecRuleRemoveById 1 2-4
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Starting phase REQUEST_HEADERS\..*This phase consists of 0 rule.*Starting phase RESPONSE_HEADERS\./s, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
||||
# SecRuleRemoveByMsg
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleRemoveByMsg",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1,msg:'testing rule'"
|
||||
SecRuleRemoveByMsg "testing rule"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/Starting phase REQUEST_HEADERS\..*This phase consists of 0 rule.*Starting phase RESPONSE_HEADERS\./s, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
||||
# SecRuleUpdateActionById
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleUpdateActionById",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1,msg:'testing rule'"
|
||||
SecRuleUpdateActionById 1 "pass,nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/id:1,.*,pass,nolog/, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleUpdateActionById (chain)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1,msg:'testing rule',chain"
|
||||
SecRule ARGS "bar"
|
||||
SecRuleUpdateActionById 1 "pass,nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
debug => [ qr/id:1,.*,pass,nolog/, 1 ],
|
||||
-debug => [ qr/Access denied/, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?foo=bar",
|
||||
),
|
||||
},
|
Reference in New Issue
Block a user