Overview
Secure cookie flags are attributes that control how browsers store and send cookies. In React applications, cookies are often used for server-managed sessions, refresh tokens, CSRF tokens, preferences, or identity provider flows. The most important attributes for interviews are HttpOnly, Secure, SameSite, Path, Domain, Expires, and Max-Age.
This topic matters because cookie behavior is deceptively simple. A single missing flag can expose a session to JavaScript theft, allow cross-site request forgery, send credentials to too many subdomains, or keep a user logged in longer than intended.
React does not make cookies secure by itself. Cookie security is mainly controlled by the server's Set-Cookie header, browser behavior, HTTPS, CORS, CSRF protections, and the backend's authorization checks. The frontend must understand the consequences because API clients, route guards, refresh flows, and unauthorized UX all depend on the authentication model.
For interviews, this topic tests whether a candidate can explain browser security controls precisely and connect them to practical app behavior.
Core Concepts
Cookie Basics
A cookie is usually set by the server with a Set-Cookie response header.
Example:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
After the browser stores the cookie, it sends the cookie on future requests that match the cookie's domain, path, security, and same-site rules.
Important cookie facts:
- Cookies are small compared with other browser storage mechanisms.
- Cookies are sent automatically with matching requests.
- A server can set cookies that JavaScript cannot read.
- Cookies are scoped by domain and path.
- Cookies can expire at browser close or at a configured time.
- Cookies are not a complete security solution without server-side validation.
HttpOnly
HttpOnly tells the browser not to expose the cookie through JavaScript APIs such as document.cookie.
Example:
Set-Cookie: refreshToken=abc123; HttpOnly; Secure; SameSite=Strict; Path=/auth/refresh
Why it matters:
- Reduces direct cookie theft from XSS.
- Protects session IDs and refresh tokens from ordinary JavaScript access.
- Forces auth logic to rely on server validation or session endpoints instead of reading the token in React.
What it does not do:
- It does not stop the browser from sending the cookie with matching requests.
- It does not prevent CSRF by itself.
- It does not prevent XSS from performing actions as the user while the cookie is present.
- It does not remove the need for output encoding and CSP.
For session or refresh cookies, HttpOnly is usually expected.
Secure
Secure tells the browser to send the cookie only over secure HTTPS requests.
Example:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
Why it matters:
- Reduces exposure over plaintext HTTP.
- Should be used for authentication cookies.
- Is required for
SameSite=None.
Important nuance:
Secureprotects transmission, not JavaScript access.Securedoes not replaceHttpOnly.- Local development may need HTTPS or special local handling.
Production authentication cookies should use Secure.
SameSite
SameSite controls whether a cookie is sent with cross-site requests.
Common values:
Strict: send the cookie only for same-site requests.Lax: send the cookie for same-site requests and some top-level safe navigations.None: send the cookie in cross-site contexts; must be paired withSecure.
Example:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
Choosing a value:
Strictis strongest but can break sign-in redirects, links from email, or identity provider flows.Laxis a practical default for many session cookies.Noneis needed for true cross-site embedding or some third-party scenarios, but it increases CSRF exposure and requires careful controls.
SameSite helps reduce CSRF risk, but it should not be the only defense for sensitive unsafe operations.
Path
Path controls which URL paths receive the cookie.
Example:
Set-Cookie: refreshToken=abc123; HttpOnly; Secure; SameSite=Strict; Path=/auth/refresh
If Path=/, the cookie is sent to the whole site. If Path=/auth/refresh, it is only sent to requests under that path.
Useful patterns:
- Session cookie with
Path=/when the whole app needs it. - Refresh token cookie with a narrow refresh endpoint path.
- CSRF cookie with a path that matches the API surface that needs it.
Limits:
Pathis not a strong security boundary against malicious code on the same origin.- It mainly controls request matching.
- A broad
Path=/increases where the cookie is sent.
Use the narrowest path that still supports the app's flow.
Domain
Domain controls which hosts receive the cookie. If omitted, the cookie is host-only and applies only to the exact host that set it.
Example host-only cookie:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
Example broader domain cookie:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Domain=example.com; Path=/
Trade-off:
- Omitting
Domainis usually safer because the cookie is limited to the exact host. - Setting
Domain=example.comallows subdomains to receive the cookie. - If any subdomain is less trusted, broad domain cookies increase risk.
For sensitive auth cookies, prefer host-only cookies unless there is a clear cross-subdomain requirement.
Expiration: Session Cookies, Expires, and Max-Age
Cookie lifetime is controlled by Expires or Max-Age.
Examples:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
Set-Cookie: remember=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=2592000
If a cookie has no explicit expiration, it is a session cookie and is typically removed when the browser session ends. Browser session restore features can affect user expectations, so do not rely on this alone for critical security.
Max-Age sets lifetime in seconds. Expires sets an absolute date. When both are present, modern behavior gives Max-Age precedence.
For authentication:
- Use short lifetimes for high-risk credentials.
- Match cookie lifetime to server session lifetime.
- Expire cookies on logout.
- Rotate refresh tokens where appropriate.
Cookie Deletion
To delete a cookie, the server must set the same cookie name with matching Path and Domain attributes and an expiration in the past or Max-Age=0.
Example:
Set-Cookie: session=; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=0
Important:
- JavaScript cannot delete an
HttpOnlycookie. - The server must expire it.
- Path and domain must match the original cookie.
- Server-side session state should also be invalidated.
Logout should not only remove the browser cookie. It should also invalidate the session or refresh token server-side.
Cookie Prefixes
Cookie name prefixes can add browser-enforced constraints.
Common prefixes:
__Secure-: cookie must be set withSecurefrom a secure origin.__Host-: cookie must be set withSecure, must not includeDomain, and must usePath=/.
Example:
Set-Cookie: __Host-session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
The __Host- prefix is useful for sensitive host-bound cookies because it prevents broad domain scoping.
Cookie-Based Auth in React
When React uses cookie-based auth, the frontend often does not read the credential directly. Instead, it asks the server for session state.
Example:
async function loadCurrentUser() {
const response = await fetch("/api/me", {
credentials: "include",
});
if (response.status === 401) {
return null;
}
if (!response.ok) {
throw new Error("Failed to load session");
}
return response.json() as Promise<User>;
}
The frontend sees whether the user is authenticated based on server responses, not by reading the cookie.
For cross-origin APIs, credentialed requests also require correct CORS configuration from the server.
SameSite and OAuth Redirects
Authentication flows often involve redirects between an app and an identity provider. SameSite=Strict can break some redirect-based flows because the browser may not send the cookie when returning from another site.
Common approach:
- Use
SameSite=Laxfor main session cookies when top-level sign-in redirects are expected. - Use
SameSite=None; Secureonly when cross-site sending is required. - Use state and nonce parameters for OAuth/OIDC flows.
- Keep unsafe state-changing actions protected by CSRF controls.
The strongest cookie setting is not always the setting that works for the product. The correct setting balances security and the required navigation flow.
CSRF and Cookie Flags
Cookie flags reduce CSRF risk but do not eliminate every scenario.
Defense layers:
SameSite=LaxorStrictwhere compatible.- CSRF tokens for unsafe actions.
- Origin or Referer validation.
- No state-changing behavior on
GET. - CORS allow-listing for credentialed APIs.
Example double-submit style shape:
Set-Cookie: csrf=token-value; Secure; SameSite=Lax; Path=/
The JavaScript-readable CSRF cookie is different from an HttpOnly session cookie. It does not authenticate the user by itself. It is used to prove that the request came from a page that could read the CSRF value.
Local Development
Secure cookie behavior can be awkward locally.
Common approaches:
- Run local development over HTTPS.
- Use localhost-specific exceptions where the platform supports them.
- Keep production flags in production configs.
- Avoid weakening production behavior for local convenience.
Do not ship development cookie settings such as missing Secure, broad Domain, or SameSite=None without a real need.
Common Mistakes
Common mistakes include:
- Setting session cookies without
HttpOnly. - Setting auth cookies without
Securein production. - Using
SameSite=Nonewithout understanding cross-site risk. - Setting a broad
Domainfor sensitive cookies. - Using
Path=/for refresh tokens that only need one endpoint. - Forgetting that JavaScript cannot delete
HttpOnlycookies. - Clearing the browser cookie but not invalidating the server session.
- Relying only on
SameSitefor all CSRF protection. - Assuming
Pathis a strong security boundary. - Logging
Set-Cookieheaders or cookie values.
Best Practices
Best practices include:
- Use
HttpOnlyfor session and refresh cookies. - Use
Securefor production auth cookies. - Prefer
SameSite=LaxorStrictunless cross-site behavior is required. - Use
SameSite=None; Secureonly with a clear need. - Prefer host-only cookies by omitting
Domain. - Use narrow
Pathvalues when possible. - Align cookie expiration with server session expiration.
- Expire cookies and invalidate server sessions on logout.
- Consider
__Host-for sensitive host-bound cookies. - Add CSRF protection for unsafe cookie-authenticated requests.
- Keep frontend auth state derived from server validation.