RFC: CSRF protection for forms and presenters
- David Grudl
- Nette Core | 8218
(in czech)
Low level CSRF protection
- Nette will automatically send token in a cookie
__csrf
with expiration0
(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 headerX-CSRF Token
- hrach
- Member | 1838
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
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 | 8218
@enumag cookie will be set with expiration 0
, so it will
never expire for inactivity
- David Grudl
- Nette Core | 8218
@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 | 1838
- 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)
- 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.
- 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…
- I do not care on which backend layer is the request validated, etc.