121. How does cross-site request forgery affect a cookie-authenticated frontend?
A banking page uses an automatically sent session cookie for POST /api/payments. Explain how a malicious site can cause the browser to send a state-changing request, what asset and authorization boundary are at risk, and how SameSite cookies, anti-CSRF tokens, origin checks, and request design reduce the attack. Distinguish CSRF from reading a cross-origin response through JavaScript.
CSRF abuses the browser's automatic cookie behavior. A malicious site can trigger a payment request that carries the victim's bank session cookie even though it normally cannot read the response. Use SameSite cookies, anti-CSRF tokens, Origin checks, safe request design, and server-side authorization.
This question asks how another website can make your browser perform an action on a banking website while you are already signed in. The danger is not that the bad website can see your bank page. The danger is that your browser may automatically include proof that you are signed in when it sends a request. If the bank accepts that request without checking where it came from or whether it belongs to an expected user action, money could be moved or account information could be changed. The answer should explain how the bank recognizes and rejects these unwanted actions.
- Can I assume the banking application uses a server-managed session stored in a cookie that the browser automatically sends when the cookie rules allow it?
- Should I focus on browser-based CSRF defenses for a same-site frontend calling the bank API?
- Can I assume POST /api/payments changes server state and therefore requires both authentication and server-side authorization?
Assume the user signs in to bank.example and receives a session cookie. The browser stores that cookie and may automatically attach it to later requests to the bank when the cookie's domain, path, security, and SameSite rules allow it.
Now the user visits evil.example. The malicious page tries to cause the browser to send a request to https://bank.example/api/payments. If the browser includes the bank's session cookie and the bank accepts the request without an additional CSRF check, the server may treat the request as belonging to the authenticated user even though the user did not intentionally create that payment from the bank application.
That is cross-site request forgery, or CSRF: another site causes the victim's browser to send an authenticated state-changing request.
The asset at risk is the user's authenticated authority to perform sensitive banking actions, such as creating a payment.
The trusted authorization boundary is the bank server. The session cookie can identify an authenticated session, but authentication answers only who the session belongs to. It does not prove that the user intended this payment. The server must separately authorize the payment, for example by checking that the authenticated account is permitted to perform the operation, and must reject requests that fail its CSRF defenses.
Frontend JavaScript is not the final authorization boundary because requests can reach the server without using the legitimate frontend code.
The browser's same-origin policy normally prevents JavaScript running on evil.example from reading protected response data from bank.example unless cross-origin access is explicitly permitted.
That does not mean the browser cannot send any cross-origin requests. Normal browser features such as form submission can cause cross-origin requests. If such a request includes an authenticated cookie and the server accepts it, state may change even though the malicious site's JavaScript cannot inspect the response.
CORS is therefore not the primary CSRF defense. CORS controls whether JavaScript is allowed to access certain cross-origin responses and whether some non-simple cross-origin requests are permitted after a preflight. It does not turn all cross-origin requests into blocked requests.
The session cookie should normally use Secure, HttpOnly, and an appropriate SameSite value.
Secure means the cookie is sent only over HTTPS. HttpOnly prevents normal JavaScript from reading the cookie, which helps limit cookie theft through script access, although it does not itself stop CSRF.
SameSite=Strict generally prevents the cookie from being sent with cross-site requests. It gives strong CSRF protection but can interfere with legitimate flows that enter the site from another site.
SameSite=Lax is more permissive. It generally withholds the cookie on cross-site subresource requests and cross-site POST requests, while allowing it on some top-level cross-site navigations that use safe methods such as GET. Because state-changing actions must not be performed with GET, Lax provides useful protection for many applications.
SameSite=None allows the cookie to be sent in cross-site contexts and requires Secure. Applications that genuinely need cross-site cookies need strong explicit CSRF defenses.
SameSite is valuable defense in depth, but sensitive applications should still design their state-changing endpoints so that a browser cookie alone is not enough to authorize an unintended request.
For cookie-authenticated state-changing requests, the server can require an unpredictable anti-CSRF token in addition to the session cookie. The trusted application obtains the token and sends it with the state-changing request, commonly in a custom request header or protected form field.
A malicious cross-origin page normally cannot read a properly protected token from the bank because of the same-origin policy. The server validates the submitted token using its chosen CSRF-token design and rejects the request before changing state if the token is absent or invalid.
The token must have enough entropy to resist guessing, must be associated correctly with the application's authenticated request model, and must not be exposed through URLs, logs, or other unsafe channels.
Using a custom request header can add another useful property: ordinary cross-origin HTML forms cannot set arbitrary custom headers. Cross-origin JavaScript attempting to send such a non-simple header is subject to CORS preflight rules, which the bank should not authorize for untrusted origins.
For sensitive state-changing endpoints, the server can inspect the Origin header and compare it with an explicit allowlist such as https://bank.example.
If a request is expected to come only from the bank's own origin and its Origin value is untrusted, the server should reject it before changing state. Where an application needs a fallback for requests without Origin, a carefully validated Referer policy may be used according to the server's documented request model.
Origin matching must compare parsed origins exactly. Weak substring or suffix checks can accidentally trust attacker-controlled domains.
State-changing operations must not use GET. A URL that can be activated by a link, image, preload, or navigation must never create a payment merely because it was requested.
Use an explicit state-changing method such as POST for payment creation. Require the expected content type and CSRF proof, and reject malformed or unexpected request shapes before changing state.
A JSON API that requires an anti-CSRF custom header can be harder to invoke from ordinary attacker-controlled HTML because HTML forms cannot add arbitrary headers and cannot directly submit application/json. This is useful defense in depth, but the server should still enforce explicit CSRF and authorization controls rather than assuming a content type alone is sufficient protection.
For high-impact transactions, an application may also require transaction-specific confirmation or stronger user verification. Those controls complement rather than replace authorization and CSRF protection.
Authentication asks, 'Which authenticated session sent this request?'
Authorization asks, 'Is this authenticated user allowed to perform this payment?'
CSRF protection asks, 'Does this browser request satisfy the evidence required for an expected request from the trusted application flow?'
The trusted server must enforce every required check before creating the payment. A successful session-cookie check alone must not be treated as sufficient evidence of user intent.
If the anti-CSRF token is missing or invalid, or a required Origin check fails, the server should reject the request before creating the payment. Authorization failures must also fail before state changes occur.
Security logs can record information such as the endpoint, rejection reason, timestamp, and a safe correlation identifier. They should not record session-cookie values, anti-CSRF token values, credentials, or sensitive payment secrets.
Verification should include a legitimate request that is expected to succeed and negative tests that must fail. Test a cross-site request with no CSRF token, an incorrect token, an untrusted Origin, unexpected methods or content types, and the relevant SameSite cookie contexts. Confirm after each rejected request that no payment or other protected state change occurred.
- Identify whether authentication uses cookies that the browser sends automatically.
- Identify every state-changing endpoint, such as POST /api/payments.
- Confirm that the trusted server authenticates the session and separately authorizes the requested action.
- Configure the session cookie with Secure, HttpOnly, and the strongest practical SameSite policy.
- Require and validate an unpredictable anti-CSRF token for protected state-changing requests.
- Validate the request Origin against an exact trusted-origin allowlist when the application flow supports it.
- Keep state changes off GET endpoints and require expected methods, headers, content types, and request shapes.
- Reject failed CSRF, authentication, or authorization checks before changing state.
- Log rejection metadata without secrets.
- Verify the controls with legitimate requests and simulated cross-site attacks.
These protections add very little computation compared with normal request processing. SameSite enforcement is performed by the browser. Checking an Origin or validating a token usually requires only small comparisons or lookups for each request, with a small amount of extra request or session data. The larger cost is maintenance: choosing cookie behavior that does not break legitimate flows, implementing the token design consistently, maintaining trusted-origin rules, testing browser behavior, and ensuring every sensitive endpoint applies the required protections.
Interviewers want to know whether the candidate understands the browser trust boundary created by automatically sent cookies, the difference between authentication and authorization, why the same-origin policy and CORS do not by themselves prevent CSRF, and how layered controls such as SameSite cookies, anti-CSRF tokens, Origin validation, and safer request design reduce the risk.
Common mistakes are saying that the same-origin policy or CORS automatically prevents CSRF; treating a valid session cookie as proof that the user intended the action; assuming POST alone prevents forgery; performing state changes with GET; relying only on frontend JavaScript checks; treating HttpOnly as a CSRF defense; relying only on SameSite without considering application requirements; accepting missing or invalid anti-CSRF tokens; using weak Origin matching; forgetting server-side authorization; logging session cookies or CSRF tokens; and confusing CSRF with XSS. XSS means attacker-controlled script executes in the trusted application's origin and can often perform actions with the same privileges as legitimate frontend code, while classic CSRF normally causes authenticated requests without needing to read the protected cross-origin response.
Explain CSRF as a browser trust-boundary problem: the browser may automatically attach authentication, but the trusted server still needs authorization and evidence that a sensitive request satisfies the application's CSRF policy. Clearly separate authentication, authorization, SameSite, anti-CSRF tokens, same-origin policy, CORS, and Origin checks, then finish with safe rejection and verification.










