The dead CSRF says, “I am not dead…”

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.

Don’t rush

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.

11 thoughts on “The dead CSRF says, “I am not dead…”

  1. I do consider all of the concepts you’ve introduced to
    your post. They’re very convincing and will certainly work.
    Still, the posts are too brief for starters. May you please lengthen them a little from subsequent time?
    Thank you for the post.

    1. Hi! So I’ve edited the blog a bit but I don’t think the underlying topic could be elaborated. Nonetheless, we might consider writing on similar topics like SameSite cookie attribute and so on with much more detail. I’ve also added links to other articles that you must know to understand the theme in depth. If you still have any questions , please let us know and we’ll be happy to provide details. -MO

  2. Great, this website provides us with useful information. Fortunately, I found your website by accident, and I am surprised why this coincidence did not happen in advance! Thank you for writing this article, and the rest of the site is also very good. We linked to this great article on our website. Keep good writing.
    Noach William Thompson

Leave a Reply

Your email address will not be published. Required fields are marked *