Search code examples
phplaravellaravel-4laravel-5csrf

CSRF (Cross Site Request Forgery) does not work as expected in Laravel


I am learning Laravel using "Laravel Code Bright". In the "Form Security" section of this book, it talks about how Laravel generates secret hidden code to prevent "CSRF - Cross Site Request Forgery" when using the Form::Open() method to generate form inputs.

I tried an example to access the route that will process the form using an external form. First I did it without the "before"=>"csrf" filter attached to the route and i got the answer I was expecting, that is the external form was able to access the route.

For the second test, I added the "before"=>"csrf" filter to the route. When i clicked the submit button of the external form, the page kept on loading for a long time and it gave up without showing any results, the page was blank. It means that the "before"=>"csrf" filter prevented this external form from accessing the route.

For my third test, I copied the hidden-token of the original form (by viewing the browser's source code page) and added it to the external form and tried it again and by clicking the submit button this external form gave me the same results as the first test, that is it showed the results meaning that it was able to access the route through the hidden token I added from the original form.

My understanding is that if you add a hidden-token to your forms to prevent "CSRF" and the attacker views the browser's source page and copied the hidden-token and adds it to his form, he can still target your routes, since the hidden-token will always be visible in the browser's view source page.

My question is, is there a better way of preventing "CSRF" even if the attacker copies the hidden-token and adds to his forms?

The external form am using is outside the root folder of Laravel. I also copy the value of the "action" attribute of the original form in order to target the route of the original form. I copy it from the browser's view source page.


Solution

  • Your tests are correct - but your understanding is wrong.

    The whole point of CSRF is to prevent a hacker from creating a form on their page that works on your page for another user. They can always copy a form that works for themselves - because they know their own CSRF code - but they can never know another users CSRF code.

    Without CSRF:

    The way CSRF attacks work is your website has a form to "transfer money". The attacker puts a fake copy of your "transfer money" form on his page.

    If User A is logged into your website, and goes to the attackers page, the attacker can trick the user into submitting the "transfer money" form and transfer himself lots of money.

    Because User A is logged into your website, the transfer form will work, since they have a valid session. But there is no CSRF check - so the hackers 'copied' form will work for User A.

    But with CSRF:

    The attacker copies the form from your website - but they dont know the CSRF code for User A. They only know the code for themself. They can basically* never get that code. So when User A submits the 'fake' "transfer money" form on the hacker page - it will fail - since the hacker cannot include the CSRF token since they dont know it.

    This is how you protect against CSRF attacks.