For preventing CSRF attacks does creating an encrypted cookie with a nonce prevent a CSRF attack? In addition, to that checking the referrer against the target origin. I cannot change 1000s of pages to embed the token in each submit and I do not have session state.
3 Answers
For preventing CSRF attacks does creating an encrypted cookie with a nonce prevent a CSRF attack?
No, requiring certain cookies would not defend against Cross Site Request Forgery, because the browser will still send the cookies, regardless of whether the request was Cross-Site or Same-Site.
In addition, to that checking the referrer against the target origin. I cannot change 1000s of pages to embed the token in each submit and I do not have session state.
Read the OWSAP CSRF Prevention Cheat Sheet for recommended methods to prevent CSRF. Specifically look at the Verifying Same Origin techniques which are more easy to implement than tokens. Also look for OWSAP's description of this technique's limitations, if any.
If I remember correctly, checking the Origin is an effective countermeasure against CSRF for most (if not all) 'major' clients.
-
1The problem with checking the Origin/Referer is that under some circumstances those headers can be forged. For example (very) old versions of Flash or Java plugins in some browsers would allow setting those headers to arbitrary values without any user intervention. That is not the case anymore, but there could be other unsafe plugins installed. With all that in mind, I would say checking Origin is probably acceptable for some applications and is definitely much better than nothing, but it is not the best practice. Commented Nov 15, 2016 at 22:50
-
So even if that cookie has the proper protections marking like marking the cookie as httponly and only transmitting it over https and marking a domain and path and the decrypted value contains values that are submitted to the client ie a random nonce, user id, date and time. This would still be considered a insecure option. I can understand it being insecure if it was plain text not marked as http only and doesn't have a domain and path.– bdawgCommented Nov 16, 2016 at 2:02
-
The
HttpOnly
option means that JavaScript cannot view the cookie. (and thus encryption is unhelpful) However, JavaScript (or other means) can still be used to initiate a Cross-Site Request. The Browser will still send the cookies, even if the JavaScript does not have access to view them. TheSecure
option just means the (cross-site) request must be sent onhttps
which is just as easy ashttp
from a CSRF point of view. Similarly, thedomain
andpath
options are unhelpful to defend against CSRF. Commented Nov 16, 2016 at 13:19
Firstly, we have to understand the main problem about CSRF; the server trusts every request which we send, in other words, the server does not ensure that the request has been consciously sent by a legitimate user, for this reason, we have to add an element to identify every request correctly.
The main idea to protect againts CSRF is the implementation of an unique element and this must be hard to predict, then measures like token or CAPTCHA are good solutions. The CAPTCHA isn't efficient in most cases, because an user doesn't like to introduce values to the CAPTCHA for every site which he visits, remeber, there must be a balance between security and performance, in this way, the main solution will be token.
Now, checking the origin isn't enough to protect against CSRF; imagine a web site vulnerable to XSS, you can inject a script to execute a CSRF attack; another example could be a editable module where you can add or edit elements to customize a web page which could be visited for every user of the application, you can add something like this:
<img src="http://mywebsite/transfer?account=123456&quantity=1000000" />
If the web application validate the origin, in this case, the request will be valid, because it belongs to same origin.
I hope this information helps you.
No, encrypting the cookie does absolutely nothing to protect against CSRF attacks, because an attacker never needs to access the cookie to preform the attack. The bowser automatically sends it for the domain it was set on.
Checking the referer and origin headers on the other hand is pretty good, but not perfect as the client may be configured not to send these headers.
Sending the token in the request is really the only perfect solution, but you would probably be able to get away with just checking the headers.