1### Test basic targets
2
3# ARGS
4{
5	type => "target",
6	comment => "ARGS (get)",
7	conf => qq(
8		SecRuleEngine On
9		SecRequestBodyAccess On
10		SecResponseBodyAccess On
11		SecResponseBodyMimeType null
12		SecDebugLog $ENV{DEBUG_LOG}
13		SecDebugLogLevel 9
14		SecRule ARGS "val1" "phase:2,log,pass,id:500189"
15		SecRule ARGS "val2" "phase:2,log,pass,id:500190"
16	),
17	match_log => {
18		error => [ qr/Pattern match "val1" at ARGS.*Pattern match "val2" at ARGS/s, 1 ],
19		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
20	},
21	match_response => {
22		status => qr/^200$/,
23	},
24	request => new HTTP::Request(
25		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
26	),
27},
28{
29	type => "target",
30	comment => "ARGS (post)",
31	conf => qq(
32		SecRuleEngine On
33		SecRequestBodyAccess On
34		SecResponseBodyAccess On
35		SecResponseBodyMimeType null
36		SecDebugLog $ENV{DEBUG_LOG}
37		SecDebugLogLevel 9
38		SecRule ARGS "val1" "phase:2,log,pass,id:500191"
39		SecRule ARGS "val2" "phase:2,log,pass,id:500192"
40	),
41	match_log => {
42		error => [ qr/Pattern match "val1" at ARGS.*Pattern match "val2" at ARGS/s, 1 ],
43		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
44	},
45	match_response => {
46		status => qr/^200$/,
47	},
48	request => new HTTP::Request(
49		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
50		[
51			"Content-Type" => "application/x-www-form-urlencoded",
52		],
53		"arg1=val1&arg2=val2",
54	),
55},
56
57# ARGS_COMBINED_SIZE
58{
59	type => "target",
60	comment => "ARGS_COMBINED_SIZE (get)",
61	conf => qq(
62		SecRuleEngine On
63		SecRequestBodyAccess On
64		SecResponseBodyAccess On
65		SecResponseBodyMimeType null
66		SecRule ARGS_COMBINED_SIZE "\@eq 16" "phase:2,log,pass,id:500193"
67	),
68	match_log => {
69		error => [ qr/Operator EQ matched 16 at ARGS_COMBINED_SIZE\./s, 1 ],
70	},
71	match_response => {
72		status => qr/^200$/,
73	},
74	request => new HTTP::Request(
75		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
76	),
77},
78{
79	type => "target",
80	comment => "ARGS_COMBINED_SIZE (post)",
81	conf => qq(
82		SecRuleEngine On
83		SecRequestBodyAccess On
84		SecResponseBodyAccess On
85		SecResponseBodyMimeType null
86		SecRule ARGS_COMBINED_SIZE "\@eq 16" "phase:2,log,pass,id:500194"
87	),
88	match_log => {
89		error => [ qr/Operator EQ matched 16 at ARGS_COMBINED_SIZE\./s, 1 ],
90	},
91	match_response => {
92		status => qr/^200$/,
93	},
94	request => new HTTP::Request(
95		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
96		[
97			"Content-Type" => "application/x-www-form-urlencoded",
98		],
99		"arg1=val1&arg2=val2",
100	),
101},
102
103# ARGS_NAMES
104{
105	type => "target",
106	comment => "ARGS_NAMES (get)",
107	conf => qq(
108		SecRuleEngine On
109		SecRequestBodyAccess On
110		SecResponseBodyAccess On
111		SecResponseBodyMimeType null
112		SecDebugLog $ENV{DEBUG_LOG}
113		SecDebugLogLevel 9
114		SecRule ARGS_NAMES "arg1" "phase:2,log,pass,id:500195"
115		SecRule ARGS_NAMES "arg2" "phase:2,log,pass,id:500196"
116	),
117	match_log => {
118		error => [ qr/Pattern match "arg1" at ARGS.*Pattern match "arg2" at ARGS/s, 1 ],
119		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
120	},
121	match_response => {
122		status => qr/^200$/,
123	},
124	request => new HTTP::Request(
125		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
126	),
127},
128{
129	type => "target",
130	comment => "ARGS_NAMES (post)",
131	conf => qq(
132		SecRuleEngine On
133		SecRequestBodyAccess On
134		SecResponseBodyAccess On
135		SecResponseBodyMimeType null
136		SecDebugLog $ENV{DEBUG_LOG}
137		SecDebugLogLevel 9
138		SecRule ARGS_NAMES "arg1" "phase:2,log,pass,id:500197"
139		SecRule ARGS_NAMES "arg2" "phase:2,log,pass,id:500198"
140	),
141	match_log => {
142		error => [ qr/Pattern match "arg1" at ARGS_NAMES.*Pattern match "arg2" at ARGS_NAMES/s, 1 ],
143		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
144	},
145	match_response => {
146		status => qr/^200$/,
147	},
148	request => new HTTP::Request(
149		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
150		[
151			"Content-Type" => "application/x-www-form-urlencoded",
152		],
153		"arg1=val1&arg2=val2",
154	),
155},
156
157# ARGS_GET
158{
159	type => "target",
160	comment => "ARGS_GET (get)",
161	conf => qq(
162		SecRuleEngine On
163		SecRequestBodyAccess On
164		SecResponseBodyAccess On
165		SecResponseBodyMimeType null
166		SecDebugLog $ENV{DEBUG_LOG}
167		SecDebugLogLevel 9
168		SecRule ARGS_GET "val1" "phase:2,log,pass,id:500199"
169		SecRule ARGS_GET "val2" "phase:2,log,pass,id:500200"
170	),
171	match_log => {
172		error => [ qr/Pattern match "val1" at ARGS_GET.*Pattern match "val2" at ARGS_GET/s, 1 ],
173		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
174	},
175	match_response => {
176		status => qr/^200$/,
177	},
178	request => new HTTP::Request(
179		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
180	),
181},
182{
183	type => "target",
184	comment => "ARGS_GET (post)",
185	conf => qq(
186		SecRuleEngine On
187		SecRequestBodyAccess On
188		SecResponseBodyAccess On
189		SecResponseBodyMimeType null
190		SecDebugLog $ENV{DEBUG_LOG}
191		SecDebugLogLevel 9
192		SecRule ARGS_GET "val1" "phase:2,log,pass,id:500201"
193		SecRule ARGS_GET "val2" "phase:2,log,pass,id:500202"
194	),
195	match_log => {
196		-error => [ qr/Pattern match/, 1 ],
197		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
198	},
199	match_response => {
200		status => qr/^200$/,
201	},
202	request => new HTTP::Request(
203		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
204		[
205			"Content-Type" => "application/x-www-form-urlencoded",
206		],
207		"arg1=val1&arg2=val2",
208	),
209},
210
211# ARGS_GET_NAMES
212{
213	type => "target",
214	comment => "ARGS_GET_NAMES (get)",
215	conf => qq(
216		SecRuleEngine On
217		SecRequestBodyAccess On
218		SecResponseBodyAccess On
219		SecResponseBodyMimeType null
220		SecDebugLog $ENV{DEBUG_LOG}
221		SecDebugLogLevel 9
222		SecRule ARGS_GET_NAMES "arg1" "phase:2,log,pass,id:500203"
223		SecRule ARGS_GET_NAMES "arg2" "phase:2,log,pass,id:500204"
224	),
225	match_log => {
226		error => [ qr/Pattern match "arg1" at ARGS_GET.*Pattern match "arg2" at ARGS_GET/s, 1 ],
227		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
228	},
229	match_response => {
230		status => qr/^200$/,
231	},
232	request => new HTTP::Request(
233		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
234	),
235},
236{
237	type => "target",
238	comment => "ARGS_GET_NAMES (post)",
239	conf => qq(
240		SecRuleEngine On
241		SecRequestBodyAccess On
242		SecResponseBodyAccess On
243		SecResponseBodyMimeType null
244		SecDebugLog $ENV{DEBUG_LOG}
245		SecDebugLogLevel 9
246		SecRule ARGS_GET_NAMES "arg1" "phase:2,log,pass,id:500205"
247		SecRule ARGS_GET_NAMES "arg2" "phase:2,log,pass,id:500206"
248	),
249	match_log => {
250		-error => [ qr/Pattern match/, 1 ],
251		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
252	},
253	match_response => {
254		status => qr/^200$/,
255	},
256	request => new HTTP::Request(
257		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
258		[
259			"Content-Type" => "application/x-www-form-urlencoded",
260		],
261		"arg1=val1&arg2=val2",
262	),
263},
264
265# ARGS_POST
266{
267	type => "target",
268	comment => "ARGS_POST (get)",
269	conf => qq(
270		SecRuleEngine On
271		SecRequestBodyAccess On
272		SecResponseBodyAccess On
273		SecResponseBodyMimeType null
274		SecDebugLog $ENV{DEBUG_LOG}
275		SecDebugLogLevel 9
276		SecRule ARGS_POST "val1" "phase:2,log,pass,id:500207"
277		SecRule ARGS_POST "val2" "phase:2,log,pass,id:500208"
278	),
279	match_log => {
280		-error => [ qr/Pattern match/, 1 ],
281		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
282	},
283	match_response => {
284		status => qr/^200$/,
285	},
286	request => new HTTP::Request(
287		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
288        [
289                "Content-Type" => "application/x-www-form-urlencoded",
290        ],
291        "a=b",
292	),
293},
294{
295	type => "target",
296	comment => "ARGS_POST (post)",
297	conf => qq(
298		SecRuleEngine On
299		SecRequestBodyAccess On
300		SecResponseBodyAccess On
301		SecResponseBodyMimeType null
302		SecDebugLog $ENV{DEBUG_LOG}
303		SecDebugLogLevel 9
304		SecRule ARGS_POST "val1" "phase:2,log,pass,id:500209"
305		SecRule ARGS_POST "val2" "phase:2,log,pass,id:500210"
306	),
307	match_log => {
308		error => [ qr/Pattern match "val1" at ARGS_POST.*Pattern match "val2" at ARGS_POST/s, 1 ],
309		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
310	},
311	match_response => {
312		status => qr/^200$/,
313	},
314	request => new HTTP::Request(
315		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
316		[
317			"Content-Type" => "application/x-www-form-urlencoded",
318		],
319		"arg1=val1&arg2=val2",
320	),
321},
322
323# ARGS_POST_NAMES
324{
325	type => "target",
326	comment => "ARGS_POST_NAMES (get)",
327	conf => qq(
328		SecRuleEngine On
329		SecRequestBodyAccess On
330		SecResponseBodyAccess On
331		SecResponseBodyMimeType null
332		SecDebugLog $ENV{DEBUG_LOG}
333		SecDebugLogLevel 9
334		SecRule ARGS_POST_NAMES "arg1" "phase:2,log,pass,id:500211"
335		SecRule ARGS_POST_NAMES "arg2" "phase:2,log,pass,id:500212"
336	),
337	match_log => {
338		-error => [ qr/Pattern match/, 1 ],
339		debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
340	},
341	match_response => {
342		status => qr/^200$/,
343	},
344	request => new HTTP::Request(
345		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
346	),
347},
348{
349	type => "target",
350	comment => "ARGS_POST_NAMES (post)",
351	conf => qq(
352		SecRuleEngine On
353		SecRequestBodyAccess On
354		SecResponseBodyAccess On
355		SecResponseBodyMimeType null
356		SecDebugLog $ENV{DEBUG_LOG}
357		SecDebugLogLevel 9
358		SecRule ARGS_POST_NAMES "arg1" "phase:2,log,pass,id:500213"
359		SecRule ARGS_POST_NAMES "arg2" "phase:2,log,pass,id:500214"
360	),
361	match_log => {
362		error => [ qr/Pattern match "arg1" at ARGS_POST.*Pattern match "arg2" at ARGS_POST/s, 1 ],
363		debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
364	},
365	match_response => {
366		status => qr/^200$/,
367	},
368	request => new HTTP::Request(
369		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
370		[
371			"Content-Type" => "application/x-www-form-urlencoded",
372		],
373		"arg1=val1&arg2=val2",
374	),
375},
376# FULL_REQUEST
377{
378	type => "target",
379	comment => "FULL_REQUEST (get)",
380	conf => qq(
381		SecRuleEngine On
382		SecRequestBodyAccess On
383		SecResponseBodyAccess On
384		SecDebugLog $ENV{DEBUG_LOG}
385		SecDebugLogLevel 9
386		SecRule FULL_REQUEST "arg1" "phase:4,log,pass,id:500211"
387		SecRule FULL_REQUEST "arg2" "phase:4,log,pass,id:500212"
388	),
389	match_log => {
390		error => [ qr/Pattern match "arg1" at FULL_REQUEST.*Pattern match "arg2" at FULL_REQUEST/s, 1 ],
391		debug => [ qr/against FULL_REQUEST.*Target value: "GET \/test.txt\?arg1=val1\&arg2=val2 HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:[0-9]+\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\n\\n\\x00"/s, 1],
392	},
393	match_response => {
394		status => qr/^200$/,
395	},
396	request => new HTTP::Request(
397		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
398	),
399},
400{
401	type => "target",
402	comment => "FULL_REQUEST (post)",
403	conf => qq(
404		SecRuleEngine On
405		SecRequestBodyAccess On
406		SecResponseBodyAccess On
407		SecDebugLog $ENV{DEBUG_LOG}
408		SecDebugLogLevel 9
409		SecRule FULL_REQUEST "arg1" "phase:4,log,pass,id:500213"
410		SecRule FULL_REQUEST "arg2" "phase:4,log,pass,id:500214"
411	),
412	match_log => {
413		error => [ qr/Pattern match "arg1" at FULL_REQUEST.*Pattern match "arg2" at FULL_REQUEST/s, 1 ],
414		debug => [ qr/against FULL_REQUEST.*Target value: "POST \/test.txt HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:[0-9]+\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\nContent-Type: application\/x-www-form-urlencoded\\nContent-Length: 19\\n\\narg1=val1&arg2=val2\\x00"/s, 1 ],
415	},
416	match_response => {
417		status => qr/^200$/,
418	},
419	request => new HTTP::Request(
420		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
421		[
422			"Content-Type" => "application/x-www-form-urlencoded",
423		],
424		"arg1=val1&arg2=val2",
425	),
426},
427# FULL_REQUEST_LENGTH
428{
429	type => "target",
430	comment => "FULL_REQUEST_LENGTH (get)",
431	conf => qq(
432		SecRuleEngine On
433		SecRequestBodyAccess On
434		SecResponseBodyAccess On
435		SecDebugLog $ENV{DEBUG_LOG}
436		SecDebugLogLevel 9
437		SecRule FULL_REQUEST_LENGTH "\@eq 1" "phase:4,log,pass,id:500211"
438		SecRule FULL_REQUEST_LENGTH "\@eq 115" "phase:4,log,pass,id:500212"
439	),
440	match_log => {
441		error => [ qr/Operator EQ matched 115 at FULL_REQUEST_LENGTH./s, 1 ],
442		debug => [ qr/against FULL_REQUEST_LENGTH.*Target value: "115"/s, 1 ],
443	},
444	match_response => {
445		status => qr/^200$/,
446	},
447	request => new HTTP::Request(
448		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
449	),
450},
451{
452	type => "target",
453	comment => "FULL_REQUEST_LENGTH (post)",
454	conf => qq(
455		SecRuleEngine On
456		SecRequestBodyAccess On
457		SecResponseBodyAccess On
458		SecDebugLog $ENV{DEBUG_LOG}
459		SecDebugLogLevel 9
460		SecRule FULL_REQUEST_LENGTH "\@eq 1" "phase:4,log,pass,id:500213"
461		SecRule FULL_REQUEST_LENGTH "\@eq 201" "phase:4,log,pass,id:500214"
462	),
463	match_log => {
464		error => [ qr/Operator EQ matched 201 at FULL_REQUEST_LENGTH./s, 1 ],
465		debug => [ qr/against FULL_REQUEST_LENGTH.*Target value: "201"/s, 1 ],
466	},
467	match_response => {
468		status => qr/^200$/,
469	},
470	request => new HTTP::Request(
471		POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
472		[
473			"Content-Type" => "application/x-www-form-urlencoded",
474		],
475		"arg1=val1&arg2=val2",
476	),
477},
478
479
480
481# AUTH_TYPE
482#{
483#	type => "target",
484#	comment => "AUTH_TYPE",
485#	conf => qq(
486#		<IfVersion >= 2.2>
487#			<IfModule !mod_authn_file.c>
488#				LoadModule authn_file_module modules/mod_authn_file.so
489#			</IfModule>
490#		</IfVersion>
491##		<IfVersion ~ ^2.0.>
492##			<IfModule !mod_auth.c>
493##				LoadModule auth_module modules/mod_auth.so
494##			</IfModule>
495##		</IfVersion>
496#		<Location />
497#			AuthType Basic
498#			AuthName Test
499#			AuthUserFile "$ENV{CONF_DIR}/htpasswd"
500#			Require user nobody
501#		</Location>
502#		SecRuleEngine On
503#		SecRequestBodyAccess On
504#		SecResponseBodyAccess On
505#		SecResponseBodyMimeType null
506##		SecDebugLog $ENV{DEBUG_LOG}
507##		SecDebugLogLevel 9
508#		SecRule REQUEST_HEADERS:Authorization "Basic (.*)" "phase:2,log,pass,capture,chain"
509#		SecRule TX:1 "nobody:test" "t:none,t:base64Decode,chain"
510#		SecRule AUTH_TYPE "Basic"
511#	),
512#	match_log => {
513#		error => [ qr/Pattern match "Basic" at AUTH_TYPE/s, 1 ],
514#	},
515#	match_response => {
516#		status => qr/^200$/,
517#	},
518#	request => new HTTP::Request(
519#		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
520#		[
521#			"Authorization" => "Basic bm9ib2R5OnRlc3Q="
522#		],
523#	),
524#},
525
526## ENH: We cannot include this test as we cannot distribute the database.
527##      Instead we should create a simple test DB of our own.
528## GEO
529#{
530#	type => "target",
531#	comment => "GEO (ip)",
532#	conf => qq(
533#		SecRuleEngine On
534#		SecDebugLog $ENV{DEBUG_LOG}
535#		SecDebugLogLevel 9
536#        SecGeoLookupDB GeoLiteCity.dat
537#		SecRule ARGS:ip "\@geoLookup" "phase:2,log,pass,t:none"
538#		SecRule GEO:COUNTRY_CODE "\@streq US" "phase:2,log,pass,t:none"
539#		SecRule GEO:COUNTRY_CODE3 "\@streq USA" "phase:2,log,pass,t:none"
540#		SecRule GEO:COUNTRY_NAME "\@streq United States" "phase:2,log,pass,t:none"
541#        # ENH: Not in this database?
542#		SecRule GEO:COUNTRY_CONTINENT "\@streq NA" "phase:2,log,pass,t:none"
543#		SecRule GEO:REGION "\@streq CA" "phase:2,log,pass,t:none"
544#		SecRule GEO:CITY "\@streq San Diego" "phase:2,log,pass,t:none"
545#		SecRule GEO:POSTAL_CODE "\@streq 92123" "phase:2,log,pass,t:none"
546#		SecRule GEO:LATITUDE "\@beginsWith 32.8" "phase:2,log,pass,t:none"
547#		SecRule GEO:LONGITUDE "\@beginsWith 117.1" "phase:2,log,pass,t:none"
548#		SecRule GEO:DMA_CODE "\@streq 825" "phase:2,log,pass,t:none"
549#		SecRule GEO:AREA_CODE "\@streq 858" "phase:2,log,pass,t:none"
550#	),
551#	match_log => {
552#		debug => [ qr/Geo lookup for "216.75.21.122" succeeded.*match "US" at GEO:COUNTRY_CODE.*match "USA" at GEO:COUNTRY_CODE3.*match "United States" at GEO:COUNTRY_NAME.*match "NA" at GEO:COUNTRY_CONTINENT.*match "CA" at GEO:REGION.*match "San Diego" at GEO:CITY.*match "92123" at GEO:POSTAL_CODE.*match "32.8" at GEO:LATITUDE.*match "825" at GEO:DMA_CODE.*match "858" at GEO:AREA_CODE/si, 1 ],
553#	},
554#	match_response => {
555#		status => qr/^200$/,
556#	},
557#	request => new HTTP::Request(
558#		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ip=216.75.21.122",
559#	),
560#},
561#{
562#	type => "target",
563#	comment => "GEO (host)",
564#	conf => qq(
565#		SecRuleEngine On
566#		SecDebugLog $ENV{DEBUG_LOG}
567#		SecDebugLogLevel 9
568#        SecGeoLookupDB GeoLiteCity.dat
569#		SecRule ARGS:host "\@geoLookup" "phase:2,log,pass,t:none"
570#		SecRule GEO:COUNTRY_CODE "\@streq US" "phase:2,log,pass,t:none"
571#		SecRule GEO:COUNTRY_CODE3 "\@streq USA" "phase:2,log,pass,t:none"
572#		SecRule GEO:COUNTRY_NAME "\@streq United States" "phase:2,log,pass,t:none"
573#        # ENH: Not in this database?
574#		SecRule GEO:COUNTRY_CONTINENT "\@streq NA" "phase:2,log,pass,t:none"
575#		SecRule GEO:REGION "\@streq CA" "phase:2,log,pass,t:none"
576#		SecRule GEO:CITY "\@streq San Diego" "phase:2,log,pass,t:none"
577#		SecRule GEO:POSTAL_CODE "\@streq 92123" "phase:2,log,pass,t:none"
578#		SecRule GEO:LATITUDE "\@beginsWith 32.8" "phase:2,log,pass,t:none"
579#		SecRule GEO:LONGITUDE "\@beginsWith 117.1" "phase:2,log,pass,t:none"
580#		SecRule GEO:DMA_CODE "\@streq 825" "phase:2,log,pass,t:none"
581#		SecRule GEO:AREA_CODE "\@streq 858" "phase:2,log,pass,t:none"
582#	),
583#	match_log => {
584#		debug => [ qr/Using address "\d+\.\d+\.\d+\.\d+".*Geo lookup for "www\.modsecurity\.org" succeeded.*match "US" at GEO:COUNTRY_CODE.*match "USA" at GEO:COUNTRY_CODE3.*match "United States" at GEO:COUNTRY_NAME.*match "NA" at GEO:COUNTRY_CONTINENT.*match "CA" at GEO:REGION.*match "San Diego" at GEO:CITY.*match "92123" at GEO:POSTAL_CODE.*match "32.8" at GEO:LATITUDE.*match "825" at GEO:DMA_CODE.*match "858" at GEO:AREA_CODE/si, 1 ],
585#	},
586#	match_response => {
587#		status => qr/^200$/,
588#	},
589#	request => new HTTP::Request(
590#		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?host=www.modsecurity.org",
591#	),
592#},
593#{
594#	type => "target",
595#	comment => "GEO (failed lookup)",
596#	conf => qq(
597#		SecRuleEngine On
598#		SecDebugLog $ENV{DEBUG_LOG}
599#		SecDebugLogLevel 9
600#        SecGeoLookupDB GeoLiteCity.dat
601#		SecRule ARGS:ip "\@geoLookup" "phase:2,log,pass,t:none"
602#		SecRule \&GEO "\@eq 0" "phase:2,log,deny,status:403,t:none"
603#		SecRule ARGS:badip "\@geoLookup" "phase:2,log,pass,t:none"
604#		SecRule \&GEO "!\@eq 0" "phase:2,log,deny,status:403,t:none"
605#	),
606#	match_log => {
607#		-debug => [ qr/Geo lookup for "127\.0\.0\.1" succeeded/si, 1 ],
608#	},
609#	match_response => {
610#		status => qr/^200$/,
611#	},
612#	request => new HTTP::Request(
613#		GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ip=216.75.21.122&badip=127.0.0.1",
614#	),
615#},
616
617# TODO: ENV
618# TODO: FILES
619# TODO: FILES_COMBINED_SIZE
620# TODO: FILES_NAMES
621# TODO: FILES_SIZES
622# TODO: FILES_TMPNAMES
623# TODO: HIGHEST_SEVERITY
624# TODO: MATCHED_VAR
625# TODO: MATCHED_VAR_NAME
626# TODO: MODSEC_BUILD
627# TODO: MULTIPART_CRLF_LF_LINES
628# TODO: MULTIPART_STRICT_ERROR
629# TODO: MULTIPART_UNMATCHED_BOUNDARY
630# TODO: PATH_INFO
631# TODO: QUERY_STRING
632# TODO: REMOTE_ADDR
633# TODO: REMOTE_HOST
634# TODO: REMOTE_PORT
635# TODO: REMOTE_USER
636# TODO: REQBODY_PROCESSOR
637# TODO: REQBODY_PROCESSOR_ERROR
638# TODO: REQBODY_PROCESSOR_ERROR_MSG
639# TODO: REQUEST_BASENAME
640# TODO: REQUEST_BODY
641# TODO: REQUEST_COOKIES
642# TODO: REQUEST_COOKIES_NAMES
643# TODO: REQUEST_FILENAME
644# TODO: REQUEST_HEADERS
645# TODO: REQUEST_HEADERS_NAMES
646# TODO: REQUEST_LINE
647# TODO: REQUEST_METHOD
648# TODO: REQUEST_PROTOCOL
649# TODO: REQUEST_URI
650# TODO: REQUEST_URI_RAW
651# TODO: RESPONSE_BODY
652# TODO: RESPONSE_CONTENT_LENGTH
653# TODO: RESPONSE_CONTENT_TYPE
654# TODO: RESPONSE_HEADERS
655# TODO: RESPONSE_HEADERS_NAMES
656# TODO: RESPONSE_PROTOCOL
657# TODO: RESPONSE_STATUS
658# TODO: RULE
659# TODO: SCRIPT_BASENAME
660# TODO: SCRIPT_FILENAME
661# TODO: SCRIPT_GID
662# TODO: SCRIPT_GROUPNAME
663# TODO: SCRIPT_MODE
664# TODO: SCRIPT_UID
665# TODO: SCRIPT_USERNAME
666# TODO: SERVER_ADDR
667# TODO: SERVER_NAME
668# TODO: SERVER_PORT
669# TODO: SESSION
670# TODO: SESSIONID
671# TODO: TIME
672# TODO: TIME_DAY
673# TODO: TIME_EPOCH
674# TODO: TIME_HOUR
675# TODO: TIME_MIN
676# TODO: TIME_MON
677# TODO: TIME_SEC
678# TODO: TIME_WDAY
679# TODO: TIME_YEAR
680# TODO: TX
681# TODO: USERID
682# TODO: WEBAPPID
683# TODO: WEBSERVER_ERROR_LOG
684# TODO: XML
685
686