Cross-Site Request Forgery (CSRF) Complete Guide with Examples
I am a relatively new Bug Bounty Hunter and do not claim to be a professional! Just trying to share my experience from the perspective of a newbie. I expect all readers to have basic understanding of CSRF.
Cross-Site Request Forgery (CSRF) was one of the first vulnerabilities that I learned at the beginning of my Bug Bounty journey. Combined with social engineering, It is a vulnerability that allows attackers to commit/perform unintended actions on target’s account. Like most vulnerabilities, the impact of CSRF ranges from Low — High. From simply enabling/disabling newsletter subscription to initiating fund transfer, the attack vector of this vulnerability is endless. In this Medium article, I will be explaining CSRF in-depth based on my personal bug bounty experience. The article will be divided into the following sections:
- Introduction (Above)
- Attack Vector — Where to Look
- Confirming CSRF
- Tips and Tricks
When I first started to learn new vulnerabilities, the most frequent question that came to my mind is “Where do I start looking?”. Due to the nature of bug bounty hunting, time-sensitive, it is important for us to be as efficient as possible when searching for vulnerabilities, therefore we shall always identify the possible attack vector of the bug we are trying to discover. According to the simple definition above, we could already tell that the attack vector for CSRF is vast. Basically, every endpoint that performs specific action is susceptible to CSRF. Endpoints like; Payment related, newsletter subscription, notification, adding or removing actions (Friends, Post, etc.) and many more might be exploitable. Since the attack vector is vast, it has been an industry standard to implement CSRF protection on critical endpoints or even all actions related endpoints, but this does not close our opportunity to finding CSRF.
After identifying the attack vector, we shall continue to tamper with the headers and request body to confirm CSRF. My thought process when testing endpoints is to pick on a sample endpoint, from here we should identify if there is CSRF protection implemented. Look for CSRF Tokens either in the header or body request. If present, start tempering with it:
- Leave CSRF Token empty
- Use other account’s CSRF Token
- Delete header or request body CSRF Token entirely
If the above method is successfully, proceed to the next phase!
A lot of companies integrate multi-layer protection. On top of implementing CSRF Token, only whitelisted domains are allowed for both Origin and Referer header, therefore both headers play an equal part in blocking CSRF attack by only allowing whitelisted domains. Therefore, the next step is to alter both Origin and Referer headers. A good rule of thumb is to do the following:
- Change header to a completely distinct domain (e.g. https://attacker.com)
- Change the Top Level Domain (e.g. https://company.eu)
- Change it into a subdomain (e.g. https://company.com.yourdomain.com)
*Since most companies focus mainly on the Origin Header, test the above to the Origin Header first then proceed to the Referer Header.
Being able to change the Content-Type is also crucial in exploiting CSRF vulnerability. The main Content-Type used in CSRF vulnerabilities are ‘text/plain’ and ‘application/x-www-form-urlencoded’. Make sure to tamper with the Content-Type Header and confirm that the server is still accepting the above content type. Being able to alter Content-Type will allow us to create an easier PoC!
Another thing to keep in mind is Cookie ‘Same-Site’ Attribute. If our target company implements ‘Same-Site: Lax’ for their cookies, then it will be impossible for us to exploit CSRF. Although this is the case, most companies probably leave their Cookie ‘Same-Site’ attribute to default, which starting from Chrome 84, will be treated as ‘Same-Site: Lax’. This can still be bypassed using the 2 minutes rule. If a Cookie ‘Same-Site’ attribute is set to default, there is a 2 minutes window where all of the cookies will be included from a third-party when new cookies are set by the server. Therefore, what we need to do is to chain logout/login CSRF with our current CSRF. Nonetheless, if the above requirement has been satisfied, I recommend testing the ‘plain’ CSRF first. If the CSRF does not fully send your cookie, then resort to chaining logout/login CSRF.
I could not guarantee that the above steps would surely produce CSRF, there are many complications and emerging technologies that might render my above method partially useless. Therefore, try at your own risk, this is just points that I learned from my experience. In addition, there are some other tricks that I could not dive into deeper in this article such as; CSRF with JSONP, IDN homograph attack, Chaining Vulnerabilities and etc. Bug bounty is a highly practical field, therefore I would recommend all of you guys to just try and practice the vulnerabilities you are learning, legally. There are tons of great resources available online, starting from official documentation, hacker’s reports and writeups. Read all of them multiple times! Write in the comments below what other topics that you want me to discuss. If you think that this article is helpful, drop a clap, comment, and follow me for more. Happy Hacking & Godspeed!