ModSecurity/apache2/t/regression/config/10-request-directives.t
2008-09-10 19:45:13 +00:00

549 lines
13 KiB
Perl

### Tests for directives altering how a request is handled
# SecArgumentSeparator
{
type => "config",
comment => "SecArgumentSeparator (get-pos)",
conf => q(
SecRuleEngine On
SecArgumentSeparator ";"
SecRule ARGS:a "@streq 1" "phase:1,deny,chain"
SecRule ARGS:b "@streq 2"
),
match_log => {
error => [ qr/Access denied with code 403 \(phase 1\)\. String match "2" at ARGS:b\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?a=1;b=2",
),
},
{
type => "config",
comment => "SecArgumentSeparator (get-neg)",
conf => q(
SecRuleEngine On
SecRule ARGS:a "@streq 1" "phase:1,deny,chain"
SecRule ARGS:b "@streq 2"
),
match_log => {
-error => [ qr/Access denied/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?a=1;b=2",
),
},
{
type => "config",
comment => "SecArgumentSeparator (post-pos)",
conf => q(
SecRuleEngine On
SecRequestBodyAccess On
SecArgumentSeparator ";"
SecRule ARGS:a "@streq 1" "phase:2,deny,chain"
SecRule ARGS:b "@streq 2"
),
match_log => {
error => [ qr/Access denied with code 403 \(phase 2\)\. String match "2" at ARGS:b\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1;b=2",
),
},
{
type => "config",
comment => "SecArgumentSeparator (post-neg)",
conf => q(
SecRuleEngine On
SecRequestBodyAccess On
SecRule ARGS:a "@streq 1" "phase:2,deny"
SecRule ARGS:b "@streq 2" "phase:2,deny"
),
match_log => {
-error => [ qr/Access denied/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1;b=2",
),
},
# SecRequestBodyAccess
{
type => "config",
comment => "SecRequestBodyAccess (pos)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRule ARGS:a "\@streq 1" "phase:2,deny,chain"
SecRule ARGS:b "\@streq 2"
),
match_log => {
error => [ qr/Access denied with code 403 \(phase 2\)\. String match "2" at ARGS:b\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
{
type => "config",
comment => "SecRequestBodyAccess (neg)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess Off
SecRule ARGS:a "\@streq 1" "phase:2,deny"
SecRule ARGS:b "\@streq 2" "phase:2,deny"
),
match_log => {
-error => [ qr/Access denied/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
# SecRequestBodyLimit
{
type => "config",
comment => "SecRequestBodyLimit (equal)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 7
),
match_log => {
-error => [ qr/Request body is larger than the configured limit/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
{
type => "config",
comment => "SecRequestBodyLimit (greater)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 5
),
match_log => {
error => [ qr/Request body .*is larger than the configured limit \(5\)\./, 1 ],
},
match_response => {
status => qr/^413$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
{
type => "config",
comment => "SecRequestBodyLimit (equal - chunked)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 276
),
match_log => {
-error => [ qr/Request body is larger than the configured limit/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
{
type => "config",
comment => "SecRequestBodyLimit (greater - chunked)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 256
),
match_log => {
error => [ qr/Request body .*is larger than the configured limit \(256\)\./, 1 ],
},
match_response => {
status => qr/^413$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
{
type => "config",
comment => "SecRequestBodyLimit (ctl:ruleEngine=off)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 5
SecAction "phase:1,pass,nolog,ctl:ruleEngine=off"
SecRule REQUEST_BODY "." "phase:2,deny"
),
match_log => {
-error => [ qr/Request body .*is larger than the configured limit/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
{
type => "config",
comment => "SecRequestBodyLimit (ctl:requestBodyAccess=off)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 5
SecAction "phase:1,pass,nolog,ctl:requestBodyAccess=off"
SecRule REQUEST_BODY "." "phase:2,deny"
),
match_log => {
-error => [ qr/Request body .*is larger than the configured limit/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
"a=1&b=2",
),
},
{
type => "config",
comment => "SecRequestBodyLimit (ctl:ruleEngine=off - chunked)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 256
SecAction "phase:1,pass,nolog,ctl:ruleEngine=off"
SecRule REQUEST_BODY "." "phase:2,deny"
),
match_log => {
-error => [ qr/Request body .*is larger than the configured limit/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
{
type => "config",
comment => "SecRequestBodyLimit (ctl:requestBodyAccess=off - chunked)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 256
SecAction "phase:1,pass,nolog,ctl:requestBodyAccess=off"
SecRule REQUEST_BODY "." "phase:2,deny"
),
match_log => {
-error => [ qr/Request body .*is larger than the configured limit \(256\)\./, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
# SecRequestBodyInMemoryLimit
{
type => "config",
comment => "SecRequestBodyInMemoryLimit (equal)",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9
SecRequestBodyAccess On
SecRequestBodyLimit 1000
SecRequestBodyInMemoryLimit 276
),
match_log => {
-debug => [ qr/Input filter: Request too large to store in memory, switching to disk\./, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
{
type => "config",
comment => "SecRequestBodyInMemoryLimit (greater)",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9
SecRequestBodyAccess On
SecRequestBodyLimit 1000
SecRequestBodyInMemoryLimit 16
),
match_log => {
debug => [ qr/Input filter: Request too large to store in memory, switching to disk\./, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => normalize_raw_request_data(
qq(
POST /test.txt HTTP/1.1
Host: $ENV{SERVER_NAME}:$ENV{SERVER_PORT}
User-Agent: $ENV{USER_AGENT}
Content-Type: multipart/form-data; boundary=---------------------------69343412719991675451336310646
Transfer-Encoding: chunked
),
)
.encode_chunked(
normalize_raw_request_data(
q(
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="a"
1
-----------------------------69343412719991675451336310646
Content-Disposition: form-data; name="b"
2
-----------------------------69343412719991675451336310646--
)
),
1024
),
},
# SecCookieFormat
{
type => "config",
comment => "SecCookieFormat (pos)",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 5
SecCookieFormat 1
SecRule REQUEST_COOKIES_NAMES "\@streq SESSIONID" "phase:1,deny,chain"
SecRule REQUEST_COOKIES:\$SESSIONID_PATH "\@streq /" "chain"
SecRule REQUEST_COOKIES:SESSIONID "\@streq cookieval"
),
match_log => {
error => [ qr/Access denied with code 403 \(phase 1\)\. String match "cookieval" at REQUEST_COOKIES:SESSIONID\./, 1 ],
debug => [ qr(Adding request cookie: name "\$SESSIONID_PATH", value "/"), 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Cookie" => q($Version="1"; SESSIONID="cookieval"; $PATH="/"),
],
undef,
),
},
{
type => "config",
comment => "SecCookieFormat (neg)",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 5
SecCookieFormat 0
SecRule REQUEST_COOKIES_NAMES "\@streq SESSIONID" "phase:1,deny,chain"
SecRule REQUEST_COOKIES:\$SESSIONID_PATH "\@streq /" "chain"
SecRule REQUEST_COOKIES:SESSIONID "\@streq cookieval"
),
match_log => {
-error => [ qr/Access denied/, 1 ],
-debug => [ qr(Adding request cookie: name "\$SESSIONID_PATH", value "/"), 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Cookie" => q($Version="1"; SESSIONID="cookieval"; $PATH="/"),
],
undef,
),
},