1### Test for XML operator rules
2
3### Validate Scheme
4# OK
5{
6	type => "rule",
7	comment => "validateSchema (validate ok)",
8	conf => qq(
9		SecRuleEngine On
10		SecRequestBodyAccess On
11        SecXmlExternalEntity On
12		SecDebugLog $ENV{DEBUG_LOG}
13		SecDebugLogLevel 9
14		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500005, \\
15		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
16		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500006
17		SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" "id:500007, \\
18		        phase:3:,deny"
19	),
20	match_log => {
21		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Successfully validated payload against Schema/s, 1 ],
22		-debug => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
23		-error => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
24	},
25	match_response => {
26		status => qr/^200$/,
27	},
28	request => new HTTP::Request(
29		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
30		[
31			"Content-Type" => "text/xml",
32		],
33		normalize_raw_request_data(
34			q(
35				<?xml version="1.0" encoding="utf-8"?>
36				<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
37				xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
38				xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
39				xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
40				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
41				xmlns:xsd="http://www.w3.org/2001/XMLSchema">
42						<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
43								<q1:getInput xmlns:q1="http://DefaultNamespace">
44										<id xsi:type="xsd:string">12123</id>
45								</q1:getInput>
46						</soap:Body>
47				</soap:Envelope>
48			),
49		),
50	),
51},
52# Failed attribute value
53{
54	type => "rule",
55	comment => "validateSchema (validate attribute value failed)",
56	conf => qq(
57		SecRuleEngine On
58		SecRequestBodyAccess On
59        SecXmlExternalEntity On
60		SecDebugLog $ENV{DEBUG_LOG}
61		SecDebugLogLevel 9
62		SecAuditEngine RelevantOnly
63		SecAuditLog "$ENV{AUDIT_LOG}"
64		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500008, \\
65		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
66		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500009
67		SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" "id:500010 \\
68		        phase:2,deny,log,auditlog,id:12345"
69	),
70	match_log => {
71		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 ],
72		-debug => [ qr/Successfully validated payload against Schema|\n\r?\n/, 1 ],
73		audit => [ qr/^Message: Element.*'badval' is not a valid value of the local atomic type\.\nMessage:/m, 1 ],
74	},
75	match_response => {
76		status => qr/^403$/,
77	},
78	request => new HTTP::Request(
79		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
80		[
81			"Content-Type" => "text/xml",
82		],
83		normalize_raw_request_data(
84			q(
85				<?xml version="1.0" encoding="utf-8"?>
86				<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
87				xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
88				xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
89				xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
90				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
91				xmlns:xsd="http://www.w3.org/2001/XMLSchema">
92						<soap:Body soap:mustUnderstand="badval" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
93								<q1:getInput xmlns:q1="http://DefaultNamespace">
94										<id xsi:type="xsd:string">12123</id>
95								</q1:getInput>
96						</soap:Body>
97				</soap:Envelope>
98			),
99		),
100	),
101},
102# Failed validation
103{
104	type => "rule",
105	comment => "validateSchema (validate failed)",
106	conf => qq(
107		SecRuleEngine On
108		SecRequestBodyAccess On
109        SecXmlExternalEntity On
110		SecDebugLog $ENV{DEBUG_LOG}
111		SecDebugLogLevel 9
112		SecAuditEngine RelevantOnly
113		SecAuditLog "$ENV{AUDIT_LOG}"
114		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500011, \\
115		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
116		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500012
117		SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" "id:500013 \\
118		        phase:2,deny,id:12345"
119	),
120	match_log => {
121		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*element is not expected/s, 1 ],
122		-debug => [ qr/XML parser error|Failed to load/, 1 ],
123		-error => [ qr/XML parser error|Failed to load/, 1 ],
124		audit => [ qr/^Message: Element.*This element is not expected.*\nMessage:/m, 1 ],
125	},
126	match_response => {
127		status => qr/^403$/,
128	},
129	request => new HTTP::Request(
130		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
131		[
132			"Content-Type" => "text/xml",
133		],
134		normalize_raw_request_data(
135			q(
136				<?xml version="1.0" encoding="utf-8"?>
137				<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
138				xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
139				xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
140				xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
141				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
142				xmlns:xsd="http://www.w3.org/2001/XMLSchema">
143						<soap:xBody soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
144								<q1:getInput xmlns:q1="http://DefaultNamespace">
145										<id xsi:type="xsd:string">12123</id>
146								</q1:getInput>
147						</soap:xBody>
148				</soap:Envelope>
149			),
150		),
151	),
152},
153# Bad XML
154{
155	type => "rule",
156	comment => "validateSchema (bad XML)",
157	conf => qq(
158		SecRuleEngine On
159		SecRequestBodyAccess On
160        SecXmlExternalEntity On
161		SecDebugLog $ENV{DEBUG_LOG}
162		SecDebugLogLevel 9
163		SecAuditEngine RelevantOnly
164		SecAuditLog "$ENV{AUDIT_LOG}"
165		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500014, \\
166		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
167		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500015
168		SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" "id:500016, \\
169		        phase:2,deny,id:12345"
170	),
171	match_log => {
172		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ],
173		-debug => [ qr/Failed to load|Successfully validated/, 1 ],
174		-error => [ qr/Failed to load|Successfully validated/, 1 ],
175		audit => [ qr/^Message: .*Failed parsing document.*\nMessage:/m, 1 ],
176	},
177	match_response => {
178		status => qr/^403$/,
179	},
180	request => new HTTP::Request(
181		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
182		[
183			"Content-Type" => "text/xml",
184		],
185		normalize_raw_request_data(
186			q(
187				<?xml version="1.0" encoding="utf-8"?>
188				<soap:Envelop xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
189				xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
190				xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
191				xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
192				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
193				xmlns:xsd="http://www.w3.org/2001/XMLSchema">
194						<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
195								<q1:getInput xmlns:q1="http://DefaultNamespace">
196										<id xsi:type="xsd:string">12123</id>
197								</q1:getInput>
198						</soap:Body>
199				</soap:Envelope>
200			),
201		),
202	),
203},
204# Bad schema
205{
206	type => "rule",
207	comment => "validateSchema (bad schema)",
208	conf => qq(
209		SecRuleEngine On
210		SecRequestBodyAccess On
211        SecXmlExternalEntity On
212		SecDebugLog $ENV{DEBUG_LOG}
213		SecDebugLogLevel 9
214		SecAuditEngine RelevantOnly
215		SecAuditLog "$ENV{AUDIT_LOG}"
216		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500017 \\
217		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
218		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500018
219		SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope-bad.xsd" "id:500019 \\
220		        phase:2,deny,id:12345"
221	),
222	match_log => {
223		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 ],
224		audit => [ qr/^Message: .*Failed to parse the XML resource.*\nMessage: Rule processing failed/m, 1 ],
225	},
226	match_response => {
227		status => qr/^200$/,
228	},
229	request => new HTTP::Request(
230		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
231		[
232			"Content-Type" => "text/xml",
233		],
234		normalize_raw_request_data(
235			q(
236				<?xml version="1.0" encoding="utf-8"?>
237				<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
238				xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
239				xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
240				xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
241				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
242				xmlns:xsd="http://www.w3.org/2001/XMLSchema">
243						<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
244								<q1:getInput xmlns:q1="http://DefaultNamespace">
245										<id xsi:type="xsd:string">12123</id>
246								</q1:getInput>
247						</soap:Body>
248				</soap:Envelope>
249			),
250		),
251	),
252},
253
254# Validate DTD
255# OK
256{
257	type => "rule",
258	comment => "validateDTD (validate ok)",
259	conf => qq(
260		SecRuleEngine On
261		SecRequestBodyAccess On
262        SecXmlExternalEntity On
263		SecDebugLog $ENV{DEBUG_LOG}
264		SecDebugLogLevel 9
265		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500020, \\
266		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
267		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500021
268		SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" "id:500022, \\
269		        phase:2,deny,id:12345"
270	),
271	match_log => {
272		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Successfully validated payload against DTD/s, 1 ],
273		-debug => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
274		-error => [ qr/XML parser error|validation failed|Failed to load/, 1 ],
275	},
276	match_response => {
277		status => qr/^200$/,
278	},
279	request => new HTTP::Request(
280		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
281		[
282			"Content-Type" => "text/xml",
283		],
284		normalize_raw_request_data(
285			q(
286				<?xml version="1.0" encoding="utf-8"?>
287				<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
288				<Envelope>
289						<Body>
290								<getInput>
291										<id type="string">12123</id>
292								</getInput>
293						</Body>
294				</Envelope>
295			),
296		),
297	),
298},
299# Failed validation
300{
301	type => "rule",
302	comment => "validateDTD (validate failed)",
303	conf => qq(
304		SecRuleEngine On
305		SecRequestBodyAccess On
306        SecXmlExternalEntity On
307		SecDebugLog $ENV{DEBUG_LOG}
308		SecDebugLogLevel 9
309		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500023, \\
310		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
311		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500024
312		SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" "id:500025, \\
313		        phase:2,deny,id:12345"
314	),
315	match_log => {
316		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*content does not follow the DTD/s, 1 ],
317		-debug => [ qr/XML parser error|Failed to load/, 1 ],
318		-error => [ qr/XML parser error|Failed to load/, 1 ],
319	},
320	match_response => {
321		status => qr/^403$/,
322	},
323	request => new HTTP::Request(
324		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
325		[
326			"Content-Type" => "text/xml",
327		],
328		normalize_raw_request_data(
329			q(
330				<?xml version="1.0" encoding="utf-8"?>
331				<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
332				<Envelope>
333						<xBody>
334								<getInput>
335										<id type="string">12123</id>
336								</getInput>
337						</xBody>
338				</Envelope>
339			),
340		),
341	),
342},
343# Bad XML
344{
345	type => "rule",
346	comment => "validateDTD (bad XML)",
347	conf => qq(
348		SecRuleEngine On
349		SecRequestBodyAccess On
350        SecXmlExternalEntity On
351		SecDebugLog $ENV{DEBUG_LOG}
352		SecDebugLogLevel 9
353		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500026, \\
354		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
355		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500027
356		SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope.dtd" "id:500028, \\
357		        phase:2,deny,id:12345"
358	),
359	match_log => {
360		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ],
361		-debug => [ qr/Failed to load|Successfully validated/, 1 ],
362		-error => [ qr/Failed to load|Successfully validated/, 1 ],
363	},
364	match_response => {
365		status => qr/^403$/,
366	},
367	request => new HTTP::Request(
368		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
369		[
370			"Content-Type" => "text/xml",
371		],
372		normalize_raw_request_data(
373			q(
374				<?xml version="1.0" encoding="utf-8"?>
375				<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
376				<Envelop>
377						<Body>
378								<getInput>
379										<id type="string">12123</id>
380								</getInput>
381						</Body>
382				</Envelope>
383			),
384		),
385	),
386},
387# Bad DTD
388{
389	type => "rule",
390	comment => "validateDTD (bad DTD)",
391	conf => qq(
392		SecRuleEngine On
393		SecRequestBodyAccess On
394        SecXmlExternalEntity On
395		SecDebugLog $ENV{DEBUG_LOG}
396		SecDebugLogLevel 9
397		SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" "id:500029, \\
398		        phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
399		SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345,id:500030
400		SecRule XML "\@validateDTD $ENV{CONF_DIR}/SoapEnvelope-bad.dtd" "id:500031 \\
401		        phase:2,deny,id:12345"
402	),
403	match_log => {
404		debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Failed to load DTD/s, 1 ],
405	},
406	match_response => {
407		status => qr/^200$/,
408	},
409	request => new HTTP::Request(
410		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
411		[
412			"Content-Type" => "text/xml",
413		],
414		normalize_raw_request_data(
415			q(
416				<?xml version="1.0" encoding="utf-8"?>
417				<!DOCTYPE Envelope SYSTEM "SoapEnvelope.dtd">
418				<Envelope>
419						<Body>
420								<getInput>
421										<id type="string">12123</id>
422								</getInput>
423						</Body>
424				</Envelope>
425			),
426		),
427	),
428},
429