Skip to content
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

Enable audit log and add 00-phases tests #70

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
ACLOCAL_AMFLAGS = -I build

postamb = "modsecurity_rules \"SecAuditEngine On\""

MAINTAINERCLEANFILES = \
config.log \
Makefile.in \
Expand Down Expand Up @@ -39,7 +41,7 @@ all:
test:
cd t/ && ./TEST -clean
cd t/ && ./TEST -configure
cd t/ && ./TEST -httpd_conf conf/httpd.conf -httpd @APACHE@ -apxs @APXS@
cd t/ && ./TEST -httpd_conf conf/httpd.conf -httpd @APACHE@ -apxs @APXS@ -postamble $(postamb)


install-exec-hook: $(pkglib_LTLIBRARIES)
Expand Down
132 changes: 132 additions & 0 deletions t/00-phases.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@

use strict;
use Apache::Test;
use Apache::TestRequest;

require "t/find_string_in_file.pl";

plan tests => 5, have_lwp;

my $audit_log = Apache::Test::config()->{vars}->{t_logs} . "/audit_logs.txt";

###############################################################################
# Test phases
# phase 1 (request headers)
###############################################################################
{
# Remember position in audit log file before our test
my $audit_log_start_size = -s $audit_log or die "Failed to access file: " . $audit_log;

my $url = "/00-phases/00-phases_01.html";
my $ct_header_name = "Content-Type";
my $ct_header_val = "application/x-www-form-urlencoded";
my $content = "arg1=val1&arg2=val2";
my $res1 = POST $url, $ct_header_name => $ct_header_val, content => $content;

# Expected results
my $status_code_expected = 200;
my $audit_log_expected = 'Matched "Operator \`Rx\' with parameter \`\^POST\' against variable \`REQUEST_LINE';
my $audit_log_missing = 'Matched [\s\S]*(ARGS|RESPONSE)';

my $audit_found_expected = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_expected);
my $audit_found_missing = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_missing);

ok (($res1->code == $status_code_expected) && ($audit_found_expected) && (not $audit_found_missing));
}

###############################################################################
# Test phases
# phase 2 (request body)
###############################################################################
{
# Remember position in audit log file before our test
my $audit_log_start_size = -s $audit_log or die "Failed to access file: " . $audit_log;

my $url = "/00-phases/00-phases_02.html";
my $ct_header_name = "Content-Type";
my $ct_header_val = "application/x-www-form-urlencoded";
my $content = "arg1=val1&arg2=val2";
my $res1 = POST $url, $ct_header_name => $ct_header_val, content => $content;

# Expected results
my $status_code_expected = 200;
my $audit_log_expected = 'Matched "Operator \`Rx\' with parameter \`\^POST\' against variable \`REQUEST_LINE[\s\S]*Matched "Operator \`Rx\' with parameter \`val1\' against variable \`ARGS';
my $audit_log_missing = 'Matched [\s\S]*RESPONSE';

my $audit_found_expected = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_expected);
my $audit_found_missing = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_missing);

ok (($res1->code == $status_code_expected) && ($audit_found_expected) && (not $audit_found_missing));
}

###############################################################################
# Test phases
# phase 3 (response headers)
###############################################################################
{
# Remember position in audit log file before our test
my $audit_log_start_size = -s $audit_log or die "Failed to access file: " . $audit_log;

my $url = "/00-phases/00-phases_03.html";
my $ct_header_name = "Content-Type";
my $ct_header_val = "application/x-www-form-urlencoded";
my $content = "arg1=val1&arg2=val2";
my $res1 = POST $url, $ct_header_name => $ct_header_val, content => $content;

# Expected results
my $status_code_expected = 200;
my $audit_log_expected = 'Matched "Operator \`Rx\' with parameter \`\^POST\' against variable \`REQUEST_LINE[\s\S]*Matched "Operator \`Rx\' with parameter \`val1\' against variable \`ARGS[\s\S]*Matched "Operator \`Rx\' with parameter \`.\' against variable \`RESPONSE_HEADERS';
my $audit_log_missing = 'Matched [\s\S]*RESPONSE_BODY';

my $audit_found_expected = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_expected);
my $audit_found_missing = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_missing);

ok (($res1->code == $status_code_expected) && ($audit_found_expected) && (not $audit_found_missing));
}

###############################################################################
# Test phases
# phase 4 (response body)
###############################################################################
{
# Remember position in audit log file before our test
my $audit_log_start_size = -s $audit_log or die "Failed to access file: " . $audit_log;

my $url = "/00-phases/00-phases_04.html";
my $ct_header_name = "Content-Type";
my $ct_header_val = "application/x-www-form-urlencoded";
my $content = "arg1=val1&arg2=val2";
my $res1 = POST $url, $ct_header_name => $ct_header_val, content => $content;

# Expected results
my $status_code_expected = 200;
my $audit_log_expected = 'Matched "Operator \`Rx\' with parameter \`\^POST\' against variable \`REQUEST_LINE[\s\S]*Matched "Operator \`Rx\' with parameter \`val1\' against variable \`ARGS[\s\S]*Matched "Operator \`Rx\' with parameter \`.\' against variable \`RESPONSE_HEADERS[\s\S]*Matched "Operator \`Rx\' with parameter \`TEST\' against variable \`RESPONSE_BODY';

my $audit_found_expected = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_expected);

ok (($res1->code == $status_code_expected) && ($audit_found_expected));
}

###############################################################################
# Test phases
# phase 5 (logging)
###############################################################################
{
# Remember position in audit log file before our test
my $audit_log_start_size = -s $audit_log or die "Failed to access file: " . $audit_log;

my $url = "/00-phases/00-phases_05.html";
my $ct_header_name = "Content-Type";
my $ct_header_val = "application/x-www-form-urlencoded";
my $content = "arg1=val1&arg2=val2";
my $res1 = POST $url, $ct_header_name => $ct_header_val, content => $content;

# Expected results
my $status_code_expected = 200;
my $audit_log_expected = 'Matched "Operator \`Rx\' with parameter \`\^POST\' against variable \`REQUEST_LINE[\s\S]*Matched "Operator \`Rx\' with parameter \`val1\' against variable \`ARGS[\s\S]*Matched "Operator \`Rx\' with parameter \`.\' against variable \`RESPONSE_HEADERS[\s\S]*Matched "Operator \`Rx\' with parameter \`TEST\' against variable \`RESPONSE_BODY';

my $audit_found_expected = find_string_in_file($audit_log, $audit_log_start_size, $audit_log_expected);

ok (($res1->code == $status_code_expected) && ($audit_found_expected));
}

45 changes: 45 additions & 0 deletions t/conf/extra.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ LoadModule security3_module "@ServerRoot@/.././src/.libs/mod_security3.so"
# Lets make sure that the engine is on.
modsecurity_rules 'SecRuleEngine On'

# Audit logs -- it is actually turned on via postamble
modsecurity_rules 'SecAuditLog @ServerRoot@/logs/audit_logs.txt'
modsecurity_rules 'SecAuditLogParts ABIJDEFHZ'

# Debug logs
modsecurity_rules 'SecDebugLog @ServerRoot@/logs/debug_logs.txt'
modsecurity_rules 'SecDebugLogLevel 9'
Expand Down Expand Up @@ -61,3 +65,44 @@ modsecurity_rules 'SecDebugLogLevel 9'
modsecurity_rules 'SecRule ARGS "evil" "phase:5,id:114,log,status:402,block,deny"'
</Location>

<Location "/00-phases/00-phases_01.html">
modsecurity_rules 'SecRequestBodyAccess On'
modsecurity_rules 'SecResponseBodyAccess On'
modsecurity_rules 'SecRule REQUEST_LINE "^POST" "phase:1,pass,log,auditlog,id:500169"'
modsecurity_rules 'SecRule ARGS "val1" "phase:1,pass,log,auditlog,id:500170"'
modsecurity_rules 'SecRule RESPONSE_HEADERS:Last-Modified "." "phase:1,pass,log,auditlog,id:500171"'
modsecurity_rules 'SecRule RESPONSE_BODY "TEST" "phase:1,pass,log,auditlog,id:500172"'
</Location>
<Location "/00-phases/00-phases_02.html">
modsecurity_rules 'SecRequestBodyAccess On'
modsecurity_rules 'SecResponseBodyAccess On'
modsecurity_rules 'SecRule REQUEST_LINE "^POST" "phase:2,pass,log,auditlog,id:500173"'
modsecurity_rules 'SecRule ARGS "val1" "phase:2,pass,log,auditlog,id:500174"'
modsecurity_rules 'SecRule RESPONSE_HEADERS:Last-Modified "." "phase:2,pass,log,auditlog,id:500175"'
modsecurity_rules 'SecRule RESPONSE_BODY "TEST" "phase:2,pass,log,auditlog,id:500176"'
</Location>
<Location "/00-phases/00-phases_03.html">
modsecurity_rules 'SecRequestBodyAccess On'
modsecurity_rules 'SecResponseBodyAccess On'
modsecurity_rules 'SecRule REQUEST_LINE "^POST" "phase:3,pass,log,auditlog,id:500177"'
modsecurity_rules 'SecRule ARGS "val1" "phase:3,pass,log,auditlog,id:500178"'
modsecurity_rules 'SecRule RESPONSE_HEADERS:Last-Modified "." "phase:3,pass,log,auditlog,id:500179"'
modsecurity_rules 'SecRule RESPONSE_BODY "TEST" "phase:3,pass,log,auditlog,id:500180"'
</Location>
<Location "/00-phases/00-phases_04.html">
modsecurity_rules 'SecRequestBodyAccess On'
modsecurity_rules 'SecResponseBodyAccess On'
modsecurity_rules 'SecRule REQUEST_LINE "^POST" "phase:4,pass,log,auditlog,id:500181"'
modsecurity_rules 'SecRule ARGS "val1" "phase:4,pass,log,auditlog,id:500182"'
modsecurity_rules 'SecRule RESPONSE_HEADERS:Last-Modified "." "phase:4,pass,log,auditlog,id:500183"'
modsecurity_rules 'SecRule RESPONSE_BODY "TEST" "phase:4,pass,log,auditlog,id:500184"'
</Location>
<Location "/00-phases/00-phases_05.html">
modsecurity_rules 'SecRequestBodyAccess On'
modsecurity_rules 'SecResponseBodyAccess On'
modsecurity_rules 'SecRule REQUEST_LINE "^POST" "phase:5,pass,log,auditlog,id:500185"'
modsecurity_rules 'SecRule ARGS "val1" "phase:5,pass,log,auditlog,id:500186"'
modsecurity_rules 'SecRule RESPONSE_HEADERS:Last-Modified "." "phase:5,pass,log,auditlog,id:500187"'
modsecurity_rules 'SecRule RESPONSE_BODY "TEST" "phase:5,pass,log,auditlog,id:500188"'
</Location>

22 changes: 22 additions & 0 deletions t/find_string_in_file.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

use strict;
use FileHandle;

# arg0 = filename; arg1 = start position; arg2 = string to find
sub find_string_in_file {
my $file_end_size = -s $_[0] or die "(find_string_in_file.pl) Failed to access file: " . $_[0];
my $bytes_to_read = $file_end_size - $_[1];

my $file_content;
open FILE, $_[0] || die $!;
seek(FILE, $_[1], IO::Seekable::SEEK_SET);
my $bytes_read = read(FILE, $file_content, $bytes_to_read);

# if (index($file_content, $_[2]) != -1) {
if ($file_content =~ $_[2]) {
return 1;
}
return 0;
}
1;

1 change: 1 addition & 0 deletions t/htdocs/00-phases/00-phases_01.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00-phases_01 TEST
1 change: 1 addition & 0 deletions t/htdocs/00-phases/00-phases_02.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00-phases_02 TEST
1 change: 1 addition & 0 deletions t/htdocs/00-phases/00-phases_03.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00-phases_03 TEST
1 change: 1 addition & 0 deletions t/htdocs/00-phases/00-phases_04.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00-phases_04 TEST
1 change: 1 addition & 0 deletions t/htdocs/00-phases/00-phases_05.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00-phases_05 TEST