A CSRF attack works on an unprotected site to which the user is logged in. Consider site S that uses session cookie C (and nothing else) to identify a user's session. This means that the browser will send C on every request to S. As the presence of the session cookie is all that's required to confirm a session, the user will be logged in when they access S. This is great. Exactly what we want.
Except...
Let's assume that S can is a website that can email cash via an URL such as https://S/email-cash?email=recipient@examplecom
. An evil website E can have embed the link https://S/email-cash?email=ATTACKER@examplecom
in one of its pages. Now, when the user is browsing site E while logged into site S and they click on this link, they'll end up emailing the attacker money. Even worse, this link can be executed in JavaScript behind the scenes so the user only needs to visit site E. Very bad.
The problem happens because every request accompanied by a valid session ID cookie C is treated as a valid request. The solution is to require the browser to send some piece of ID that it could only have gotten very recently from site S. This is the CSRF token. There's no way for the browser to get it unless it is given it by S and S will only give it when it's serving a page, not for a cross-site attack.
Now if you start storing the CSRF token as a persistent cookie, it defeats the entire purpose because it becomes something that the browser can send on a cross-site attack.