This past Fathers Day my fiancé and I decided to take my Grandfather out to eat. When we got to the restaurant, the valet parking attendant gave me a ticket and proceeded to park my car. Once we entered the restaurant, the hostess gave us a pager to notify us when our table was ready. It’s in these routine exchanges that a sensible solution to the ever growing Cross-Site Request Forgery, or CSRF, attacks can be formulated. Let’s first define what CSRF is.
The Open Web Application Security Project defines CSRF as “an attack that tricks the victim into loading a page that contains a malicious request”. (https://www.owasp.org/index.php/CSRF) Basically, an attacker can make a request using your identity to a site that you are already authenticated on without your consent or knowledge. For example, in 2006 Netflix’s website was vulnerable to this exploit. It was possible for an attacker to add/remove movies from your queue, change your name, address, email address, and password on the account! In 2007, even Gmail fell victim to this type of attack which allowed the attacker to access a user’s contact list. All that one has to do is access the rogue code while having an active session to the vulnerable site. To put this into perspective, anyone who uses webmail (i.e. Gmail) and has an active session going in the browser while surfing other sites could be subject to such an attack if that webmail service is vulnerable to this exploit! Although we won’t examine the methods these acts are carried out by, we will now discuss the ways in which we can prevent such a back door request from even happening.
Getting back to the Fathers Day dinner for my Grandpa, we will recall that a pager was given to me to notify me of when my request for a table to eat could be fulfilled. When my table was ready, the pager went off and the hostess made sure it was the same pager she had actually alerted. Can this same concept be used in the programming world to foil a CSRF attack? Actually it can!
First we must generate unique and unpredictable tokens that are issued to an individual user’s session that will be appended to each request. How these unpredictable tokens are created could be considered an entirely different area of study due to the massive complexity in generating truly random values in computers. It is important to understand that this process is only as strong as your weakest link, so be sure to do your research on generating random values programmatically! For simplicity’s sake let’s just say we have an algorithm to make a truly random token. We then give the user this token by creating a session cookie. How is this secure? Cross-domain rules make it impossible for foreign domains to read a cookie’s value. We do, however, need to do one more thing to make sure this process is air tight. We will want to embed this token in a hidden field of the request so that it is not exposed to the attacker. Including the token in the URL could give attackers the pieces they need to crack this validation! Finally when handling the request, you can validate the token cookie against the requests embedded token, and if they match then we can say with great confidence this was an intended request.
In conclusion, my meal was fantastic and deservedly so, my grandfather feasted like a king. When the pager went off and the hostess validated my request for a table of 3, I knew that no one had taken my spot in line. I also was relieved when I requested my car from the valet attendant, who matched my unique ticket to their records and successfully brought me my car. No one else could easily have requested and obtained my car without having my ticket. What is interesting about this type of vulnerability is that all the responsibility falls on the developers of the application. For example, staying logged into Netflix while browsing other sites is not reckless and should be an expected behavior for your site. Do everyone a favor and employ this challenge token protocol into your application. It will protect your users from nefarious requests and help provide the best experience possible.