Tricking a user's browser into executing unwanted actions on another site.
Browsers automatically attach cookies (including session cookies) to HTTP requests made to a specific domain, regardless of where the request originated. In a CSRF attack, an attacker tricks the victim into clicking a link or loading an image on a malicious site, which triggers a background request to a vulnerable site where the victim is already logged in. The browser dutifully attaches the session cookie, and the server processes the request as the victim.
The standard defense against CSRF is the Synchronizer Token Pattern. The server generates a unique, cryptographically random token and embeds it in the HTML form. When the form is submitted, the server verifies the token. An attacker on a different site cannot read this token (due to the Same-Origin Policy) and therefore cannot forge a valid request.
<!-- VULNERABLE: No CSRF protection -->
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
<!-- A malicious site can easily replicate this exact form and auto-submit it -->
</form>
<!-- SECURE: Includes an Anti-CSRF Token -->
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="csrf_token" value="x8a9b21f... (unguessable)">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
<!-- The attacker cannot guess the csrf_token, so the server rejects the forged request -->
</form>
An admin is logged into their WordPress site. They visit a forum and read a post by a hacker. The post contains a hidden, invisible form that automatically submits a POST request to `https://admin-site.com/wp-admin/user-new.php` via JavaScript. The admin's browser automatically attaches their WordPress session cookie. The request creates a new administrator account controlled by the hacker. This is a classic CSRF attack.
Why can't an attacker just use JavaScript on their malicious site to fetch the `csrf_token` from the bank's website before submitting the forged form?