In the recent Getting Real with Realex discussions I raised the issue of Cross Site Request Forgery (CSRF) and how the use of a second password for the refund request would prevent it. I received some feedback requesting that I explain CSRF and how it could be used to exploit an back-office application that was not exposed on the Internet.
This blog post will detail a simple example of how a CSRF vulnerability could be used by an external party to perform a refund using a back-office application. Remember that this back-office application is not accessible from the Internet. The back-office application is running on a server on an internal network and is only accessible by employees within that office environment. To start with, we will look at how an internal user would perform a refund using our example back-office application. They would log into the application and find the transaction they want to view. The following mock-up will illustrate how the transaction view might look.

In the above illustration you can see there is a button to refund the transaction. When the user clicks on this button the web browser will submit a HTTP POST to the server to request it to carry out the refund. The HTTP POST would generate a request that looks something like this:
POST http://app/transaction.php HTTP/1.1
...
...
...
transactionID=105
From the above HTTP Request you can see that the transaction ID is passed as a parameter to the server to indicate which transaction the user requests be refunded. When the user clicks on the refund button the refund is executed and the user is then presented with the following screen.

Now we know how the application works when a valid user is using it. In order to do the above refund the user would need to be logged into the application and have permission to carry out refunds. Based on our knowledge of how the system works we can create a URL that will execute the refund request on the server.
http://app/refund-transaction.php?transactionID=105
Obviously this URL will only work when executed by the user who is logged into the application and has permission to carry out refunds. If the user was to open a new tab in their web browser and paste in this URL then the refund would be executed. The goal of an attacker hoping to exploit CSRF is to get the user's web browser to make a request to the above URL. There are various approaches that can be taken to achieve this. We will keep our example simple and look at a common approach.
<img src="http://app/refund-transaction.php?transactionID=105" border="0" width="1" height="1">
The above HTML code, when rendered by a web browser will submit a request to the URL contained in the "src" attribute. If the attacker can get this HTML to be rendered by a legitimate user who is logged into the back-office application, then the request would be executed with the correct permission and the refund carried out. The web browser will attempt to display the result of the request as a 1x1 image. This means the legitimate user will not see any visual indication that the refund has occurred only an small icon displayed by the web browser to indicate that it cannot load the request image.
The next step with this exploit is to find a way to get this HTML rendered by the victims web browser. There are various different options for an attacker to use to achieve this such as:
- Placing the HTML code within an email that is sent to the victim
- Placing the HTML code on an external website and getting the victim to visit this site
- Getting the victim to view the HTML via the user of a social networking site
- Getting the victim to view the HTML on a website that they trust which contains an Cross Site Scripting (XSS) vulnerability
The above example has been simplified to help illustrate the process. Hopefully after reading it you can see the security benefit of requiring users to re-authenticate when they wish to perform certain actions. There are other methods of protecting against CSRF but requiring the user to authenticate themselves again is a simple, effective solution. Use of a secondary password can cause confusion with users and generate more support requests as a result, a point made to me by David Rice in a recent discussion. As with most things in the world of security its all about risk and balancing security needs with usability needs. Depending on your specific business the risk of CSRF and the cost of implementing a solution may well outweigh the usability issues encountered with the above solution. I would go as far as saying that a perfectly secure application would be unusable and a perfectly usable application is insecure.
Note: I have used HTTP GET rather than HTTP POST in the above example to keep things simple so I could illustrate the concept. It is worth noting that configuring your application to only accept HTTP POSTs does not prevent CSRF. CSRF is possible with HTTP POST but it is a little more complicated.
Still not convinced? Take a look at these two real world examples of CSRF -
Dave
--
If you liked this article then you can:
Related Blog Posts: