(Very Simple) Checkout Manipulation Fun with PayPal
Many small businesses (and to be fair, several large businesses as well) use an external vendor to handle their checkout process. There may be many reasons to do so, such as reducing a company’s PCI footprint, using a more established checkout product to more quickly deploy applications, or not having the security staff to be able to properly protect an in-house developed checkout process.
One of the bigger players in the market is PayPal. From a third-party application perspective, users can use PayPal to either login to their ‘PayPal’ account or to act as a credit card processor. When a user finishes the checkout process in the custom application, they are redirected to PayPal to enter payment information. After the PayPal process is completed, you receive a receipt and are redirected back to the application.
This method of checkout can be secure, but many developers fall into the trap of generating the checkout value and PayPal redirection link on the client side, rather than server side. As many of you know, it is trivial to modify a value on the client-side browser or an intercepting proxy. Below, I will show you an example of an application that implements client-side checkout values.
In this modified example of a real-world application, you visit the page to register for an online class. After entering user account details, the type of class you’d like to visit, and selecting the payment method, the web page sends the following request with the original price of $1500:
As a pentester, we would try to modify that highlighted section to change it to a cheaper value (lucky $13), as noted in the below request. Feel free to use your intercepting proxy of choice (choosy pentesters choose Burp):
We get the following response with the PayPalRedirectUrl to take us to the PayPal checkout process, with the server responding with the updated price. Behind the scenes, the server has taken the updated price value, generated a PayPal URL, and given us the redirect URL to pay for the lowered $13 price tag:
When the PayPal site loads in our browser, we see the following screen with our modified price of $13!
It really was as easy as modifying that one value! PayPal only processes a value based on what it receives. If the value of the cart comes from the client and not the application server, PayPal (or the payment processor of choice) has no way of telling the difference.
To recap, the application took the price from the client, ran the price into the PayPal URL generator on the server, and redirected the browser to the PayPal checkout with the updated (lower price).
To remediate this issue (and many other cart manipulation issues), the price of the cart needs to be controlled by the server and should not be modified by the client. If the application generates a URL to redirect to a third-party processor, ensure that the price of the cart exchanged between any payment processor is handled on the backend with no client interaction.