web php

Cookie Attributes

Cookie attributes control when the browser stores a cookie, when it sends that cookie back, and whether JavaScript can read it. They are part of the security and behaviour of authentication, session, preference, and "remember this device" flows.

Cookie values are still client-controlled data. Attributes reduce risk, but they do not turn a plain cookie into trusted storage.

Common attributes

PHP example
<?php

declare(strict_types=1);

$attributes = [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
];

foreach ($attributes as $name => $value) {
    echo $name . ': ' . (is_bool($value) ? ($value ? 'true' : 'false') : $value) . PHP_EOL;
}

// Prints:
// expires: 1790000000
// path: /
// secure: true
// httponly: true
// samesite: Lax

expires controls when the browser should remove the cookie. Without expires or max-age, the cookie is a session cookie and normally disappears when the browser session ends.

path limits which URL paths receive the cookie. path => '/' sends it to the whole site.

domain controls which hostnames receive the cookie. Avoid setting it unless you need subdomain sharing.

secure tells the browser to send the cookie only over HTTPS.

httponly stops JavaScript from reading the cookie through document.cookie. It does not stop the browser from sending the cookie with requests.

samesite controls whether the browser sends the cookie on cross-site requests. Lax is a common default. Strict is tighter but can break some flows. None allows cross-site use but requires Secure.

Authentication and session cookies should normally use strong attributes:

PHP example
<?php

declare(strict_types=1);

setcookie('remember_device', 'opaque-random-token', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

echo 'Remember-device cookie prepared.' . PHP_EOL;

// Prints:
// Remember-device cookie prepared.

The value should be an opaque random token that maps to server-side data, not a plain user ID or role.

Attribute tradeoffs

Use HttpOnly for cookies that JavaScript does not need to read, especially session and auth cookies. Leave it off only for non-sensitive values that client-side JavaScript genuinely needs, such as a display preference.

Use Secure in production for cookies that matter. If a cookie must work over local HTTP during development, make that a local-only exception.

Use SameSite=Lax for many normal browser apps. Use SameSite=None; Secure only when the cookie must be sent in a third-party context, such as some embedded apps or cross-site authentication flows.

Browsers recognise prefixes that require stronger settings.

__Secure-  requires the Secure attribute
__Host-    requires Secure, path=/, and no Domain attribute

For a host-only session cookie, __Host-session is a useful shape because the browser enforces important scope rules. The application and framework still need correct session handling.

Session Cookies And Remember-Me Cookies

A session cookie and a remember-me cookie solve different problems.

A session cookie identifies the current short-lived server-side session. A remember-me cookie should normally contain an opaque random token linked to a server-side record that can be revoked, rotated, and expired.

Do not put a password, password hash, role, or permanent user ID in a remember-me cookie and treat possession as enough proof forever. Build a revocation path for logout, password changes, and suspicious activity.

What you should be able to do

After this lesson, you should be able to choose sensible cookie attributes, explain what HttpOnly, Secure, and SameSite do, understand path/domain scope and cookie prefixes, distinguish session cookies from remember-me tokens, and avoid storing trusted application facts in editable cookie values.

Practice

Task: Choose Cookie Attributes

Create a PHP example or checklist for setting a remember-device cookie.

Requirements

  • Use an opaque token value, not a user ID.
  • Set expires, path, secure, httponly, and samesite.
  • Explain why HttpOnly is useful.
  • Explain why Secure depends on HTTPS.
  • Explain when SameSite=None would need extra care.

Check your work

The answer should make the cookie safer without pretending that cookie attributes replace server-side validation.

Show solution
PHP example
<?php

declare(strict_types=1);

$token = bin2hex(random_bytes(16));

setcookie('remember_device', $token, [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

echo strlen($token) . PHP_EOL;

// Prints:
// 32

HttpOnly reduces the chance that JavaScript can read the token if XSS exists. Secure means the browser should send it only over HTTPS. SameSite=None is needed for some cross-site cookie flows, but it must be paired with Secure and should be chosen deliberately because it allows the cookie to travel in more cross-site situations.