### 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( 12123 ), ), ), }, # Failed validation { type => "rule", comment => "validateSchema (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 "\@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 ], }, 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( 12123 ), ), ), }, # Bad XML { type => "rule", comment => "validateSchema (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 "\@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 ], }, 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( 12123 ), ), ), }, # Bad schema { type => "rule", comment => "validateSchema (bad schema)", 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-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 ], }, 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( 12123 ), ), ), }, # 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( 12123 ), ), ), }, # 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( 12123 ), ), ), }, # 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( 12123 ), ), ), }, # 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( 12123 ), ), ), },