Take the State of PHP 2026 Survey →

Secure Session Configuration Defaults View as Markdown

Implemented (PHP 8.6)
Authors
Jorg Sowa (jorg.sowa@gmail.com)
Date
2026-04-04
Target
PHP 8.6
Source
wiki.php.net/rfc/session_security_defaults

Votes

Change session.use_strict_mode default to 1? closed
Yes
27
No
0
Abstain
0
27 voters
alcaeus Yes 2026-05-07 13:37
alexandredaubois Yes 2026-05-07 12:33
ashnazg Yes 2026-05-06 17:35
ayesh Yes 2026-05-04 02:28
bwoebi Yes 2026-05-03 20:12
crell Yes 2026-05-07 18:28
daniels Yes 2026-05-04 02:57
derick Yes 2026-05-04 20:53
duncan3dc Yes 2026-05-07 12:17
galvao Yes 2026-05-04 09:16
girgias Yes 2026-05-04 12:27
iliaa Yes 2026-05-03 14:30
kalle Yes 2026-05-03 13:14
kguest Yes 2026-05-06 15:54
klaussilveira Yes 2026-05-07 20:39
marandall Yes 2026-05-04 07:45
mbeccati Yes 2026-05-04 16:51
narf Yes 2026-05-03 13:15
nicolasgrekas Yes 2026-05-13 20:35
petk Yes 2026-05-03 17:08
pmjones Yes 2026-05-08 00:33
ramsey Yes 2026-05-17 21:23
shivam Yes 2026-05-07 22:05
svpernova09 Yes 2026-05-06 14:37
theodorejb Yes 2026-05-03 18:44
timwolla Yes 2026-05-03 13:25
weierophinney Yes 2026-05-17 12:24
Change session.cookie_httponly default to 1? closed
Yes
26
No
0
Abstain
1
27 voters
alcaeus Yes 2026-05-07 13:37
alexandredaubois Yes 2026-05-07 12:33
ashnazg Yes 2026-05-06 17:35
ayesh Yes 2026-05-04 02:28
bwoebi Yes 2026-05-03 20:12
crell Yes 2026-05-07 18:29
daniels Yes 2026-05-04 02:57
derick Yes 2026-05-04 20:53
duncan3dc Yes 2026-05-07 12:17
galvao Abstain 2026-05-04 09:17
girgias Yes 2026-05-04 12:27
iliaa Yes 2026-05-03 14:30
kalle Yes 2026-05-03 13:13
kguest Yes 2026-05-06 15:54
klaussilveira Yes 2026-05-07 20:39
marandall Yes 2026-05-04 07:45
mbeccati Yes 2026-05-04 16:51
narf Yes 2026-05-03 13:15
nicolasgrekas Yes 2026-05-13 20:35
petk Yes 2026-05-03 17:08
pmjones Yes 2026-05-08 00:33
ramsey Yes 2026-05-17 21:23
shivam Yes 2026-05-07 22:05
svpernova09 Yes 2026-05-06 14:38
theodorejb Yes 2026-05-03 18:44
timwolla Yes 2026-05-03 13:25
weierophinney Yes 2026-05-17 12:25
Change session.cookie_samesite default to Lax? closed
Yes
26
No
0
Abstain
0
26 voters
alcaeus Yes 2026-05-07 13:37
alexandredaubois Yes 2026-05-07 12:33
ashnazg Yes 2026-05-06 17:58
ayesh Yes 2026-05-04 02:29
bwoebi Yes 2026-05-03 20:12
crell Yes 2026-05-07 18:29
daniels Yes 2026-05-04 02:58
derick Yes 2026-05-04 20:53
duncan3dc Yes 2026-05-07 12:17
galvao Yes 2026-05-04 09:17
girgias Yes 2026-05-04 12:27
iliaa Yes 2026-05-03 14:30
kalle Yes 2026-05-03 13:14
kguest Yes 2026-05-06 15:55
klaussilveira Yes 2026-05-07 20:40
marandall Yes 2026-05-04 07:46
mbeccati Yes 2026-05-04 16:51
narf Yes 2026-05-03 13:15
nicolasgrekas Yes 2026-05-13 20:35
petk Yes 2026-05-03 17:08
pmjones Yes 2026-05-08 00:33
ramsey Yes 2026-05-17 21:24
shivam Yes 2026-05-07 22:05
svpernova09 Yes 2026-05-06 14:38
theodorejb Yes 2026-05-03 18:45
timwolla Yes 2026-05-03 13:25

Discussions on the mailing list

[RFC] Secure Session Configuration Defaults
by Jorg Sowa · 3 messages
[VOTE] Secure Session Configuration Defaults
by Jorg Sowa · 6 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:50 UTC

Introduction

Three ini settings in PHP's session extension have security implications but ship with defaults that leave applications unnecessarily exposed. This RFC proposes changing those defaults so that new PHP installations are secure out of the box, without requiring application code changes for the common case.

The affected settings are:

  1. session.use_strict_mode — reject unrecognised session IDs supplied by the client
  2. session.cookie_httponly — exclude the session cookie from the JavaScript cookie API
  3. session.cookie_samesite — restrict cross-site delivery of the session cookie

Each change is a single-line edit to ext/session/session.c. No new ini entries, functions, or constants are introduced.

Background

Session Fixation (use_strict_mode)

Session fixation allows an attacker to pre-plant a known session ID and wait for a victim to authenticate against it. With use_strict_mode=0 (the current default), session_start() accepts any well-formed ID supplied in a cookie, $_GET, or $_POST and begins a session under that ID without verifying that the ID already exists in storage.

With use_strict_mode=1, php_session_initialize() calls s_validate_sid() on the proposed ID before accepting it. The built-in files handler checks whether a session file for that ID exists on disk; because an attacker-planted ID has no corresponding file, a fresh random ID is generated instead.

JavaScript Cookie Access (cookie_httponly)

The HttpOnly cookie attribute, defined in RFC 6265 §4.1.2.6 and supported by all browsers since IE 6, instructs the browser to exclude the cookie from the document.cookie API. A script running in the page — whether first-party or injected by an XSS attack — cannot read or exfiltrate an HttpOnly cookie.

PHP has supported session.cookie_httponly since PHP 5.2.0 (2006) and the flag has been universally recommended by security guidance (OWASP, Mozilla, NIST) ever since. There is no legitimate reason to default it to off.

CSRF via Cross-Site Requests (cookie_samesite)

The SameSite attribute controls whether the browser attaches a cookie to cross-site requests. Without it, a forged form or link on an attacker-controlled site can trigger authenticated requests using the victim's session.

PHP's session.cookie_samesite defaults to an empty string, which emits Set-Cookie with no SameSite attribute. Browsers have progressively tightened their handling of such cookies: Chrome applied SameSite=Lax as the default starting with Chrome 80 (February 2020). Firefox has been moving in the same direction as part of its privacy improvements (Enhanced Tracking Protection and cookie partitioning), aiming to reduce reliance on unspecified cross-site cookies, though its behavior is enforced through privacy controls rather than a single hard default rule Setting the attribute explicitly in PHP aligns the Set-Cookie header with browser behaviour and removes reliance on per-browser inference.

Setting SameSite=Lax on session cookies is recommended by (OWASP, Mozilla, NIST).

Comparison with Other Platforms

Platform HttpOnly default SameSite default
PHP ''0'' (off) not set
Java (Tomcat 11) ''true'' not set
ASP.NET Core ''true'' ''Lax''
Ruby (Rails) ''false'' (off) ''Lax''
Python (Django) ''true'' ''Lax''
Node.js (express-session) ''true'' None or Lax
Go (gin-contrib/sessions) ''false'' (off) not set
PHP (Laravel) ''true'' ''Lax''
PHP (Symfony) ''true'' ''Lax''

Proposal

Change the following three default values in ext/session/session.c:

INI setting Old default New default
session.use_strict_mode 0 1
session.cookie_httponly 0 1
session.cookie_samesite not set Lax

Backward Incompatible Changes

session.use_strict_mode = 1

Applications that deliberately supply an externally controlled session ID — for example, a shared-secret hand-off between subdomains using the files save handler — will have the ID rejected because no matching session file exists at the time of the first request. The correct approach is to write and close the session on the originating side (session_write_close()) before presenting the ID to the receiving side.

Applications using a custom session handler whose validateId() method returns true unconditionally are unaffected. This includes common backends such as Redis and Memcached when using the default php-memcached or phpredis session handlers, which do not implement validateId() and therefore fall back to returning true.

session.cookie_httponly = 1

The HttpOnly flag is enforced by the browser. It prevents the session cookie value from being read via document.cookie; it has no effect on whether the browser sends the cookie with requests.

Applications that read the session cookie value from document.cookie in JavaScript (for example, to embed the ID in a custom request header) will no longer be able to do so. The session ID is a server-side credential and should not be consumed by client-side code. Applications that need a client-accessible token for request correlation should use a separate, explicitly non-HttpOnly CSRF token rather than the session cookie itself.

session.cookie_samesite = Lax

With SameSite=Lax, the browser sends the session cookie on same-site requests and on top-level cross-site navigations using safe HTTP methods (GET, HEAD). It does not send the cookie on cross-site sub-resource requests or cross-site POST requests.

Applications that rely on cross-site POST carrying the session cookie — for example, SP-initiated SAML SSO flows or legacy cross-origin form submissions — must either set SameSite=None; Secure explicitly for those endpoints or migrate to a token-based flow.

As noted above, Chrome and Firefox already apply Lax as the implicit default for cookies sent without a SameSite attribute. Applications running on those browsers are already subject to this behaviour; the change makes it explicit and consistent across all browsers and PHP versions.

Browser support

The SameSite cookie attribute is supported across all modern browsers:

Browser SameSite support since Lax-by-default since Reference
Chrome 51 (May 2016) 80 (February 2020) Chrome blog
Firefox 60 (May 2018) 103 (August 2022) MDN
Safari 12.1 (March 2019) not applied WebKit blog
Edge 18 (October 2018) 85 (August 2020) Edge docs

Safari supports the attribute and respects an explicit SameSite=Lax value but does not apply Lax as an implicit default for cookies lacking the attribute. Setting the attribute explicitly in PHP therefore closes the cross-browser gap and removes reliance on per-browser inference.

Proposed PHP Versions

PHP 8.6.

Vote

As per the voting RFC, each change requires a 2/3 majority to pass. Each ini setting is voted on independently so that the internals list can accept a subset of the proposal.

Change session.use_strict_mode default from 0 to 1

Vote: Change session.use_strict_mode default to 1? — Yes: 27 · No: 0 · Abstain: 0 (closed)

Change session.cookie_httponly default from 0 to 1

Vote: Change session.cookie_httponly default to 1? — Yes: 26 · No: 0 · Abstain: 1 (closed)

Change session.cookie_samesite default from <empty string> to Lax

Vote: Change session.cookie_samesite default to Lax? — Yes: 26 · No: 0 · Abstain: 0 (closed)

Implementation

- https://github.com/php/php-src/pull/21938

References