Safeguard
Security Guides•

Why do anti-CSRF tokens break DAST scans, and how do you fix it?

Why do DAST scans fail on forms with anti-CSRF tokens? Single-use tokens reject replayed requests. Learn how scanners handle them and how to check yours.

Safeguard Security Team
7 min read

Anti-CSRF tokens change on each form load, so a scanner that replays an old request gets rejected and never reaches the code behind the form. The fix is a scanner that fetches a fresh token before each attack request, plus a check that those requests really succeed.

What the token does

A cross-site request forgery attack tricks a logged-in user's browser into sending a request they did not intend. An anti-CSRF token defends against it. The server puts a random value in each form, and only accepts a submission that carries the matching value. An attacker's page cannot read it, so it cannot forge a valid request.

Why scanners struggle

The ZAP documentation puts the clash plainly: these tokens protect against CSRF, and they also make a tester's job harder, especially when they are regenerated every time a form is requested. A scanner that submits a payload with a stale token gets an error page. It may log "no vulnerability" for a form it never tested. Your report then looks clean for the wrong reason.

How scanners cope

ZAP's documentation says it detects anti-CSRF tokens by attribute names, using a configurable list of names. When it recognizes one, it requests a fresh value before each submission. Its options also describe a setting to treat form parameter names as tokens if they include one of the listed names. Other tools use similar approaches, such as recorded login-and-form sequences or custom scripts.

The ZAP active scan options add a caution: if you use more than one thread, check that tokens are being generated correctly, for example by using custom tags to check for success or failure patterns in the response.

Steps to check your own app

  1. Find the token name. Open the form source and look for a hidden field or a header.
  2. Add the name to the scanner if it is custom, such as a project-specific field.
  3. Run one form by hand with the scanner's proxy and confirm the server accepts the submission.
  4. Read the scan log. Look for a high rate of 403 or 400 responses on POST requests.
  5. Add a success check. Many scanners let you define text that proves a form worked, such as a confirmation message.
  6. Reduce threads if tokens still fail. A single thread is slower but safer for single-use tokens.
  7. Ask for a test switch. In a test environment, some teams add a setting that relaxes token checks for the scanner account only. Keep it off in production and document it.

Common failure signs

Sign in the logLikely cause
Many 403 responses on POSTStale or missing token
Same error text on every payloadForm rejected before reaching logic
Fewer findings after you enable CSRF protectionScanner no longer reaching the handler
Works with one thread, fails with manySingle-use token raced between threads

Do not remove the protection to make scans easier

It is tempting to turn token checks off in the test environment so scans pass. That hides the very control you want to keep working. Better to teach the scanner about the token, or relax it only for a named test account in a non-production environment.

A worked example

A team scans a profile page. The form has a hidden field named csrf_token, and the server accepts a post only if the value matches the one issued with the form. Their first scan reports no findings on that page. The scan log tells another story.

StepWhat the log shows
1Scanner loads the form and records a token value
2Scanner sends 400 variations of the name field, each carrying that same old token
3The server rejects every one with a 403 error and a generic message
4The report says "no issues", though no payload reached the handler

The team then takes five steps.

  1. They confirm the token field name and add it to the scanner's list of token names, since the project uses a custom name.
  2. They configure a success check, a text string that appears only after a successful save.
  3. They run a short scan with one thread and watch the log. Now most requests return 200 with the success text.
  4. They raise the thread count and see failures return, which shows the tokens are single use. They keep one thread for this area.
  5. They rerun the full scan. It finds a stored input problem in the name field that the first scan never reached.

The responses and counts in this example are illustrative. The pattern is common and easy to check.

Variations in token design

Tokens are not all alike. The way a token is issued changes how a scanner must handle it.

DesignHow it behavesScanner approach
Hidden form field, new per page loadChanges every time the form loadsFetch the form before each submission
Per session tokenStays the same until logoutCapture once, reuse
Header token read from a cookieCopied by front end codeNeeds script or browser-driven handling
Token inside a single-page app API callIssued by an earlier API responseUse a recorded login and call sequence
Same-site cookie settings onlyNo token at allNothing to handle, but test cross-site behavior

Think about what the scanner can learn from CSRF protection

A scanner that handles tokens can still test whether your protection works. A good manual check is to remove the token, send a request, and confirm it is rejected. Then use a token from another session and confirm that fails too. If either succeeds, the protection is weaker than it looks, and that is a real finding.

Document your setup

Write down the token names, the success text and the thread count. The next person who changes the form will otherwise break the scan without knowing it. A one-page note beside the scan config is enough.

When to ask for developer help

If the front end builds tokens in script and no list of names works, ask a developer for a test mode. A common arrangement is a flag that turns token checks into logging only, available for a dedicated scan account in a non-production environment. Record that the flag exists and that it must never be enabled in production.

Where Safeguard fits

Token handling is a web testing concern. For the libraries behind your forms, Safeguard offers SBOM and dependency scanning with reachability analysis, and a free scan at gold.safeguard.sh/scan.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch for steps where a form is submitted and think about how a fresh token would be obtained.

Quick check

How can I tell the scanner never reached my form handler?

Look for many 403 or 400 responses on POST requests in the scan log.

Should I disable CSRF checks in staging for scans?

Avoid it. Teach the scanner the token name, or relax it for one test account only.

Do SameSite cookies replace anti-CSRF tokens for scanning purposes?

They change what a scanner must handle, since there may be no token to fetch. Still test cross-site behavior, because the cookie setting alone does not cover every case.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.