The Chrome update in 2018 introduced SameSite Cookie Attribute; not really a new invention but just the shift of the default settings. Prior to the update, the user-agents sent all the cookies to a site it was instructed to, but this behavior is only valid now if the developer specifically sets the SameSite to None, otherwise, the Lax will be used as a default. In simple words, this means if you are trying to exploit CSRF, it wouldn’t be successful because the cookies won’t be sent automatically by the browser as it used to be (if sameSite attribute is not set).
Before reading further, it’s vital to have a fundamental understanding of what CSRF means in the first place. You can read about that here:
SameSite is an attribute of Cookies that can have three values:
Lax (the new Default) – which means that the Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating to the origin site (i.e. when following a link).
Strict – means no cookies at all will be sent cross-site.
None – means cookies will be sent in all condition even if the same site condition isn’t met.
The new default mitigated a number of attacks including Cross Site Request Forgery.
Same-Site Cookies draft-ietf-httpbis-cookie-same-site-00 Abstract This document updates RFC6265 by defining a "SameSite" attribute which allows servers to assert that a cookie ought not to be sent along with cross-site requests. This assertion allows user agents to mitigate the risk of cross-origin information leakage, and provides some protection against cross-site request forgery attacks. RFC6265bis
The SameSite has been implemented on almost all major browsers at the time of this writing, and this has made CSRF a dead weapon. Since this blog is intended to state some ways around this, it won’t concentrate on the definitions of them mainly.
So, is CSRF really dead?
I believe there are a number of ways to bypass this which include attempts to bypass the Same Origin Policy itself, but this article outlines the power of CSRF without such attempts. I will state some of the things we can still do (without actually bypassing the SOP).
Changing GET to a POST
In most of the instances, we have seen that state-changing actions are carried by the HTTP requests with POST very types, but I have also dealt with many examples where changing POST method to a GET works fine.
XSS to the rescue!
If you find XSS in your target, try to escalate the impact. It is possible to steal CSRF tokens and carry out POST requests using XSS. In such cases the site will be treated as same-site and cookies will be sent even if LAX or Strict types are used.
OOS sub-domains help in-scope hunt
Luckily, subdomains are counted under same site. This means vulnerable.com and sub.vulnerable.com are considered same sites (based on document.domain(), the origin is same for both). Didn’t find XSS in the main domain? Try finding in subdomains.
If subdomains are out of scope, you can still use them to find vulnerability if it affects the main domain.
Sometimes, a website handles the GET request but changing the method type directly doesn’t indicate any chances of that at the first glance. I think, a lot of people do not realize the weight of this point. I have seen many cases where a simple extra step of creativity has manifested the vulnerability where a thousand people may return singing the rhymes of loss. Let us see an example of what such an extra observation could be..
The code below does a state changing action:
POST /doSomething HTTP/1.1 Host: vulnerablesite.com . . csrf=CSRF-Token&parm=value
HTTP 200 OK
Changing POST verb type in this request to GET will look something like this:
GET /doSomething?csrf=CSRF-Token&parm=value HTTP/1.1 Host: vulnerablesite.com . .
HTTP 404 Not Found
Please note that, at this point we are not trying to bypass CSRF. But it is interesting to note that the server returns a 404 on a GET to the same endpoint, but developers have their own logic and this could be a fair possibility that there should be an extra parameter and a value to be able to make this a valid request, for example:
GET /doSomething?csrf=CSRF-Token&parm=value&userID=123 HTTP/1.1 Host: vulnerablesite.com . .
HTTP 200 OK
The intention is to demonstrate is digging deep may manifest those vulnerable layers of security which is almost impossible to detect at the first hand. The methodology and a black-box testing against these may vary but it depends on how well you understand the program.
I’ve attempted to boil down the mentioned bypass into easiest manner possible but to really understand anything listed in the article, you’d need to know other basic concepts such as the working of HTTP requests etc. If you still seem to have any questions about the covered areas, please comment below and we’ll respond to you.