Does anyone see any downsides of doing the following to prevent CSRF?
I'm wondering if the following method will completely prevent CSRF, and be compatible with all users.
Here it is:
In the form just include an extra parameter that is: enc开发者_开发百科rypted(user's userID + request time)
. Server-side just decrypt and make sure it's the right userID and the request time was reasonably recent.
Aside from someone sniffing the user's traffic or breaking the encryption, is this completely secure? Are there any downsides?
While your approach is safe it is not standard. The standard way to prevent CSRF attacks is to generate pseudo-random number that you include in a hidden field and also in a cookie and then on the server side you verify that both values match. Take a look at this post.
One major downside is that your page will 'timeout' if the user leaves their browser open longer than the time frame you decide is reasonable before they post the form. I prefer sites not to rush their user into committing their action unless the action is inherently time-sensitive.
It's not completely secure, as it may be possible for an attacking site to guess the User ID.
If you use a per-session encryption key, it is secure. (But then all you need to do is send the raw key, and it's already secure)
Also, remember about timezones and inaccurate clocks.
It should work, yes. Though I would suggest you use a random number for UserID when you create new users, rather than a simple incrementing number (obviously, make sure it's unique when you create the user). That way, it's hard for an attacker to "guess".
Having the UserID and a DateTime is a start, but you also want a pseudo random number value preferably with high entropy in addition in the canary token. Basically, you need to reduce the predictability of the token in a page in a given context. Having only the UserID and a DateTime could in theory be possible to break after some time as it is not "random enough". Having said that, CSRF attacks are generally scripted and not directly monitored, so depending upon the exposure of your application, it may be enough.
Also, be sure to use a more secure encryption algorithm such as Rijndael/AES with a key of bits sufficient for the security of your application and a pseudo random initialization vector.
The security system you have proposed is vulnerable to attack.
Block ciphers like AES are commonly used as very secure random number generators. They are called CSPRNGs. However, like any random number generator you have to worry about what you are seeding the algorithm with. In this case you are using user's userID + request time
both of which the attacker can know, your implementation doesn't have a Key or IV so I assume they are NULL. The attacker is building the request so he will always know the request time
. The userId
is likely a primary key, if you have 100 users then the attacker could forge 100 requests and one of them will work. But the attacker might just want to force the administrator to change his password, admin's usually have a primary key of 1.
Do not re-invent the wheal, very good random number generators have already been built and there are also anti-csrf libraries.
精彩评论