Skip to content

session_starts sends duplicate Set-Cookie #18601

@kamil-tekiela

Description

@kamil-tekiela
Member

Description

The following code:

<?php

session_id('mysessionid');

session_start();
session_write_close();
session_start();

Resulted in this output:

HTTP/1.1 200 OK
Date: Mon, 19 May 2025 15:51:57 GMT
Server: Apache/2.4.62 (Win64) PHP/8.4.0 mod_fcgid/2.3.10-dev
X-Powered-By: PHP/8.4.0
Set-Cookie: PHPSESSID=mysessionid; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=mysessionid; path=/
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

But I expected this output instead:

HTTP/1.1 200 OK
Date: Mon, 19 May 2025 15:51:57 GMT
Server: Apache/2.4.62 (Win64) PHP/8.4.0 mod_fcgid/2.3.10-dev
X-Powered-By: PHP/8.4.0

Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=mysessionid; path=/
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

I tried with output buffering on and off. If I remove session_id() I cannot reproduce it again, but I only used it to create a reproducible example, as in the real project, it's sending duplicate headers even without it.

PHP Version

PHP 8.4 and Apache 2.4.62

> Apache/2.4.62 (Win64) PHP/8.4.0 mod_fcgid/2.3.10-dev

Operating System

Windows 10

Activity

kamil-tekiela

kamil-tekiela commented on May 19, 2025

@kamil-tekiela
MemberAuthor

Putting ini_set('session.use_cookies', 'false'); before the second session_start helps but it shouldn't be required. This becomes evident when you execute the script 2 times. The second time there should be 0 Set-Cookie but I still see 2 without this line and 0 with this line.

kkmuffme

kkmuffme commented on May 21, 2025

@kkmuffme

See #18169

kamil-tekiela

kamil-tekiela commented on May 21, 2025

@kamil-tekiela
MemberAuthor

I don't know about setcookie() but as I understand session_start() already has this feature build in. It just doesn't seem to work properly.

NattyNarwhal

NattyNarwhal commented on May 27, 2025

@NattyNarwhal
Member

I haven't tried Windows, but I've tried to reproduce this on macOS at least w/ CLI/CGI and can't get the duplicate header.

My understanding reading it, it initializes the session, calls reset_id, calls send_cookies, calls remove_cookie (which is looking for that specific Set-Cookie: PHPSESSID instance, then munging the header linked list directly, because the SAPI APIs don't have a way to remove a specific one), then appends the new one. That seems to work correctly (it removes the stale Set-Cookie: PHPSESSID, then appends the new one).

That said, I think I might clean up this session/SAPI header code anyways, because it is pretty ugly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @NattyNarwhal@kamil-tekiela@nielsdos@kkmuffme

        Issue actions

          session_starts sends duplicate Set-Cookie · Issue #18601 · php/php-src