CodeIgniter Forums
CSRF and double posting - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forumdisplay.php?fid=5)
+--- Forum: General Help (https://forum.codeigniter.com/forumdisplay.php?fid=24)
+--- Thread: CSRF and double posting (/showthread.php?tid=65498)

Pages: 1 2 3


RE: CSRF and double posting - Narf - 06-20-2016

(06-20-2016, 11:18 AM)spjonez Wrote:
Code:
$config['csrf_regenerate'] = TRUE;


Disable this setting, it adds nothing to security and will only make your life harder. Especially if you use a lot of AJAX or concurrent AJAX requests.

This is BAD advice, don't listen to it.

The fact that you think token regeneration is related to the described problem, shows that you don't understand how CSRF protection works. Thus, you shouldn't randomly tell people to turn security features Off.


RE: CSRF and double posting - spjonez - 06-20-2016

Narf Wrote:This is BAD advice, don't listen to it.

The fact that you think token regeneration is related to the described problem, shows that you don't understand how CSRF protection works. Thus, you shouldn't randomly tell people to turn security features Off.

I only read the title and the first post, which describe the issue as submitting a form twice, which this setting will break if the first request reaches the server. It also creates problems with single page apps unless you pass the token back and forth as it changes between requests. You can forget about concurrent AJAX requests with this enabled. So yes, I do understand how it works, what it's trying to protect against, and why regeneratting it isn't necessary.

Put this at the top of your .htaccess to prevent your site from being loaded into an iframe and have your login page generate the CSRF token.

Code:
Header always append X-Frame-Options SAMEORIGIN

Here's a few pages of reasons why this option does not improve security: http://security.stackexchange.com/questions/22903/why-refresh-csrf-token-per-form-request

We've paid to have our app penetration tested and they found no fault with this design.


RE: CSRF and double posting - PaulD - 06-20-2016

(06-20-2016, 11:18 AM)spjonez Wrote:
Code:
$config['csrf_regenerate'] = TRUE;


Disable this setting, it adds nothing to security and will only make your life harder. Especially if you use a lot of AJAX or concurrent AJAX requests.

1. Disable this setting
No. I do not want double posting from the back button. If a user wants to add data then they need to request the form.

2. It adds nothing to security
There is debate about this even in the link you posted and, on further reading, you can do it per request, per session, per form, per url, per successful submission or per time-span. It has to change at some point otherwise it is useless. The most secure is per request, the least secure is per-session (if we discount a silly site wide, permanent global token of course). This is because of the potential for leaking the token in some other way. Something is better than nothing of course, and none of them are unbreakably secure.

3. It will only make your life harder
Yes it will. And it does. And it is a pain in the arse. It would be much better to say to a user, tell me who you are and I trust the world I will not bother with any security at all. Just tell me your email address and I will fetch all your data for you. It is interesting to read about but I am not a security professional by any stretch of the imagination, but there are numerous debates about this online that I have read and even now, with my very limited understanding, can see people writing stuff that is very confused or simply wrong.

4. Especially if you use a lot of AJAX or concurrent AJAX requests
Yes, I do use AJAX, but try to avoid concurrent AJAX requests. AJAX has caused me so many headaches from a security point of view and seems to open everything up to abuse. Having the token regenerated at every request gives me a lot of comfort. A standard piece of js that updates the token values and reads them for all ajax calls seems to fix all the issues too with a tiny js function that remains the same on every page.

The main reason people give for not regenerating the token per request is that it is difficult to implement or to upgrade an existing website/framework that does not currently do it. This is not an issue in my case. CI does it for me (Thank you CI) and it is a new site.

The original post was not about double posting in the traditional 'back button' way, but a very quick double click in chrome resubmitting a form twice almost instantaneously. Disabling the regeneration of the CSRF token would do nothing for that.

CSRF is not about double posting (although it can help with it in certain cases/setups). In my later posts I realised that I was expecting CSRF to deal with something it had nothing to do with. Hence my JS solution works fine for now, and whats more, I can adapt it to be included in my standard JS script to apply to every form, so problem understood and solved.

Thank you for your suggestion though about the

Quote:Header always append X-Frame-Options SAMEORIGIN

I think that is probably very good advice and worth doing.

Paul.


RE: CSRF and double posting - Narf - 06-20-2016

(06-20-2016, 12:37 PM)spjonez Wrote: I only read the title and the first post, which describe the issue as submitting a form twice, which this setting will break if the first request reaches the server.

What are you trying to say here? That csrf_regenerate would "break the issue"? How does that event make sense?

Regardless of what you mean - it's just not true. If it did, the OP would NOT have a problem at all.

(06-20-2016, 12:37 PM)spjonez Wrote: It also creates problems with single page apps unless you pass the token back and forth as it changes between requests.

Yes, you do need to update your forms with the new token or use a different CSRF protection method, as you've suggested below.
That's challenging, but that's not a reason to downgrade security.

(06-20-2016, 12:37 PM)spjonez Wrote: You can forget about concurrent AJAX requests with this enabled.

No, you can "forget" about asynchronous requests if you're not updating your form tokens.
Concurrency is not asynchronicity; the OP is having the double-submit problem exactly because concurrency is not a problem.

(06-20-2016, 12:37 PM)spjonez Wrote: So yes, I do understand how it works, what it's trying to protect against, and why regeneratting it isn't necessary.

No, as explained above - you don't understand it.
All of your arguments are based on doing less work and avoiding hard problems. That is not how security works.

And you're creating these problems for yourself by doing POST requests, which is the only case when tokens are regenerated - on a POST form submission, NOT literally on every request. For the majority of AJAX stuff that you may need to do - anything that doesn't modify server state - GET is the way to go.

(06-20-2016, 12:37 PM)spjonez Wrote: Put this at the top of your .htaccess to prevent your site from being loaded into an iframe and have your login page generate the CSRF token.

Code:
Header always append X-Frame-Options SAMEORIGIN

Fair enough, that is a good solution. One that unfortunately didn't exist at the time when CodeIgniter's CSRF protection was designed.
Except, X-Frame-Options relies entirely on the user-agent and you don't need to generate CSRF tokens for it, at all - yet more proof that you don't understand the topic.

(06-20-2016, 12:37 PM)spjonez Wrote: Here's a few pages of reasons why this option does not improve security: http://security.stackexchange.com/questions/22903/why-refresh-csrf-token-per-form-request

ALL of the referred to reasons are "why this option does not improve security" are usability issues and personal opinions.
ALL of them talk about "each request" and that's where the usability issue comes from. This is not the case here.

And most importantly:

ALL of them talk about CSRF tokens stored in the session. Tokens stored in the session in general don't need regeneration, because the session itself is supposed to be regenerated and short-lived. THIS IS NOT THE CASE HERE!


RE: CSRF and double posting - spjonez - 06-20-2016

(06-20-2016, 01:49 PM)Narf Wrote: blah blah blah

What does the "A" stand for in AJAX? If you're making synchronous AJAX calls you've failed on so many levels I don't even know where to begin. I'd love to see how you manage concurrent AJAX requests with this enabled since CI's implementation uses a single valid token. I'm astounded I even had to say asynchronous as only a complete moron would send synchronous AJAX calls. The spec is even deprecating this behaviour and for good reason. Let's lock browser threads! Yay!

If you aren't vulnerable to XSS attacks, can you provide an example of a security hole created by using a single token vs a token that changes per request? I'd love to hear it because apparently the security company we paid to smash away at our app for 3 days straight wasn't able to find one.

And please, don't say "in theory if they get your token"... if they can steal it once they can steal it 100 times.


RE: CSRF and double posting - PaulD - 06-20-2016

LOL, I am the guilty one of saying too much Blah Blah Blah.

And WTF? When did Narf use the word 'sychronous'? Your entire tirade is based on a misreading.

Even your link said that if your site is secure against XSS you probably do not need to regenerate tokens on every request. But I would tentatively suggest Breach Attacks and Replay Attacks could be examples. And I highly doubt my sites are entirely safe from XSS attacks anyway. I hope they are, but I have not had pro's bashing away for three days like you have.

And no, "if they can get it once they can get it 100 times" is simply not true. What if I got it by getting you to click on a malicious link? Are you going to click on that link 100 times? No, you are not.

And the A in AJAX stands for 'AND', is that the A you were referring to?

And in the same straw-man manner that you began, only a complete moron would claim the pacific ocean is a lake :-)

Please don't ask me to search for any more examples. For some reason people do not like posting good solid examples of hacking on the web - I wonder why that is?

Finally, in theory if they get your token...

Blah Blah Blah

Paul.

Quote:Overview. The standard advice is to use a unique CSRF token that is unique for each request. Why? Because a per-request token is a bit more resilient to certain kinds of implementation errors than a per-session token. This makes per-request tokens arguably the best choice for new web application development. Also, no security auditor is going to hassle you about using a per-request CSRF token.

If you're a web application developer, this is all you need to know, and you can stop reading here.



RE: CSRF and double posting - spjonez - 06-20-2016

PaulD Wrote:And WTF? When did Narf use the word 'sychronous'? Your entire tirade is based on a misreading.

Narf Wrote:No, you can "forget" about asynchronous requests if you're not updating your form tokens.

Concurrency is not asynchronicity; the OP is having the double-submit problem exactly because concurrency is not a problem.

I said concurrent AJAX requests, you can't send concurrent synchronous AJAX requests since JS is single threaded so I'm not sure what else to take from that. Yes you can multi-thread with web workers but the DOM paints in a single blocking thread.

PaulD Wrote:And the A in AJAX stands for 'AND', is that the A you were referring to?

The first A. Asynchronous JavaScript And XML.

PaulD Wrote:And no, "if they can get it once they can get it 100 times" is simply not true. What if I got it by getting you to click on a malicious link? Are you going to click on that link 100 times? No, you are not.

That's only one way and there's a lot more possibilities with XSS attacks.

I'm not arguing the theory, that would be pedantic, but in reality the limits imposed by per request CSRF tokens simply aren't worth the theoretical security advantages. Can you imagine how an app like Google Docs would function without multiple concurrent requests? Our app is an editor that's very similar and it wouldn't be worth building under those constraints.

I replied under the same line of reasoning. Having a user click back and being unable to submit a form provides a bad user experience and security should never trump usability. If it does another approach to security is needed not the other way around.


RE: CSRF and double posting - John_Betong - 06-20-2016

[off topic]
Skunkbad,

I am unable to reply to your personal message because your "private messages" are disabled Sad

[/off topic]


RE: CSRF and double posting - skunkbad - 06-20-2016

(06-20-2016, 09:25 PM)John_Betong Wrote: [off topic]
Skunkbad,

I am unable to reply to your personal message because your "private messages" are disabled Sad

[/off topic]

Fixed


RE: CSRF and double posting - Narf - 06-21-2016

(06-20-2016, 02:32 PM)spjonez Wrote:
(06-20-2016, 01:49 PM)Narf Wrote: blah blah blah

It's one thing to disagree because of misunderstanding or lack of knowledge, but to dismiss facts as "blah blah blah"?
Are you seriously being that ignorant?

(06-20-2016, 02:32 PM)spjonez Wrote: What does the "A" stand for in AJAX?

This is in no way related to CSRF. What a moronic straw-man, indeed.

What does the "X" in "AJAX" stand for? XML you say?
Are you going to call everybody doesn't use XML a moron?

(06-20-2016, 02:32 PM)spjonez Wrote: If you're making synchronous AJAX calls you've failed on so many levels I don't even know where to begin.

Because you're the judge of everything? Features are features, they all have use cases.
Even if it is a bad feature, you're exaggerating big time and it's beside the point - I've stated what asynchronicity is what creates a problem for you, not that you should use blocking AJAX calls.

Again, nothing related to CSRF.

(06-20-2016, 02:32 PM)spjonez Wrote: I'd love to see how you manage concurrent AJAX requests with this enabled since CI's implementation uses a single valid token.

Still, you don't understand how the CSRF protection mechanism works and/or what concurrency means. You don't need to do any extra work for concurrent requests to work.

What matters is the cookie value at the time of submission. If it was possible to have 1000 concurrent (meaning: simultaneous) requests, they'd all pass, because they would all carry a matching cookie + form token pair.

(06-20-2016, 02:32 PM)spjonez Wrote: I'm astounded I even had to say asynchronous as only a complete moron would send synchronous AJAX calls.

I'm astounded by your insistence that how AJAX works best is somehow a security consideration.

(06-20-2016, 02:32 PM)spjonez Wrote: The spec is even deprecating this behaviour and for good reason.

I'm sure there's a good reason for that. In fact, I'm sure there's more than one reason.
However, you talk too much smack and present yourself as a credible authority on the subject, while not showing much substance, and I'm not convinced that you know that "good reason" yourself.

(06-20-2016, 02:32 PM)spjonez Wrote: Let's lock browser threads! Yay!

... I don't even want to know what you mean by that.

(06-20-2016, 02:32 PM)spjonez Wrote: If you aren't vulnerable to XSS attacks, can you provide an example of a security hole created by using a single token vs a token that changes per request?

First of all - per POST request, not per any request.
You know you're cherry picking here and by doing that you're ignoring a very reasonable trade-off, playing up "hard to implement" types of problems that you create for yourself, and that your whole argument is based around.

Second, "if you aren't vulnerable to XSS attacks" is a somewhat valid point to dismiss immediate threats, but also a very sneaky way of trying to control the narrative. We're talking about information security - consider all cases, don't assume that nothing will break; assumptions are the evil.

Third, nobody has said that not regenerating automatically creates a critical security flaw, like you're implying.
It's mitigation for lesser evils, but evils nonetheless.

And to answer your question: CSRF tokens can not only be stolen, but also planted. That is way worse if it happens, because even if I'm charitable enough to assume that at least you have a sane cookie expiry time configured, an attacker can override that and make you a target for years.

(06-20-2016, 07:00 PM)spjonez Wrote: I'd love to hear it because apparently the security company we paid to smash away at our app for 3 days straight wasn't able to find one.

I don't know your app, but judging by your earlier suggestion of X-Frame-Options - if you use that, of course they aren't going to find an issue.
I don't know the company, team & expertise level of those who audited it - there are a lot of crappy security auditors.
I don't know what you consider a "hole" and how honest you are here - many potential issues are raised as "info" or "warning" items on audit reports. Judging by your behavior so far, you may be twisting this all kinds of ways.

(06-20-2016, 07:00 PM)spjonez Wrote: And please, don't say "in theory if they get your token"... if they can steal it once they can steal it 100 times.

You don't know that.

I may stumble upon it by accident.
I may read it once while having limited-time access.
I may not be able to re-steal it less time than it takes to regenerate.

(06-20-2016, 07:00 PM)spjonez Wrote: ...

I said concurrent AJAX requests, you can't send concurrent synchronous AJAX requests since JS is single threaded so I'm not sure what else to take from that. Yes you can multi-thread with web workers but the DOM paints in a single blocking thread.

...

I'm not arguing the theory, that would be pedantic

Oh, now we don't want to be pedantic? What happened to the A in AJAX?

Here's something pedantic: JS and DOM aren't single-threaded, and the latter is not even a relevant term. Browser implementations may be single-threaded - that's a different thing.

(06-20-2016, 07:00 PM)spjonez Wrote: but in reality the limits imposed by per request CSRF tokens simply aren't worth the theoretical security advantages.

So we went from "adds nothing to security" to "theoretical security advantages" ... I guess that's some progress at least.

Here's the thing about theory though: opinions, everybody has them. And what isn't worth it for you is not the definitive answer for everybody.

(06-20-2016, 07:00 PM)spjonez Wrote: Can you imagine how an app like Google Docs would function without multiple concurrent requests? Our app is an editor that's very similar and it wouldn't be worth building under those constraints.

See, the same thing again: Different use cases, different considerations, different trade-offs, different solutions.
Just because you don't believe it's worth it for you, doesn't mean that the double-submit cookie mechanism was even the right solution for you in the first place.

(06-20-2016, 07:00 PM)spjonez Wrote: Having a user click back and being unable to submit a form provides a bad user experience

Have you heard of the PRG pattern? And applying different solutions to different problems in general?

(06-20-2016, 07:00 PM)spjonez Wrote: and security should never trump usability.

Sorry, but this quote alone disqualifies you from talking about security. You don't get it, you don't take it seriously enough.

(06-20-2016, 07:00 PM)spjonez Wrote: If it does another approach to security is needed not the other way around.

You're not suggesting another approach, you're telling people to decrease security.