RFC: CSRF protection for forms and presenters

Notice: This thread is very old.
David Grudl
Nette Core | 8082
+
0
-

(in czech)

Low level CSRF protection

  • Nette will automatically send token in a cookie __csrf with expiration 0 (until the end of the session)
  • all POST forms will always send the hidden field __csrf with this token as value + anti-BREACH-attack masking
  • unless cookie __csrf will match the POST element __csrf, RequestFactory throws HTTP error 403
  • protection will be enabled by default, it can be switched off in the config (and we will not write how in documentation ;-)

Pros:

  • it provides automatic protection for all POST forms without having to call addProtection
  • it will not depend on session
  • some error messages (Please submit this form again) actually helps to attacker
  • token in a cookie (as opposed to element <meta>) will not require to change templates and is resistant to BREACH attack

Cons:

  • greater risk to disclosure token, attacker can use XSS on the page where the form is not present

Protected Presenter links

activation:

  • protection will be used for actions and signals and will be enabled by annotation on the appropriate method
  • possibility to activate protection for the whole presenter or component using annotation on class
  • it will be possible to activate the protection for the individual presenter's component, in similar way how persistent components are annotated

The principle:

  • protected GET links will be marked by empty HTML attribute data-nette-secure
  • these links will be send using JavaScript as POST forms to the same URL with a field __csrf
  • default implementation will not use jQuery and will be compatible with IE8+
  • token will be check in RequestFactory, (see Low level CSRF protection)
  • Presenter will check that the link to the protected target (component, action, singal) is sent by a method other than GET / HEAD, otherwise will respond with 403

AJAX:

  • protected links can be sent via AJAX method PUT and DELETE, and then the token will be passed in header X-CSRF-Token
  • this means that RequestFactory in addition to the POST element __csrf will check header X-CSRF Token
hrach
Member | 1834
+
+3
-

The possibility of token leakage form COOKIE is quite huge! It's not more secure than nextras/secured-links. From my point of view, the possibility of leakage of specific signal token is less dangerous than leaking the master key.

Last edited by hrach (2015-02-19 12:59)

enumag
Member | 2118
+
0
-

When a user takes too long to send a form or was inactive for a longer period of time before clicking a secured signal link I want to give him some translated user-friendly error message with info what he is supposed to do. An automatic 403 page with something about CSRF won't help him, he doesn't know what is CSRF.

Last edited by enumag (2015-02-19 13:16)

David Grudl
Nette Core | 8082
+
+1
-

@enumag cookie will be set with expiration 0, so it will never expire for inactivity

enumag
Member | 2118
+
+1
-

@DavidGrudl About the XSS issue… Does it mean that if I have one page on the website that is vulnerable to XSS, the CSRF security of any action on the web can be bypassed by getting the master token from this page? Or did I get it wrong?

David Grudl
Nette Core | 8082
+
0
-

@hrach this is a completely different level of protection. This is auto protection for forms, links, links generated by AJAX etc. Secured-links are very specific and therefore limited protection, and you can of course use both of them.

hrach
Member | 1834
+
+1
-
  • generating links in javascript
    • nette doesn't support generating links in javascript. Of course, I can do some stupid “replace of”/“append to” url, but talking about “generating url in ajax” is not appropriate.
      • it's obvious, that signing link in javascript will be always vulnarable if there is XSS. The probality of XSS is with latte much lower than ever, but… to be honest, it's still the most common vulnerability in nette applications.
      • in nextras/secured-links there is some support for links constructed in javascript (not validating the dynamic parameter – it would not make sense to validate something, which can be slipped by xss)
  • implmentation details
    • I do not care on which backend layer is the request validated, etc.
      • I love the idea about turning csrf protection for components, presenters, etc…
    • but these are all implementation details. Current link generation is not well designed, even so small modification in secured-links have to be quite hacky…