What is Cross-Site Request Forgery (CSRF)
Cross-Site Request Forgery is defined as an application on a web server being left vulnerable to background requests from otherwise unauthorized users. Simply put, a well-meaning user unknowingly executes a malicious request from one web site, while logged into the other web site. The site they are logged into is the location of the cyber-crime and the other web site is the malicious site that presents the harmful request.
To further understand how CSRF can affect you, we will take a look at a common online bank account example.
Let’s say you have an online account at your favorite bank and you have logged into the bank’s web site because you want to check your account balances before you leave for your Winter vacation. Before you get a chance to check your balances and logout of the bank’s web site, you notice an email from your travel agent and you leave your browser (still logged into the bank web site). After you read the travel agent email, you decide to check other emails. One email rather catches your eye and you want to learn more about the content, so you click on the link in the email that takes you to the site. Well, as good as the site looks, in the background it has been hard coded to send a fund transfer request that moves money from your account to the account of a Cyber Bad Person within the bank that you just happened to be logged into. Because you are logged in, the fund transfer request is not challenged and the swindler has managed to transfer your money to their account without you knowing that you did it.
How to Exploit a CSRF Vulnerability
A bank web-site is configured to accept requests that are sent to a specific URL with parameters to supply the data for the requested transaction. For example, a request sent to the onlinetransfer URL with parameter values for Account, Routing and Amount will perform a fund transfer from the Account to the Routing account for the specified Amount. In addition to the request, a session identifier stored in a cookie is also sent with the request to identify the request as coming from an authenticated bank user. A would be “Bad Person” learns about this request syntax and wonders if there is a way to get a bank customer to execute this transfer fund request to move money from the unsuspecting victim’s account to their own account. They would create their own web page that executes the transfer request when their page is loaded. Of course the event would only take place if the user was also authenticated to the bank’s web site. The attacker sends out intriguing emails to 100s of thousands of people in the hopes that some of them would be curious enough to accept the invitation to visit the site. When already logged in user does access the “bad” site and cause the malicious request to be sent, the session cookie verifying the authenticity of the user is also sent so the bank doesn’t challenge the request and makes the transfer. To summarize, there are three items that need to be in place for a CSRF attack to take place:
- Victim must be logged into the target site to be attacked
- The target site does not perform re-authentication before each sensitive transaction
- User opens the malicious web-site to allow the link to be sent to the bank
How to protect against CSRF
Begin by searching the web application for functionality that could lead to an unwanted malicious action. Next determine all of the parameters needed for the action to succeed and decide if an attacker can easily determine or guess that proper values. If so, this is a CSRF vulnerability.
The easiest solution that will take care of most attack attempts is to require and sensitive transactions to be initiated through a POST request as opposed to a GET request. The POST method is much more difficult (but not impossible) to breach with a CSRF attack. Also make it as difficult as possible for an attacker to learn what the request is supposed to look like.
- Require re-authentication before any sensitive transaction is completed
- Require out-of-band confirmation – user has to respond to a cell phone text message to authorize the transaction
- User transaction specific nonces
How nonces help – when a user wants to make a money transfer they click on a link, prior to rendering this page, the web app generates a cryptographically random number (nonce) and stores it in the server side session as well as in the form being used to transfer money as a hidden field. The user then fills out the routing number, account and transfer amount and when the transfer request is submitted to the server, the nonce from the hidden field is also submitted. Prior to completing the money transfer, the server application will compare the delivered nonce to the one stored in the user’s server side session. If they match, the transaction is allowed. Before the use of the nonce, the attacker was easily able to populate the parameters of the transfer request being sent. Considering that the nonce is only created after the login and before the transfer request, it would be extremely difficult for an attacker to acquire the nonce. Particularly if the attack scripting has been setup to automatically run when the user clicks the link and the attacker is not involved.