10 September 2005
Programmers are always told, "Thou shalt never trust User Input".[?] Naturally most programmers don't listen.
An instance of this problem is the way many e-commerce applications are built. All web-based stores use "cookies" and/or "hidden fields" to link one page to the next as the customer adds objects to the virtual shopping cart and proceeds through the virtual checkout. Both of these techniques are client-side, which means they are trivial for a customer to subvert.
A well-designed application would store something like "2*ABCD,1*DEFG" which would record the quantity and id of every item the customer wanted. If the customer edits this data, they simply end up with different products in their cart. On the other hand, a badly-designed application would store something like "2*Turtle Doves=$12,1*Partridge=$8" which makes the critical mistake of recording the price. If the customer edits this data, they can pay whatever they want at the checkout.
Who would rely on the customer to keep an accurate record of what every item cost? Well, quite a few places. Want some audio books at prices you specify? Or what about tickets to anything from Pavarotti to Motorhead? What prices do you want to pay for art supplies? How about computer hardware and software? Finding more is trivial (step 1, step 2).
There are two methods of solving this vulnerability. The obvious one is to eliminate the price information from the client's side. This approach means that the price is looked up from the server-side database on every page which requires it. Unfortunately many architectures make this difficult; the credit card payment code may be on a different system than the store and thus may not have easy access to the data. A simpler approach is to keep the price information on the client's side, but also store an MD5 hash of the data in a second hidden field. Any page using this data can take the untrusted data, rehash it and compare the hash with the provided version. To prevent the customer from generating their own valid hashes for changed data, the data would always be appended to a secret salt prior to being hashed. This is an extremely effective wrapper that can be easily applied to any online store.
The four stores mentioned above have been notified of their security problems. As always, it will be interesting to see if they a) fix their systems, b) threaten me, c) ignore/deny the problem.
Update: Within minutes of sending out the notifications, I got knowlegable responses from the audio books store and the art supplies store. Both stores confirmed they were aware of the problem, and that it would be fixed soon. A few days later I got a phone call from a programmer at the ticket store asking me to check to see if the vulnerability was still there. They'd added some very effective hashes and thus closed the issue. A check of the hardware&software store shows that they reprogrammed their systems too. Four out of four, I'm impressed!