This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
OWASP ModSecurity Securing WebGoat Section4 Sublesson 07.2
7. Concurrency -> 7.2 Shopping Cart Concurrency Flaw
Lesson overview
The WebGoat lesson overview is included with the WebGoat lesson solution.
Lesson solution
Refer to the zip file with the WebGoat lesson solutions. See Appendix A for more information.
Strategy
This WebGoat lesson demonstrates a shopping cart concurrency flaw: there is a window between when the purchase is started and the confirmation, which allows the shopping cart to be updated and get more expensive items for the same price. The user chooses an item, clicks on 'Purchase', opens another window, chooses more expensive items, clicks 'Update Cart', goes back to the original window and clicks 'Confirm', and the user has bought more items but based on the original price.
To solve this lesson, place a lock on the transaction once the purchase is initiated until it is confirmed or canceled. When a buyer has clicked on Purchase, no other transactions (Purchase or Update Cart) are allowed until Confirm or Cancel is pressed.
Implementation
The relevant data gathered from the web proxy is:
menu=800 QTY1=0&QTY2=0&QTY3=0&QTY4=0&SUBMIT=Purchase QTY1=0&QTY2=0&QTY3=1&QTY4=0&SUBMIT=Update+Cart CC=5321+1337+8888+2007&PAC=111&SUBMIT=Confirm CC=5321+1337+8888+2007&PAC=111&SUBMIT=Cancel
The data file, lesson07-2.data, looks like this with initial values:
Entry{
state = "none",
pending = "no",
time = 0
}
'State' changes when a button is pushed. The original intention was to implement a timeout also, but time did not permit this and, besides, a timeout should already be implemented in the application.
The following is what should happen during different states:
- When the Purchase button is pushed and pending is "no", set the datafile parameters as such: state = "purchase"; pending = "yes"; time = 0.
- If the Update Cart button is pushed while pending, return a non-nil error message.
- If Cancel or Confirm is pushed, set pending to "no".
- If there is a page request with no POST parameters, reset pending to "no".
Only the HTTP request is being used and the relevant parts of the Lua script, shopping-cart_07-2.lua, is as follows:
datafile = "/etc/modsecurity/data/lesson07-2.data"
retval = nil
function main()
local submit_type = m.getvar("ARGS_POST.SUBMIT", "none")
function Entry (b)
local state = b.state
local pending = b.pending
local time = b.time
if b.state == "none" then
if submit_type == "Purchase" then
state = "Purchase"
pending = "yes"
time = 0
end
elseif submit_type == "Purchase" then
state = "Purchase"
pending = "yes"
time = 0
elseif submit_type == "Update Cart" then
state = "Update Cart"
time = 0
if b.pending == "yes" then -- error; block this action
str1 = string.format("Error: attempt to update cart when purchase is pending;\n")
retval = str1
end
elseif submit_type == "Cancel" or submit_type == "Confirm" then
state = submit_type
pending = "no"
time = 0
end
-- build the data file - this should all be on one line
outstr = string.format("Entry{\n state = \"%s\",\n pending = \"%s\",
\n time = %d\n}\n\n", state, pending, time)
end
dofile(datafile)
-- write back to file
local fh2 = io.open(datafile, "w+")
fh2:write(outstr)
fh2:flush()
fh2:close()
return retval
end
Here is the ModSecurity rule file, rulefile_07-2_shopping-cart-concurrency.conf:
SecRule ARGS:menu "!@eq 800" "phase:2,t:none,skip:2" SecRule &ARGS_POST:SUBMIT "@eq 0" "nolog,skip:1" # action is triggered if script returns non-nil value SecRuleScript "/etc/modsecurity/data/shopping-cart_07-2.lua" \ "phase:2,t:none,log,auditlog,deny,severity:3,msg:'Luascript: Concurrency -> \ Shopping Cart: purchase is pending',tag:'CONCURRENCY', \ redirect:/_error_pages_/lesson07-2.html" SecAction "phase:2,allow:request,t:none,log,auditlog,msg:'Luascript: \ Concurrency -> Shopping Cart: purchase is NOT pending'"
When a transaction is pending, the user will get this message:
Comments
- This lesson solution shows how Lua can be used to handle application state; in this case, a purchase that utilizes a shopping cart.
