Skip to content

Tests: added configuration merge tests #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 235 additions & 0 deletions tests/modsecurity-config-merge.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#!/usr/bin/perl

# (C) Andrei Belov

# Tests for ModSecurity-nginx connector (configuration merge).

###############################################################################

use warnings;
use strict;

use Test::More;
use Socket qw/ CRLF /;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http proxy/);

$t->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
%%TEST_GLOBALS_HTTP%%

modsecurity on;
modsecurity_rules '
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 128
SecRequestBodyLimitAction Reject
SecRule REQUEST_BODY "@rx BAD BODY" "id:11,phase:request,deny,log,status:403"
';

server {
listen 127.0.0.1:%%PORT_8080%%;
server_name localhost;

location / {
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}

location /modsec-disabled {
modsecurity_rules '
SecRuleEngine Off
';
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}

location /nobodyaccess {
modsecurity_rules '
SecRequestBodyAccess Off
';
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}

location /bodylimitprocesspartial {
modsecurity_rules '
SecRequestBodyLimitAction ProcessPartial
';
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}

location /bodylimitincreased {
modsecurity_rules '
SecRequestBodyLimit 512
';
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}

location /server {
modsecurity off;

location /server/modsec-disabled {
proxy_pass http://127.0.0.1:%%PORT_8082%%;
}

location /server/nobodyaccess {
proxy_pass http://127.0.0.1:%%PORT_8083%%;
}

location /server/bodylimitprocesspartial {
proxy_pass http://127.0.0.1:%%PORT_8084%%;
}

location /server/bodylimitincreased {
proxy_pass http://127.0.0.1:%%PORT_8085%%;
}
}
}

server {
listen 127.0.0.1:%%PORT_8082%%;

modsecurity_rules '
SecRuleEngine Off
';

location / {
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}
}

server {
listen 127.0.0.1:%%PORT_8083%%;

modsecurity_rules '
SecRequestBodyAccess Off
';

location / {
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}
}

server {
listen 127.0.0.1:%%PORT_8084%%;

modsecurity_rules '
SecRequestBodyLimitAction ProcessPartial
';

location / {
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}
}

server {
listen 127.0.0.1:%%PORT_8085%%;

modsecurity_rules '
SecRequestBodyLimit 512
';

location / {
proxy_pass http://127.0.0.1:%%PORT_8081%%;
}
}
}
EOF

$t->run_daemon(\&http_daemon);
$t->run()->waitforsocket('127.0.0.1:' . port(8081));

$t->plan(10);

###############################################################################

like(http_get_body('/', 'GOOD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "http level defaults, pass");
like(http_get_body('/', 'VERY BAD BODY'), qr/403 Forbidden/, "http level defaults, block");

TODO: {
local $TODO = 'not yet, see https://github.com/SpiderLabs/ModSecurity/pull/1990';

like(http_get_body('/modsec-disabled', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRuleEngine, pass");
like(http_get_body('/nobodyaccess', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyAccess, pass");
like(http_get_body('/bodylimitprocesspartial', 'BODY' x 33), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyLimitAction, pass");
like(http_get_body('/bodylimitincreased', 'BODY' x 64), qr/TEST-OK-IF-YOU-SEE-THIS/, "location override for SecRequestBodyLimit, pass");

like(http_get_body('/server/modsec-disabled', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRuleEngine, pass");
like(http_get_body('/server/nobodyaccess', 'VERY BAD BODY'), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyAccess, pass");
like(http_get_body('/server/bodylimitprocesspartial', 'BODY' x 33), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyLimitAction, pass");
like(http_get_body('/server/bodylimitincreased', 'BODY' x 64), qr/TEST-OK-IF-YOU-SEE-THIS/, "server override for SecRequestBodyLimit, pass");
}

###############################################################################

sub http_daemon {
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalHost => '127.0.0.1:' . port(8081),
Listen => 5,
Reuse => 1
)
or die "Can't create listening socket: $!\n";

local $SIG{PIPE} = 'IGNORE';

while (my $client = $server->accept()) {
$client->autoflush(1);

my $headers = '';
my $uri = '';

while (<$client>) {
$headers .= $_;
last if (/^\x0d?\x0a?$/);
}

$uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;

print $client <<'EOF';
HTTP/1.1 200 OK
Connection: close

EOF
print $client "TEST-OK-IF-YOU-SEE-THIS"
unless $headers =~ /^HEAD/i;

close $client;
}
}

sub http_get_body {
my $uri = shift;
my $last = pop;
return http( join '', (map {
my $body = $_;
"GET $uri HTTP/1.1" . CRLF
. "Host: localhost" . CRLF
. "Content-Length: " . (length $body) . CRLF . CRLF
. $body
} @_),
"GET $uri HTTP/1.1" . CRLF
. "Host: localhost" . CRLF
. "Connection: close" . CRLF
. "Content-Length: " . (length $last) . CRLF . CRLF
. $last
);
}

###############################################################################