Prepravljen Maintainer u debian/control.
[libapache-mod-security.git] / doc / migration-matrix.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <article>
3   <title>ModSecurity Migration Matrix</title>
4
5   <articleinfo>
6     <releaseinfo>Version 1.0 / (April 10, 2007)</releaseinfo>
7
8     <copyright>
9       <year>2004-2009</year>
10
11       <holder>Breach Security, Inc. (<ulink
12       url="http://www.breach.com">http://www.breach.com</ulink>)</holder>
13     </copyright>
14   </articleinfo>
15
16   <section id="01-introduction">
17     <title>Migration from 1.x to 2.x</title>
18
19     <section>
20       <para>If you are already using an older version of ModSecurity and want
21       to upgrade/migrate your existing custom rules, you will need to ensure
22       that you properly translate all of your Directives to their
23       corresponding 2.0 counterparts. Some directives have simply changed
24       names, however some directives actually behave differently so it is
25       important that you also review the entire 2.0 Reference Manual. The
26       migration matrix show below should help you to translate ModSecurity 1.X
27       directives to the 2.0 values. There are also some notes that provide
28       additional information is a directive significantly changed how it
29       operates. </para>
30
31       <table border="1">
32         <tr>
33           <td>
34             <emphasis role="bold">Feature/Capability</emphasis>
35           </td>
36
37           <td>
38             <emphasis role="bold">ModSecurity 1.x</emphasis>
39           </td>
40
41           <td>
42             <emphasis role="bold">ModSecurity 2.x</emphasis>
43           </td>
44
45           <td>
46             <emphasis role="bold">Notes</emphasis>
47           </td>
48
49           <td>
50             <emphasis role="bold">How To Upgrade</emphasis>
51           </td>
52         </tr>
53
54         <tr>
55           <td>
56             <emphasis role="bold">Apache Version Supported</emphasis>
57           </td>
58
59           <td>Apache 1.x/2.x</td>
60
61           <td>Apache 2.x Only</td>
62
63           <td>ModSecurity 2.0 will only work with Apache 2.x and not the older
64           1.3 version.</td>
65
66           <td>If you are mainly an Apache 1.3 shop and/or you have other web
67           servers that you want to protect (such as IIS) an alternative
68           solution is to deploy an Apache 2.x reverse proxy server and
69           implement ModSecurity 2.x on it.</td>
70         </tr>
71
72         <tr>
73           <td>
74             <emphasis role="bold">Installation</emphasis>
75           </td>
76
77           <td>Can be installed as either a DSO module or as a statically
78           compiled module.</td>
79
80           <td>Can currently only be installed as a DSO module.</td>
81
82           <td>In 1.x, you could use apxs directly, while in 2.x you must use
83           the provided Makefile.</td>
84
85           <td>If you can not use DSOs in your current Apache configs, you may
86           look at implementing a front-end Apache reverse proxy server.</td>
87         </tr>
88
89         <tr>
90           <td>
91             <emphasis role="bold">Configuration - IfModule</emphasis>
92           </td>
93
94           <td>Apache 1.x - &lt;IfModule mod_security.c&gt; Apache 2.x -
95           &lt;IfModule security_module&gt;</td>
96
97           <td>&lt;IfModule security2_module&gt;</td>
98
99           <td>The syntax of using IfModule has changed between Apache 1.x and
100           2.x</td>
101
102           <td>Make sure that any existing &lt;IfModule&gt; directives uses the
103           correct syntax.</td>
104         </tr>
105
106         <tr>
107           <td>
108             <emphasis role="bold">Processing Phases Supported</emphasis>
109           </td>
110
111           <td>2</td>
112
113           <td>5</td>
114
115           <td>ModSecurity 1.x supports:<itemizedlist>
116               <listitem>
117                 <para>Inbound - which corresponds to current Mod 2.x Request
118                 Body phase and the Apache “fixups” phase.</para>
119               </listitem>
120
121               <listitem>
122                 <para>Outbound - which corresponds to current Mod 2.x Response
123                 Body phase and just after the Apache “response” processing
124                 phase.</para>
125               </listitem>
126             </itemizedlist>ModSecurity 2.x supports: <itemizedlist>
127               <listitem>
128                 <para>Request Headers – which corresponds with the Apache
129                 “post-read-request” phase.</para>
130               </listitem>
131
132               <listitem>
133                 <para>Request Body – which corresponds with the Apache
134                 “fixups” phase.</para>
135               </listitem>
136
137               <listitem>
138                 <para>Response Headers – which corresponds to the Apache
139                 “response” phase.</para>
140               </listitem>
141
142               <listitem>
143                 <para>Response Body – which corresponds to just after the
144                 Apache “response” phase.</para>
145               </listitem>
146
147               <listitem>
148                 <para>Logging - which is the Apache logging phase.</para>
149               </listitem>
150             </itemizedlist></td>
151
152           <td>If you are translating existing 1.x rules
153           (SecFilter/SecFilterSelective) then you should use phase:2 in the
154           new rule syntax. Translate existing OUTPUT rules to run in
155           phase:4.</td>
156         </tr>
157
158         <tr>
159           <td>
160             <emphasis role="bold">Directive to turn On/Off the Rule
161             Engine</emphasis>
162           </td>
163
164           <td>SecFilterEngine</td>
165
166           <td>SecRuleEngine ctl:ruleEngine=</td>
167
168           <td>
169             <itemizedlist>
170               <listitem>
171                 <para>1.x – values were On, Off and DynamicOnly and was a
172                 Global directive.</para>
173               </listitem>
174
175               <listitem>
176                 <para>2.x - values are On, Off or DetectionOnly.</para>
177               </listitem>
178
179               <listitem>
180                 <para>2.x – the “ctl” action can control the RuleEngine
181                 dynamically for individual requests.</para>
182               </listitem>
183             </itemizedlist>
184
185             
186           </td>
187
188           <td>Replace SecFilterEngine with SecRuleEngine. The DynamicOnly mode
189           is not supported in ModSecurity 2.x because it was sometimes
190           difficult for ModSecurity to determine if a particular request was
191           dynamic in nature or not. Use of AddType vs. AddHandler would cause
192           problems. Since this logic relies on the internal (and not entirely
193           documented) workings of Apache and on the chosen configuration it
194           also makes it somewhat unpredictable.</td>
195         </tr>
196
197         <tr>
198           <td>
199             <emphasis role="bold">Directive to handle the Audit
200             Engine</emphasis>
201           </td>
202
203           <td>SecAuditEngine On, Off, RelevantOnly, DynamicOrRelevant</td>
204
205           <td>SecAuditEngine On, Off, RelevantOnly</td>
206
207           <td>In 2.x, the DynamicOrRelevant option was discontinued.</td>
208
209           <td>If you are using DynamicOrRelevant then switch it to
210           RelevantOnly.</td>
211         </tr>
212
213         <tr>
214           <td>
215             <emphasis role="bold">Default Rule Action</emphasis>
216           </td>
217
218           <td>SecFilterDefaultAction</td>
219
220           <td>SecDefaultAction</td>
221
222           <td>
223             <itemizedlist>
224               <listitem>
225                 <para>1.x – SecFilterDefaultAction could be used anywhere in
226                 the config and it would be picked up by all rules.</para>
227               </listitem>
228
229               <listitem>
230                 <para>2.x – SecDefaultAction must come before rules and be
231                 specified in each context. The default setting for this
232                 directive (if it is not specified otherwise) is –
233                 <literal>SecDefaultAction
234                 phase:2,log,deny,status:403,\</literal></para>
235
236                 <para>
237                   <literal>t:lowercase,t:replaceNulls,\</literal>
238                 </para>
239
240                 <para>
241                   <literal>t:compressWhitespace</literal>
242                 </para>
243               </listitem>
244             </itemizedlist>
245
246             
247           </td>
248
249           <td>Replace SecFilterDefaultAction with SecDefaultAction.
250           Optionally, you can group rules together where you would like to use
251           the same action and then specify a SecDefaultAction line before each
252           group. Also keep in mind that while most actions specified on
253           individual rules will supersede those specified in SecDefaultAction,
254           transformation functions are additive. So, if you specify a
255           “t:base64Decode” transformation function to a rule, it will be added
256           after the lowercase, replaceNulls and compressWhitespace
257           transformation functions.</td>
258         </tr>
259
260         <tr>
261           <td>
262             <emphasis role="bold">Debug Logging</emphasis>
263           </td>
264
265           <td>SecFilterDebugLog SecFilterDebugLogLevel</td>
266
267           <td>SecDebugLog SecDebugLogLevel</td>
268
269           <td>Name change only.</td>
270
271           <td>Change the names of these directives to their 2.x
272           counterparts.</td>
273         </tr>
274
275         <tr>
276           <td>
277             <emphasis role="bold">Rule Directive(s)</emphasis>
278           </td>
279
280           <td>SecFilter SecFilterSelective</td>
281
282           <td>SecRule</td>
283
284           <td>
285             <itemizedlist>
286               <listitem>
287                 <para>In Mod 1.x, SecFilter and SecFilterSelective were case
288                 insensitive. </para>
289               </listitem>
290
291               <listitem>
292                 <para>In Mod 2.x, the case of data is not altered unless the
293                 lowercase transformation funce is used. SecRule has
294                 essentially the same rule syntax as SecFilterSelective.</para>
295               </listitem>
296             </itemizedlist>
297           </td>
298
299           <td>Replace SecFilterSelective with SecRule and make sure to
300           translate the variable tested according to this list. Replace any
301           SecFilter with a new SecRule directive. You will need to specify a
302           new Variable location and a phase. You can optionally specify a
303           disruptive action, otherwise it will be inherited from a previous
304           SecDefaultAction. </td>
305         </tr>
306
307         <tr>
308           <td>
309             <emphasis role="bold">Rule Exceptions</emphasis>
310           </td>
311
312           <td>Whitelist approach – use pass, allow actions False Positive
313           Approach – use SecFilterRemove</td>
314
315           <td>Whitelist approach – use pass, allow and ctl actions. False
316           Positive Approach – use SecRuleRemoveById and Apache Scope
317           context</td>
318
319           <td>In Mod 2.x, using the “allow” action may not be enough to truly
320           let a request through as “allow” only applies to the current
321           processing phase. This means that rules in subsequent phases may act
322           on the request. This is why you need to also use the
323           “ctl:ruleEngine=Off” action if you really want to let a request
324           through.</td>
325
326           <td>See Blog post on handling false positives and creating custom
327           rules -
328           http://www.modsecurity.org/blog/archives/2007/02/handling_false.html</td>
329         </tr>
330
331         <tr>
332           <td>
333             <emphasis role="bold">Directive to control rule inheritance to
334             Apache Scope locations (Virtual Hosts, Location,
335             Directory)</emphasis>
336           </td>
337
338           <td>SecFilterInheritance</td>
339
340           <td>SecRuleInheritance</td>
341
342           <td>The best use of this directive is when you want to start with a
343           “clean slate” so you can use SecRuleInheritance Off and then specify
344           your new rule sets. Note – Rule Inheritance does not work across
345           Apache Scope directives (such as Vhosts, Location and Directory
346           directives). This means that you can not use SecRuleInheritance On
347           to inherit a SecDefaultAction directive within these new contexts.
348           This is an issue with the way that Apache inherits contexts. It is
349           for this reason that we recommend that you specify new
350           SecDefaultAction directives within each Apache scope location that
351           you create.</td>
352
353           <td>Translate any existing “SecFilterInheritance Off” rules directly
354           to “SecRuleInheritance Off”. Then replace any “SecFilterInheritance
355           On” directives inside Apache Scope context locations with a new
356           SecDefaultAction directive and then import the rules that you want
357           with standard Apache Include directives.</td>
358         </tr>
359
360         <tr>
361           <td>
362             <emphasis role="bold">Ability to manage rules in Apache Scope
363             locations</emphasis>
364           </td>
365
366           <td>SecFilterImport SecFilterRemove</td>
367
368           <td>SecRuleRemoveById SecRuleRemoveByMsg</td>
369
370           <td>SecFilterRemove is now SecRuleRemoveById or SecRuleRemoveByMsg.
371           SecFilterImport is no longer supported.</td>
372
373           <td>Change all of your existing SecFilterRemove rules to
374           SecRuleRemoveById. For any existing SecFilterImport rules, you will
375           need to either copy the rule into the context or use an Apache
376           Include Directive to include entire files (such as including the
377           Core Rules files).</td>
378         </tr>
379
380         <tr>
381           <td>
382             <emphasis role="bold">Ability to verify URL/UTF8
383             Encodings</emphasis>
384           </td>
385
386           <td>SecFilterCheckURLEncoding SecFilterCheckUnicodeEncoding </td>
387
388           <td>@validateUrlEncoding @validateUtf8Encoding </td>
389
390           <td>In Mod 1.x, these were Global Directives and in Mod 2.x they are
391           Operators that can be applied selectively to each rule.</td>
392
393           <td>Add the rules that will do exactly the same as the
394           directives</td>
395         </tr>
396
397         <tr>
398           <td>
399             <emphasis role="bold">Ability to enforce a Byte Range (allowed
400             character set)</emphasis>
401           </td>
402
403           <td>SecFilterForceByteRange</td>
404
405           <td>@validateByteRange</td>
406
407           <td>In Mod 1.x, this was a Global Directive and in Mod 2.x it is an
408           Operator that can be applied selectively to each rule. In Mod 1.x,
409           this directive did not check POST payloads when multipart/form-data
410           encoding was used.</td>
411
412           <td>You can now add @validateByteRange operators to individual
413           rules. This helps if you have differences in allowed character sets
414           for different portions of the web application.</td>
415         </tr>
416
417         <tr>
418           <td>
419             <emphasis role="bold">Ability to Normalize/Transform Request
420             Data</emphasis>
421           </td>
422
423           <td>ModSecurity 1.x automatically applied the following
424           transformations:<itemizedlist>
425               <listitem>
426                 <para>On Windows only, convert \ to /</para>
427               </listitem>
428
429               <listitem>
430                 <para>Reduce /./ to /</para>
431               </listitem>
432
433               <listitem>
434                 <para>Reduce // to /</para>
435               </listitem>
436
437               <listitem>
438                 <para>Decode URL-encoded characters</para>
439               </listitem>
440
441               <listitem>
442                 <para>Converts Null Bytes to Space character</para>
443               </listitem>
444             </itemizedlist></td>
445
446           <td>
447             <itemizedlist>
448               <listitem>
449                 <para>base64Decode </para>
450               </listitem>
451
452               <listitem>
453                 <para>base64Encode</para>
454               </listitem>
455
456               <listitem>
457                 <para>compressWhitespace</para>
458               </listitem>
459
460               <listitem>
461                 <para>escapeSeqDecode</para>
462               </listitem>
463
464               <listitem>
465                 <para>hexDecode</para>
466               </listitem>
467
468               <listitem>
469                 <para>hexEncode</para>
470               </listitem>
471
472               <listitem>
473                 <para>htmlEntityDecode</para>
474               </listitem>
475
476               <listitem>
477                 <para>lowercase</para>
478               </listitem>
479
480               <listitem>
481                 <para>md5</para>
482               </listitem>
483
484               <listitem>
485                 <para>none</para>
486               </listitem>
487
488               <listitem>
489                 <para>normalisePath</para>
490               </listitem>
491
492               <listitem>
493                 <para>normalisePathWin</para>
494               </listitem>
495
496               <listitem>
497                 <para>removeNulls</para>
498               </listitem>
499
500               <listitem>
501                 <para>removeWhitespace</para>
502               </listitem>
503
504               <listitem>
505                 <para>replaceComments</para>
506               </listitem>
507
508               <listitem>
509                 <para>replaceNulls</para>
510               </listitem>
511
512               <listitem>
513                 <para>urlDecode</para>
514               </listitem>
515
516               <listitem>
517                 <para>urlDecodeUni</para>
518               </listitem>
519
520               <listitem>
521                 <para>urlEncode</para>
522               </listitem>
523
524               <listitem>
525                 <para>sha1</para>
526               </listitem>
527             </itemizedlist>
528
529             
530           </td>
531
532           <td>In Mod 1.x, the normalization functions were implicit and you
533           could not control them. In Mod 2.x, not normalization is done by
534           default. There are now “Transformation Functions” that allow you to
535           selectively apply normalizations and other features.</td>
536
537           <td>You should add the appropriate transformation functions to
538           either SecDefaultAction directive or each individual rule. See the
539           Core Rules files for examples. Keep in mind that transformation
540           functions are inherited from parent SecDefaultAction directives.
541           Care should be taken to ensure that RegEx patterns match the data
542           after transformation functions are applied. In order to avoid
543           possible unwanted inherited transformation functions, use “t:none”
544           to either not apply any transformation functions or you can then
545           specify specific transformation functions after “t:none”.</td>
546         </tr>
547
548         <tr>
549           <td>
550             <emphasis role="bold">Ability to specify an arbitrary Request
551             Header in a rule</emphasis>
552           </td>
553
554           <td>HEADER_headername HTTP_headername</td>
555
556           <td>REQUEST_HEADERS REQUEST_HEADERS:headername
557           REQUEST_HEADERS:/RegEx/</td>
558
559           <td>The HTTP_headername syntax has been superseded by the new
560           REQUEST_HEADERS:headername syntax and will not be supported in
561           future releases. The advantage to using the new syntax is that you
562           can also use RegEx in the headername portion.</td>
563
564           <td>Translate any existing HTTP_headername directives to
565           REQUEST_HEADERS:headername. Also consider consolidating header
566           checks by using Regular Expressions in the header name portion of
567           the Variable.</td>
568         </tr>
569
570         <tr>
571           <td>
572             <emphasis role="bold">Variable/Location for the entire URL Request
573             Line</emphasis>
574           </td>
575
576           <td>THE_REQUEST</td>
577
578           <td>REQUEST_LINE</td>
579
580           <td>Functions the same. The variable includes the Request Method,
581           URI and HTTP version data.</td>
582
583           <td>Translate any existing THE_REQUEST directives to REQUEST_LINE
584           directives.</td>
585         </tr>
586
587         <tr>
588           <td>
589             <emphasis role="bold">Variable/Location for Arguments</emphasis>
590           </td>
591
592           <td>ARG_name</td>
593
594           <td>ARGS:name ARGS:/RegEx/</td>
595
596           <td>Similar to the HTTP_headername situation, the advantage of the
597           new syntax is the ability to use RegEx in the argument name.</td>
598
599           <td>Translate any existing ARG_name directives to ARGS:name
600           directives.</td>
601         </tr>
602
603         <tr>
604           <td>
605             <emphasis role="bold">Accessing Request Bodies</emphasis>
606           </td>
607
608           <td>SecFilterScanPOST POST_PAYLOAD</td>
609
610           <td>SecRequestBodyAccess Phase:2 REQUEST_BODY</td>
611
612           <td>In 2.x, the directive is now called SecRequestBodyAccess and it
613           is more flexible than SecFilterScanPOST as it is able to inspect all
614           request bodies (such as PUT and XML, etc…) and not just POST
615           payloads.</td>
616
617           <td>Replace the existing SecFilterScanPOST directive with
618           SecRequestBodyAccess. For individual rules where you want to inspect
619           the request bodies, you must specify REQUEST_BODY as the variable
620           and you also must ensure that it is running in phase:2 (by either an
621           inherited SecDefaultAction setting or by explicitly specifying the
622           phase within the rule action).</td>
623         </tr>
624
625         <tr>
626           <td>
627             <emphasis role="bold">Ability to disable POST/Request buffering
628             dynamically</emphasis>
629           </td>
630
631           <td>MODSEC_NOPOSTBUFFERING</td>
632
633           <td>ctl:requestBodyAccess=Off</td>
634
635           <td>In 2.x, you can use the ctl action to turn on/off request body
636           access on a per rule basis.</td>
637
638           <td>Take any existing entries in the httpd.conf file that set the
639           MODSEC_NOPOSTBUFFERING Env variable and translate them to Mod 2.x
640           rules.</td>
641         </tr>
642
643         <tr>
644           <td>
645             <emphasis role="bold">Accessing Cookies</emphasis>
646           </td>
647
648           <td>COOKIES COOKIES_COUNT COOKIES_NAMES COOKIES_VALUES
649           COOKIE_name</td>
650
651           <td>REQUEST_HEADERS:Cookie REQUEST_COOKIES_NAMES
652           REQUEST_COOKIES_NAMES:name REQUEST_COOKIES_NAMES:/RegEx/
653           REQUEST_COOKIES REQUEST_COOKIES:name REQUEST_COOKIES:/RegEx/</td>
654
655           <td> In 2.x, you can use the “&amp;” character to “count” the number
656           of variables. While there are different ways to access request
657           cookies, the main difference between them are that
658           REQUEST_HEADERS:Cookie will include all of the “raw” Cookie data
659           while any of the REQUEST_COOKIES variable values are parsed.</td>
660
661           <td>Translate rules as follows – Mod 1.x -&gt; Mod 2.x COOKIES -&gt;
662           REQUEST_COOKIES COOKIES_COUNT -&gt; &amp;REQUEST_COOKIES
663           COOKIES_NAMES -&gt; REQUEST_COOKIES_NAMES COOKIES_VALUES -&gt;
664           REQUEST_COOKIES COOKIE_name -&gt; REQUEST_COOKIES:name</td>
665         </tr>
666
667         <tr>
668           <td>
669             <emphasis role="bold">Counting Variables</emphasis>
670           </td>
671
672           <td>ARGS_COUNT COOKIES_COUNT HEADERS_COUNT FILES_COUNT</td>
673
674           <td>&amp;ARGS &amp;REQUEST_COOKIES &amp;REQUEST_HEADERS
675           &amp;FILES</td>
676
677           <td>In 2.x, prepending the “&amp;” character will count the number
678           of variables. Example – 1.x – HEADERS_COUNT 2.x -
679           &amp;REQUEST_HEADERS</td>
680
681           <td>Translate existing 1.x rules as listed.</td>
682         </tr>
683
684         <tr>
685           <td>
686             <emphasis role="bold">Accessing HTTP Status Code</emphasis>
687           </td>
688
689           <td>OUTPUT_STATUS</td>
690
691           <td>RESPONSE_STATUS Phase:3</td>
692
693           <td>In 2.x, you need to specify both the RESPONSE_STATUS variable
694           and phase:3 with the rule.</td>
695
696           <td>Translate any existing 1.x OUTPUT STATUS rules to use
697           RESPONSE_STATUS and phase:3.</td>
698         </tr>
699
700         <tr>
701           <td>
702             <emphasis role="bold">Accessing Response Bodies/Post
703             Payloads</emphasis>
704           </td>
705
706           <td>SecFilterScanOutput SecFilterOutputMimeTypes OUTPUT</td>
707
708           <td>SecResponseBodyAccess SecResponseBodyMimeTypes RESPONSE_BODY
709           Phase:4</td>
710
711           <td>In 1.x, neither skipnext nor chain could be used on the OUTPUT
712           location. In 2.x, both actions can be used on RESPONSE_BODY</td>
713
714           <td>Translate directives/rules as follows – Mod 1.x -&gt; Mod 2.x
715           SecFilterScanOutput -&gt; SecResponseBodyAccess
716           SecFilterOutputMimeTypes -&gt; SecResponseBodyMimeTypes OUTPUT -&gt;
717           RESPONSE_BODY/Phase:4</td>
718         </tr>
719
720         <tr>
721           <td>
722             <emphasis role="bold">Cookie Normalization</emphasis>
723           </td>
724
725           <td>SecFilterCookieFormat SecFilterNormalizeCookies</td>
726
727           <td>SecCookieFormat</td>
728
729           <td>SecFilterNormalizeCookies is no longer supported as Mod 2.x
730           transformation functions can now be used to normalize all Variables
731           including Cookie data.</td>
732
733           <td>Change SecFilterCookieFormat to SecCookieFormat. When specifying
734           Cookie variables, then apply the applicable transformation functions
735           in the action field of the rule.</td>
736         </tr>
737
738         <tr>
739           <td>
740             <emphasis role="bold">Ability to skip rules</emphasis>
741           </td>
742
743           <td>skipnext</td>
744
745           <td>skip</td>
746
747           <td>In Mod 2.x – skip takes into account chained rulesets and treats
748           them as 1 rule. In Mod 1.x – skipnext treated each rule directive as
749           an individual rule regardless of whether or not they were tied
750           together as a chained ruleset.</td>
751
752           <td>Translate all skipnext rules to skip, however make sure to
753           factor in any chained rulesets that may follow and adjust the skip
754           number accordingly.</td>
755         </tr>
756
757         <tr>
758           <td>
759             <emphasis role="bold">Adding/Removing Audit Log Data on a per rule
760             basis</emphasis>
761           </td>
762
763           <td>logparts</td>
764
765           <td>clt:auditLogParts=</td>
766
767           <td>The rules function the same.</td>
768
769           <td>Translate any existing logparts actions to the ctl:auditLogParts
770           equivalent.</td>
771         </tr>
772
773         <tr>
774           <td>
775             <emphasis role="bold">Inspecting uploaded files</emphasis>
776           </td>
777
778           <td>SecUploadApproveScript</td>
779
780           <td>@inspectFile FILES_TMPNAMES</td>
781
782           <td>The main difference here is that now @inspectFile is an Operator
783           vs. a global Directive. This means that you can apply @inspectFile
784           to individual rules and use different scripts as appropriate. Also,
785           the return codes are now reversed – In 1.x, a return code of “1”
786           means that the file would be allowed. In 2.x, a return code of “1”
787           means that the file would be denied. </td>
788
789           <td>In order to scan/inspect uploaded files in 2.x, you need to
790           create specific rules that use the FILES_TMPNAMES variable (as these
791           are the names of the files that are temporarily stored on disk) and
792           then use the @inspectFile Operator on each rule. Also, make sure to
793           swap your return codes in existing scripts as mentioned in the notes
794           column.</td>
795         </tr>
796
797         <tr>
798           <td>
799             <emphasis role="bold">Memory limits for uploaded files</emphasis>
800           </td>
801
802           <td>SecUploadInMemoryLimit</td>
803
804           <td>SecRequestBodyInMemoryLimit</td>
805
806           <td>These two directives function the same.</td>
807
808           <td>Change the SecUploadInMemoryLimit directive to
809           SecRequestBodyInMemoryLimit.</td>
810         </tr>
811       </table>
812     </section>
813   </section>
814 </article>