Re: [mod-security-users] LT operator seems to fail to correctly compare two variables
Brought to you by:
victorhora,
zimmerletw
From: John W. <joh...@ac...> - 2009-11-23 20:47:05
|
Hi, As suggsted, following on from my previous posting, I have attached debug log excerpts illustrating this failure to compare two variables in a modsecurity rule, which I now believe is due to macro expansion failure on the right hand side of the comparison operator (LT in this example). Can someone more knowledgable read these logs, and confirm if this is the issue that I'm experiencing ? Simple LT comparison works as expected when comparing a variable (TX.tokexp) to a constant (20): #set the variable(s) up first SecAction "pass,phase:1,setvar:tx.tokexp=10" #This rule should obviously fire, and does so SecRule TX:tokexp "@lt 20" "phase:1,deny,t:none" Debug log excerpt when working as expected: [/protected1.txt][4] Initialising transaction (txid SwrsFsNKN8IAAAm8PQkAAACV). [/protected1.txt][4] Transaction context created (dcfg 624170). [/protected1.txt][4] Starting phase REQUEST_HEADERS. [/protected1.txt][9] This phase consists of 3 rule(s). [/protected1.txt][4] Recipe: Invoking rule f478d0; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "564"]. [/protected1.txt][5] Rule f478d0: SecAction "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,pass,setvar:tx.tokexp=10" [/protected1.txt][9] T (0) lowercase: "/protected1.txt" [/protected1.txt][9] T (0) replaceNulls: "/protected1.txt" [/protected1.txt][9] T (0) compressWhitespace: "/protected1.txt" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "unconditionalMatch" with param "" against REQUEST_URI. [/protected1.txt][9] Target value: "/protected1.txt" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][9] Setting variable: tx.tokexp=10 [/protected1.txt][9] Set variable "tx.tokexp" to "10". [/protected1.txt][2] Warning. Unconditional match in SecAction. [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "564"] [/protected1.txt][4] Rule returned 1. [/protected1.txt][9] Match -> mode NEXT_RULE. [/protected1.txt][4] Recipe: Invoking rule f48230; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "565"]. [/protected1.txt][5] Rule f48230: SecAction "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,pass,setvar:tx.timeepoch=20" [/protected1.txt][9] T (0) lowercase: "/protected1.txt" [/protected1.txt][9] T (0) replaceNulls: "/protected1.txt" [/protected1.txt][9] T (0) compressWhitespace: "/protected1.txt" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "unconditionalMatch" with param "" against REQUEST_URI. [/protected1.txt][9] Target value: "/protected1.txt" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][9] Setting variable: tx.timeepoch=20 [/protected1.txt][9] Set variable "tx.timeepoch" to "20". [/protected1.txt][2] Warning. Unconditional match in SecAction. [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "565"] [/protected1.txt][4] Rule returned 1. [/protected1.txt][9] Match -> mode NEXT_RULE. [/protected1.txt][4] Recipe: Invoking rule ee9bb8; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "571"]. [/protected1.txt][5] Rule ee9bb8: SecRule "TX:tokexp" "@lt 20" "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,deny,t:none" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "lt" with param "20" against TX:tokexp. [/protected1.txt][9] Target value: "10" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][4] Rule returned 1. [/protected1.txt][9] Match, intercepted -> returning. [/protected1.txt][1] Access denied with code 403 (phase 1). Operator LT matched 20 at TX:tokexp. [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "571"] [/protected1.txt][4] Initialising logging. [/protected1.txt][4] Starting phase LOGGING. [/protected1.txt][9] This phase consists of 0 rule(s). [/protected1.txt][4] Audit log: Logging this transaction. Then try it the way I need it to work by comparing two variables (TX.tokexp to TX.timeepoch) rather than the previous example of comparing a variable to a constant: SecAction "pass,phase:1,setvar:tx.tokexp=10" SecAction "pass,phase:1,setvar:tx.timeepoch=20" #This rule should also fire, and does NOT SecRule TX:tokexp "@lt %{tx.timeepoch}" "phase:1,deny,t:none" Debug log excerpt when NOT working as expected: [/protected1.txt][4] Initialising transaction (txid SwrsicNKN8IAABw8QyMAAACV). [/protected1.txt][4] Transaction context created (dcfg 624170). [/protected1.txt][4] Starting phase REQUEST_HEADERS. [/protected1.txt][9] This phase consists of 3 rule(s). [/protected1.txt][4] Recipe: Invoking rule f478c8; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "564"]. [/protected1.txt][5] Rule f478c8: SecAction "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,pass,setvar:tx.tokexp=10" [/protected1.txt][9] T (0) lowercase: "/protected1.txt" [/protected1.txt][9] T (0) replaceNulls: "/protected1.txt" [/protected1.txt][9] T (0) compressWhitespace: "/protected1.txt" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "unconditionalMatch" with param "" against REQUEST_URI. [/protected1.txt][9] Target value: "/protected1.txt" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][9] Setting variable: tx.tokexp=10 [/protected1.txt][9] Set variable "tx.tokexp" to "10". [/protected1.txt][2] Warning. Unconditional match in SecAction. [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "564"] [/protected1.txt][4] Rule returned 1. [/protected1.txt][9] Match -> mode NEXT_RULE. [/protected1.txt][4] Recipe: Invoking rule f48228; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "565"]. [/protected1.txt][5] Rule f48228: SecAction "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,pass,setvar:tx.timeepoch=20" [/protected1.txt][9] T (0) lowercase: "/protected1.txt" [/protected1.txt][9] T (0) replaceNulls: "/protected1.txt" [/protected1.txt][9] T (0) compressWhitespace: "/protected1.txt" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "unconditionalMatch" with param "" against REQUEST_URI. [/protected1.txt][9] Target value: "/protected1.txt" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][9] Setting variable: tx.timeepoch=20 [/protected1.txt][9] Set variable "tx.timeepoch" to "20". [/protected1.txt][2] Warning. Unconditional match in SecAction. [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "565"] [/protected1.txt][4] Rule returned 1. [/protected1.txt][9] Match -> mode NEXT_RULE. [/protected1.txt][4] Recipe: Invoking rule ee9998; [file "C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf"] [line "568"]. [/protected1.txt][5] Rule ee9998: SecRule "TX:tokexp" "@lt %{tx.timeepoch}" "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,deny,t:none" [/protected1.txt][4] Transformation completed in 0 usec. [/protected1.txt][4] Executing operator "lt" with param "%{tx.timeepoch}" against TX:tokexp. [/protected1.txt][9] Target value: "10" [/protected1.txt][4] Operator completed in 0 usec. [/protected1.txt][4] Rule returned 0. [/protected1.txt][9] No match, not chained -> mode NEXT_RULE. >From looking at the debug log, it would appear that no macro expansion is being performed for %{tx.timeepoch} in the rule SecRule "TX:tokexp" "@lt %{tx.timeepoch}" "log,auditlog,status:403,phase:1,t:lowercase,t:replaceNulls,t:compressWhitespace,deny,t:none" and hence the Less Than operator is trying to compare a numeric value for TX:tokexp (which is macro expanded as expected) with a string value of "%{tx.timeepoch}" which hasn't been macro expanded for some reason. The reason I'm thinking this, is that in the debug log there is no line showing a macro expansion performed on %{tx.timeepoch}, and it shows "Executing operator "lt" with param "%{tx.timeepoch}" against TX:tokexp." which would suggest to me that it has not macro expanded %{tx.timeepoch}, where it clearly is performing macro expansion on "TX:tokexp" as there is a line showing "Target value: "10". Is this expected behaviour? I would guess not as Brian Rectanus assumed the macro expansion would work in an example rule he wrote for a previous question of mine, which had the rule : SecRule TX:tokexp "@le %{TIME_EPOCH}" "phase:1,deny,t:none" Which does not seem to work for exactly the same reason, which is that the %{TIME_EPOCH} macro is not expanded correctly. Does anyone have any ideas how to work around this limitation and compare two variables in a modsecurity rule ? Thanks, John ----- Original Message ----- From: Brian Rectanus [S+] To: mod...@li... ; joh...@ac... Sent: Monday, November 23, 2009 5:57 AM Subject: RE: [mod-security-users] LT operator seems to fail to correctly compare two variables The debug log is you friend here. Crank the SecDebugLogLevel to 9 and see what is going on. The debug log should show you all macro expansions and values used. -----Original Message----- From: John Wigley [joh...@ac...] Received: 11/22/09 9:48 PM To: mod...@li... [mod...@li...] Subject: [mod-security-users] LT operator seems to fail to correctly compare two variables Hi, I've been trying to diagnose some epoch time comparison rules which are failing to fire as expected, and in the process of debugging I've hit upon what seems to be a bug in the numeric operators. This seems hard to believe, but I cannot identify why the first rule fires as expected but the 2nd does not. Can anyone shed any ideas on what I'm doing wrong on this ? Build is 2.5.11 Win32 from ApacheLounge. #set the variable(s) up first SecAction "pass,phase:1,setvar:tx.tokexp=10" #This rule should obviously fire, and does so SecRule TX:tokexp "@lt 20" "phase:1,deny,t:none" # Then try it the way I need it to work by comparing two variables rather than the previous example of comparing a variable to a constant SecAction "pass,phase:1,setvar:tx.timeepoch=20" #This rule should also fire, and does NOT SecRule TX:tokexp "@lt %{tx.timeepoch}" "phase:1,deny,t:none" These rules aren't actually what I'm trying get to work because they're obviously pointless, but they illustrate the problem I'm having. Thanks for any inspiration, John |