It seems like I understand CSRF incorrectly?
After reading many documents regarding CSRF, I'm still a little bit confused. So I hope someone can please explain it to me:
Lets say if I have a profile page which is for authenticated users only, say abc.com/profile which shows me all my private info. If I logged in, then go to a "bad" site, can this site somehow get and parse my profile page? (I did a little experience by opening up the firebug console on a different site, then request my profile page, and it seems like at least I can see the whole content in "response" of the "Net" tab, haven't figured out how to get this content and parse it yet though. But perhaps it's possible?)
Now assume that I have on my profi开发者_如何学运维le page a form, which of course has csrf token. Now if an attacker could get my profule page, he could just parse that content, get the token then submit a fake form?
Now assume that 1 and 2 are correct, what should I do to prevent such cases from happening?
Your points aren't quite right... But take this scenario.
Example Attack
Imagine that a user is logged into The Official Bank of Fake Country - GoodBank.com and has a balance of 1,000,000 gold.
On MaliciousSite.com
, there is an <img>
or some other generic JavaScript that causes you to make a request to GoodBank.com
.
The <img>
has a src
of http://www.goodbank.com/account/transfer.php?amount=10000&sentTo=malicioususer
.
Now this site has made a request under your user account and has caused you to invoke a page which you would not have otherwise.
Now, you might be thinking that you can protect against this by using only POST, but these are not secure either. The correct way is to use CSRF tokens in your forms, and when a form is submitted, you should check that the CSRF token that you receive is the same as with what was issued.
Do not use these measures to protect yourself:
- Secret Cookies
- Only accepting POST requests
- Multi-page forms
- URL rewriting
Instead use a token like this:
<form action="/transfer.do" method="post">
<input type="hidden" name="CSRFToken" value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZjMTVi
MGYwMGEwOA==">
…
</form>
View here for great explaination: CSRF Cheat Sheet
Your first point is not correct.
You cannot read content from a different domain on the client.
Therefore, a hostile site cannot read the CSRF token.
You can send requests to a different domain (which is what CSRF attacks do), but you can't read the responses.
This may not be directly related to the question asked but need to point out that cross site scripting attacks can open doors for CSRF. Even token based solutions used to prevent CSRF can be compromised by XSS.
Take the following scenario.
Form used to update user info.
<script>
...
var userID=getUserId();//method makes AJAX call to get user ID
...
</script>
...
<form name="UpdateUserProfile">
<input type='hidden' id='userId' value='userID_attacker_cannot_guess'>
<input type='hidden' id='userName' value='goodUser'>
<input type='hidden' id='email' value='goodUser@goodsite.com'>
...
</form>
Assuming that the user Id is unique and can not be guessed easily, we can prevent CRSF without a token.(Attacker request will not be able to have the right user ID).
But if the attacker can read the value of userID
using XSS attack, he can then craft the forged request to include the correct user ID.
Although XSS is not needed for CSRF attacks, it will make it easier.
Check the following resources.
Cross-Site Request Forgery (CSRF)-OWASP
Cross-site Scripting (XSS)-OWASP
精彩评论