CSRF protection and form tampering prevention

Home / Everything About / Everything About Forms / CSRF protection and form tampering prevention

Imagine someone tricks a visitor into clicking a link while they are logged into their bank account. That link leads to a hidden form that, without the visitor knowing, submits a request to the bank to transfer money. The bank sees a legitimate request coming from an authenticated user and processes it. The attacker has now moved money using the victim's account without ever knowing their password.

This is what CSRF (Cross-Site Request Forgery) is: an attack where an attacker tricks a victim into unknowingly submitting a form or request to a different website where the victim is already logged in.

What you'll learn: What CSRF attacks are and how they work, why they are so dangerous even when other security measures are in place, how CSRF tokens prevent them, and how to implement protection on your forms.

What is CSRF?

CSRF (pronounced "sea-surf") stands for Cross-Site Request Forgery. It is an attack where an attacker exploits the fact that if you are logged into a website, your browser automatically trusts and includes your session with every request you make to that site, even if the request comes from a different website.

The attack works by tricking a logged-in visitor into unknowingly submitting a form to a website where they have an account. The attacker cannot see the victim's password. They do not need to. They just need the victim to be already logged in, and then trick them into making a request (like submitting a hidden form) that does something the attacker wants.

CSRF is different from other attacks because it does not require stealing credentials or breaking encryption. It exploits the victim's trust in the website. The victim is already authenticated, so the website trusts requests that appear to come from them.

How CSRF attacks work

A CSRF attack happens in three steps.

Step 1: The victim is logged into your site

Someone visits your website and logs into their account. Their browser now has an active session cookie that proves they are authenticated. This session stays active while they keep using the site.

Step 2: The attacker tricks them into visiting a malicious page

While still logged in to your site, the victim visits a page the attacker controls (maybe a link from social media, a misleading ad, or a website that looks legitimate). On that page is hidden code that submits a form back to your site.

Step 3: The form submits automatically using the victim's session

The hidden form submits to your website. Because the victim is already logged in, their browser automatically includes their session cookie with the request. From your form's perspective, this is a legitimate request from an authenticated user. The form processes it as if the victim intentionally submitted it.

The attacker has now done something on your site using the victim's account without the victim knowing. They might have changed their password, transferred money, updated their profile, or submitted data.

Why this works when other security measures are in place

CSRF attacks bypass several common security features:

HTTPS does not stop CSRF. The data is encrypted in transit, but the attacker does not need to intercept it. They just send the request from the victim's browser, which the victim's browser already trusts.

Password protection does not stop CSRF. The attacker never needs the victim's password. They just exploit the fact that the victim is already logged in.

A strong login system does not stop CSRF. Even if authentication is perfect, if the victim is logged in, the attack works.

This is why CSRF protection is its own layer. It is not prevented by other security measures. You have to specifically design forms to resist CSRF attacks.

CSRF tokens: how they stop the attack

The solution is a CSRF token. It is a unique, unpredictable string that your server generates for each form. Here is how it works:

Your server creates a unique token for each visitor

When someone loads a page with a form, your server generates a random token and associates it with that user's session. This token is different every time, and it is unique to that user.

The token is embedded in the form

The token is included as a hidden field in the HTML form. When the visitor submits the form, the token travels with it.

Your server verifies the token before processing the submission

When the form is submitted, your server checks whether the token in the submission matches the token you generated for this user's session. If yes, the form processes. If no (or if there is no token), the form is rejected.

The attacker's hidden form cannot include a valid token because tokens are unpredictable and unique to each session. An attacker on a different domain cannot see or guess the token. So their attack fails. The hidden form submits, but your server rejects it because the token does not match.

What a CSRF token looks like in practice

In HTML, a CSRF-protected form looks like this:

<form method="POST" action="/submit-form">
  <input type="hidden" name="csrf_token" value="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6">
  <input type="email" name="email" placeholder="Your email">
  <button type="submit">Submit</button>
</form>

The `csrf_token` field is hidden. The visitor does not see it, but it submits along with their form data. Your server checks it before processing the email or any other data.

CSRF protection for different form types

Traditional HTML forms

Standard HTML forms (the kind that POST data to your server) need CSRF tokens. This includes contact forms, login forms, password reset forms, and any form that changes data on your server.

AJAX and JavaScript forms

Forms submitted via JavaScript to an API endpoint also need CSRF protection. The token can be embedded in the form itself, stored in a cookie, or retrieved from a meta tag before the request is sent.

Stateless API requests

If your API uses token-based authentication (like JWT), CSRF protection works differently. The browser cannot automatically attach a JWT token the way it attaches a session cookie, so traditional CSRF is less of a threat. However, best practice is still to include an additional CSRF token for extra protection.

Other protections that work with CSRF tokens

CSRF tokens are the primary defense, but they work best alongside other security practices.

SameSite cookies

When you set a session cookie, you can add a `SameSite` attribute that tells the browser not to include the cookie when requests come from a different domain. This prevents the attacker's hidden form from using the victim's session at all.

Referer header checks

Your server can check the Referer header to see where the request came from. If a form submission claims to come from your domain but the Referer shows a different domain, it is probably an attack. (However, Referer headers can be spoofed, so this is not a complete defense.)

Double-submit cookie pattern

In this approach, the CSRF token is stored in both a cookie and a form field. Your server checks that they match before processing. This is less common than traditional tokens but works well for stateless applications.

How to implement CSRF protection

The implementation details depend on your technology stack, but the pattern is the same:

  1. Generate a unique token per session. When a user starts a session or loads a form page, your backend generates a new token.
  2. Store the token server-side. Save it associated with that user's session.
  3. Include the token in the form. Add it as a hidden field in the HTML or as a meta tag that JavaScript can read.
  4. Validate on submission. Before processing any form data, check that the submitted token matches the stored token for that session.
  5. Regenerate after sensitive actions. After a user changes their password or does something critical, generate a new token.

Most modern frameworks (Django, Rails, Laravel, ASP.NET) handle CSRF token generation and validation automatically. If you are using a framework, CSRF protection is usually turned on by default. Just make sure you do not accidentally disable it.

Common mistakes that leave forms vulnerable

Disabling CSRF protection for convenience. Some developers turn off CSRF checks to make API testing easier or to simplify their code. Do not do this. It creates a real vulnerability.

Using a static token for all users. The token must be unique to each user's session. A token that is the same for everyone (or the same for all users on all days) does not protect against CSRF.

Not regenerating tokens. If you use the same token for weeks, an attacker has more time to exploit it. Regenerate tokens regularly and always after sensitive operations.

Relying only on SameSite cookies. SameSite is helpful but not sufficient. Use CSRF tokens as your primary defense and SameSite as a backup.

Forgetting tokens on some forms. If you protect some forms with tokens but not others, attackers will use the unprotected forms. Every form that modifies data needs protection.

What WEMASY does for CSRF protection

WEMASY's forms automatically include CSRF token protection on every form you create. You do not need to configure it or think about it. When a visitor submits a form, WEMASY validates the token before storing the submission. This protection is built in and enabled by default.

Learn more about form security options on the pricing page.

Frequently asked questions

Can an attacker guess a CSRF token?

With WEMASY's <a href="/website-builder" target="_blank">website builder</a>, you can set this up directly on your website.

What happens if a visitor submits a form and the token is invalid?

Do I need CSRF protection if my form does not require login?

How is CSRF different from XSS?

What about attacks on mobile apps? Do CSRF tokens work?