Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ltrain's avatar

CSRF Security - Single Page Apps

So I get that for single page apps you can just store the token either in a meta tag or a javascript variable to use and submit it along with any ajax requests that need it and it works.

My question is is it possible for someone to grab the token off the page via something like a curl request or get access to javascript global variables from another tab or something like that, and then submit their request with the stolen token assuming the session is still active? I would think no but right now I'm not 100% sure. Assume it's only from another location and xss attacks are prevented via encoded output for this question. I def feel like I'm missing something here..

0 likes
12 replies
4jZW7jVSdS4U6PC's avatar

You should start with the fact that you cannot rely you entire security only upon CSFR on a SPA @Itrain even because there're some many method to exploit the CSRF.

To make it secure, your server needs to set a token in a JavaScript readable session cookie on first HTTP GET request. On subsequent non-GET requests the server can verify that the cookie matches on your token in HTTP header, and therefore be sure that only JavaScript running on your domain could have read the token. The token must be unique for each user and must be verifiable by the server in order to prevent that someone inject JS code and making up its own token. You token should be secured behind some sort of salt in you cookie for more protection

bashy's avatar

CSRF token is per user so if a server did a cURL to get it, it would be the wrong one.

1 like
nolros's avatar

@ltrain @bashy point is a subtle one, but I think people often miss that point. a CSRF token without backend Auth would be close to useless i.e. you can easily scrape snoop to get the CSRF token however unless it is verified to be a token from the Auth user it won't be accepted i.e. you need to be authorized to accept the token i.e simplified, CSRF + Auth = secure CSRF not the string of characters.

bashy's avatar

I meant cURL from within the server itself. Can't cURL on user connection. CSRF is exploitable for sure. Often used with XSS.

Even login/logout can be exploited if it's not protected with CSRF

1 like
Limweb's avatar

I'm use Angularjs to use http.post sent with object in the object have _token and change CsrfMiddle to check Input::get('_token') to validate this

RavanScafi's avatar

Your concern is about stolen sessions or mimicking the browser? You are safe with javascript, no problem, the CSRF covers it. The only way to have stolen sessions is with some kind of code injection (xss, sqli, etc.), not related to your token.

With cURL one can't steal anything, but surely can mimic the browser: get login page, extract token, post login with parameters, and so on. There's no real way to prevent it, really, pretty much all websites suffers from it, even big ones like Facebook.

1 like
davorminchorov's avatar

Speaking of CSRF and storing the token in a single page app, I have a question: Do you need to generate the token once on the page (per server request, usually in a script tag somewhere in the footer on the main layout or other layouts if there are multiple)?

I know that Blade's Form::open() generates the token by default but that's for a normal PHP app and it usually is generated on every page where you have a form.

jekinney's avatar

You can use Form::token() to make a hidden token field. Keep in mind, if your user doesn't have JavaScript enabled and your passing in a token with JavaScript it will never be generated to begin with on the browser.

Personally I use JavaScript for client side auth only and always use a server side if possible that reduces user issues and server issues.

davorminchorov's avatar

Well if the user doesn't have javascript enabled, his single page app won't work at all :D

Form::token() is the normal way of generating the token, I am asking about single page apps, how it is done. I saw this video on youtube where the token was generated in a script tag in the index.php file like this:


<script> var CSRF_TOKEN = '<?php echo csrf_token(); ?>'; </script>

and then the value from that variable was taken and posted to the server.

It was a quick demonstration, but I am looking for the best way possible to handle this.

link to the video: https://www.youtube.com/watch?v=18ifoT-Id54

1 like
bigbite's avatar

@Ruffles don't forget to add the quotations!

var CSRF_TOKEN = '<?= csrf_token(); ?>';
1 like
ltrain's avatar

So currently I am storing the token in a global JavaScript object and adding it to any forms that need it when performing an ajax call. For some reason I thought a curl request could grab the token but as @bashy pointed out it's unique to the user so my bad, not concerned about that. My original train of thought was that there was somehow a way to get the token out of the global object from a different tab or something not on the same page - seems like it would be a big security issue for browsers to allow that but I wasn't able to find any direct info on it so it's peaked my curiosity. For this example lets assume I've escaped all input so the likelihood of sql injection or xss is incredibly low. Wondering how someone could get the token without those..

bashy's avatar

I suggest you read up on some CSRF/XSS discussions, that will help you understand what is possible and how it's exploited.

You can also add more security yourself if needed. Generate a random name attribute and a value like the CSRF token and check for that on certain actions.

Bear in mind that CSRF is quite a personal attack and they would need to make the user(s) visit a page or script to do some sort of action.

Please or to participate in this conversation.