The frontend's job is to send proof that the request came from your own page. An attacker's site can make the browser send your cookies, but it can't read your pages or add custom headers.
The common methods:
- CSRF token: the server puts a random token in the page or in an API response. The frontend sends it back in a header such as
X-CSRF-Tokenon every request that changes data. The attacker can't read the token, so it can't send it. - Double-submit cookie: the server sets a random value in a cookie that is not
HttpOnly. JavaScript copies it into a header, and the server checks that the two match. It is weaker if an attacker can set cookies from a subdomain. So sign the value and tie it to the session, and use the__Host-cookie prefix. - Custom header: a cross-origin request with a custom header like
X-Requested-Withneeds a CORS preflight. A strict CORS setup rejects it, and plain forms can't add headers at all. This only works if your CORS setup is strict. - Fetch Metadata: browsers add
Sec-Fetch-Siteautomatically, with values likesame-originorcross-site. The server can rejectcross-siterequests that change data. The frontend does nothing here.
Also keep GET requests read-only, and keep SameSite cookies as the base layer.
- The frontend sends proof, such as a token in a header, that an attacker's site can't read or copy.
- A double-submit cookie is copied by JavaScript into a header and compared by the server.
- Custom headers force a preflight, so they help only with a strict CORS setup.
- Browsers send
Sec-Fetch-Siteautomatically, and the server can reject cross-site writes. GETrequests must never change data.