Why do I have two session id in my header? - php

I'm using PHP5.3, Apache 2.2 and Zend Framework 1.11 and when I do a request with curl, I got two Set-Cookie headers with two differents session id.
Any ideas?
> POST /api/register HTTP/1.1
> Authorization: Basic Ymd1ZXJ0eQ==
> Host: api.domain.tld
> Accept: */*
> Content-Length: 66
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Date: Wed, 07 Dec 2011 13:27:07 GMT
< Server: Apache
< X-Powered-By: PHP/5.3.8
< Set-Cookie: SESSID=vtvackh55bj1up3ouoq4bhk545; expires=Thu, 06-Dec-2012 19:15:53 GMT; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Set-Cookie: SESSID=79a1g98e0pkqlq8fo7elpe9492; expires=Thu, 06-Dec-2012 19:15:53 GMT; path=/
< Vary: Accept-Encoding,User-Agent
< Content-Length: 128
< Content-Type: application/json

Your server application is emitting the Set-Cookie header twice. This can come from anywhere, impossible to tell without seeing all the code.
Look for things that deal with session handling. If there is third party code involved, disable it and see if the problem persists.

From Zend 1.11 documentation:
By default, Zend_Auth provides persistent storage of the identity from a successful authentication attempt using the PHP session.
Maybe you used somewhere AuthAdapter which start session and later on you are trying to manipulate it on your own starting another session with different session id.
I've experienced this issue in Zend 2.
I first used AuthenticationService to authenticate and after successful authentication I tried to use Zend Session Container to manipulate session.
I've used session container to explicitly regenerateId() and set some additional headers like secure, http_only and as a result I had two session headers like you.

Related

SessionID is not communicated between Client/Server in webpack4 project with php/apache backend

I'm testing out ZURB foundation which runs on webpack4, babel7 and gulp (as taskrunner). My backend is built with a no-installation, latest XAMPP. I'm running apache from it and my php.
The basis for client/server communication works.
Im using jquery AJAX to call php scripts and push/pull data to/from MariaDB.
Now I want some persistence for my login functionality.
I configured my php.ini so that the session files are located inside /Session folder which resides inside the src/assets folder of my ZURB Foundation project.
Here is a (rather large) excerpt from my php.ini. I included a bit more stuff because as I've learnt here How to configure session.save_path inside php.ini for webpack4 based website?
this might also be about cookies. And Im totally new to all this and Ive never configured any cookie functionality so far so I dont know which one of these settings might be important.
; where MODE is the octal representation of the mode. Note that this
; does not overwrite the process's umask.
; http://php.net/session.save-path
;session.save_path = "\xampp\tmp"
session.save_path = "D:\foundationtests\src\assets\Session"
; Whether to use strict session mode.
; Strict session mode does not accept an uninitialized session ID, and
; regenerates the session ID if the browser sends an uninitialized session ID.
; Strict mode protects applications from session fixation via a session adoption
; vulnerability. It is disabled by default for maximum compatibility, but
; enabling it is encouraged.
; https://wiki.php.net/rfc/strict_sessions
session.use_strict_mode = 0
; Whether to use cookies.
; http://php.net/session.use-cookies
session.use_cookies = 1
; http://php.net/session.cookie-secure
;session.cookie_secure =
; This option forces PHP to fetch and use a cookie for storing and maintaining
; the session id. We encourage this operation as it's very helpful in combating
; session hijacking when not specifying and managing your own session id. It is
; not the be-all and end-all of session hijacking defense, but it's a good start.
; http://php.net/session.use-only-cookies
session.use_only_cookies = 1
; Name of the session (used as cookie name).
; http://php.net/session.name
session.name = PHPSESSID
; Initialize session on request startup.
; http://php.net/session.auto-start
session.auto_start = 0
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; http://php.net/session.cookie-lifetime
session.cookie_lifetime = 0
; The path for which the cookie is valid.
; http://php.net/session.cookie-path
session.cookie_path = /
; The domain for which the cookie is valid.
; http://php.net/session.cookie-domain
session.cookie_domain =
; Whether or not to add the httpOnly flag to the cookie, which makes it
; inaccessible to browser scripting languages such as JavaScript.
; http://php.net/session.cookie-httponly
session.cookie_httponly =
; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF)
; Current valid values are "Lax" or "Strict"
; https://tools.ietf.org/html/draft-west-first-party-cookies-07
session.cookie_samesite =
; Handler used to serialize data. php is the standard serializer of PHP.
; http://php.net/session.serialize-handler
session.serialize_handler = php
so the current behavior is that session files are created, but not accessed.
I have the following phpExample1:
<?php
session_start();
$_SESSION["id"] = 10;
?>
Then I have phpExample2:
<?php
session_start();
$test = $_SESSION["id"];
echo $test;
?>
In this case I get the following error on my console.log() in the receiving JS code:
<br />
<b>Notice</b>: Undefined index: loggedUserID in <b>D:\foundationtests\src\assets\php\globallyUsedFunctions\retrieveLoggedUserID.php</b> on line <b>4</b><br />
There seems to be an issue that the session file containing the users session data cant be accessed, probably because the session ID was somehow lost/not transmitted. This is also indicated by the fact that phpExample1 actually creates a session file with the respective data, but when I run phpExample2, a new, empty session file is created. This also concurs with the php documentation which says that session_start(); either starts a new session or continues an existing one.
I have no idea which parts of my backend/front-end, webproject or XAMPP I have to lay my hands on to fix this problem. I'm also somehow lost on how to google this ^^
I already looked into php documentation and I also tried echoing session_id() from my phpExample2 after I had executed phpExample1. But I get an empty string to my console.log(), so basically nothing was found, which again fits into the context of session_start() creating new sessions instead of continuing the existing one.
EDIT:
As per request, I post the var_dump() result of $_REQUEST and $_COOKIE here:
array(0) {
}
array(0) {
}
EDIT2:
The response headers from the phpExample1 AJAX:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 2
Access-Control-Allow-Origin: *
Set-Cookie: io=27GSwfgTRlPYm5-nAAAU; Path=/; HttpOnly
Date: Mon, 26 Aug 2019 09:57:40 GMT
Connection: keep-alive
Okay I think I got the wrong one, THIS one should be right!
HTTP/1.1 200 OK
Date: Mon, 26 Aug 2019 10:09:19 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1c PHP/7.3.8
X-Powered-By: PHP/7.3.8
Set-Cookie: PHPSESSID=aaghn2jdh4hgfhlsagoep5lqvr; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Access-Control-Allow-Origin: *
Content-Length: 1
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
EDIT3:
the AJAX headers to phpExample1 look like this:
responseHeader:
HTTP/1.1 200 OK
Date: Mon, 26 Aug 2019 10:38:07 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1c PHP/7.3.8
X-Powered-By: PHP/7.3.8
Set-Cookie: PHPSESSID=bu2ggojkrkpqen33kh6r63pd36; path=/; domain=localhost:8099
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Access-Control-Allow-Origin: *
Content-Length: 1
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
requestHeader:
Host: localhost:8099
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 115
Origin: http://localhost:8000
Connection: keep-alive
Referer: http://localhost:8000/login.html
Then, the headers for phpExample2 (the php where the session should be continued and the data written to $_SESSION should be accessed) after phpExample1 had been executed:
responseHeader:
HTTP/1.1 200 OK
Date: Mon, 26 Aug 2019 10:38:09 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1c PHP/7.3.8
X-Powered-By: PHP/7.3.8
Set-Cookie: PHPSESSID=3isk6nf8fi2k3n4mfcfmtkv62d; path=/; domain=localhost:8099
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Access-Control-Allow-Origin: *
Content-Length: 367
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
requestHeader:
Host: localhost:8099
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:8000
Connection: keep-alive
Referer: http://localhost:8000/login.html
Content-Length: 0
Note that for these requests, I had set
session.cookie_domain = localhost:8099
inside my php.ini. I also tried out :8000 for this, but it didnt change anything except ofc for the headers showing a different port.

Joomla Not Sending Custom Header

So I've got a server to server application. The PHP script on server 1, domain 1 sets a custom header in the page (Authorization: Bearer 123456789). The script on server 2, domain 2 uses get_headers() to read the headers.
It all works fine when the files are served natively. But when the script on server 1 is included in a Joomla module get_headers() doesn't retrieve the custom header.
In both cases, developer tools shows the custom header but also some different headers than returned by get_headers().
The code below uses JFactory to set the headers if Joomla is loaded but it is the same result using header(). Joomla just isn't passing the custom header.
I don't get it. Anyone have any idea what is going on here? Its not a SEF or htaccess issue.
<?php
// Server 1
if(!class_exists("JFactory")){ // no Joomla
header('Authorization: Bearer 123456789');
} else { // Joomla framework loaded
$app = JFactory::getApplication();
$app->setHeader('Authorization: ', 'Bearer 123456789');
$app->sendHeaders();
}
The code on server 2:
<?php
// Server 2
$headers = get_headers("http://server1.com/");
foreach($headers as $header) {
echo $header ."<br/>";
}
Output from get_headers() when served natively:
HTTP/1.1 200 OK
Date: Thu, 19 Jan 2017 12:44:35 GMT
Server: Apache
Authorization: Bearer 123456789
Content-Length: 0
Connection: close
Content-Type: text/html
Output from get_headers() when served by Joomla:
HTTP/1.1 200 OK
Date: Thu, 19 Jan 2017 12:45:49 GMT
Server: Apache
Set-Cookie: 3c460b3da9ecb202e794816b4144c6ff=ja7mn4b4njov98lsv76kk8pvu2; path=/; HttpOnly
Vary: Accept-Encoding
Content-Length: 1264
Connection: close
Content-Type: text/html
Native headers displayed by developer tools:
Authorization: Bearer 123456789
Date: Thu, 19 Jan 2017 13:07:32 GMT
Server: Apache
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
Content-Length: 0
Content-Type: text/html
200 OK
Joomla headers displayed by developer tools:
Pragma: no-cache
Date: Thu, 19 Jan 2017 12:19:24 GMT
Last-Modified: Thu, 19 Jan 2017 12:19:25 GMT
Server: Apache
Authorization: : Bearer 123456789
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
Content-Length: 76888
Expires: Wed, 17 Aug 2005 00:00:00 GMT
Remove double dot from setheader call :
$app = JFactory::getApplication();
$app->setHeader('Authorization', 'Bearer 123456789');
$app->sendHeaders();
Thanks for the suggestion Yoleth. I tested this and got the same result.
However I have found the problem. The Joomla site setting the header is using a component called Site Lock. This is similar to putting the site off line but has some nice features for developers.
Basically Site Lock was preventing the page being served and just returning the headers from the lock page (as it should). I don't know why I didn't see it earlier. Sometimes just can't see the forest for the trees!

Sessions in PHP 5.3.3 and kirby

Situation
I have implemented a modified version of the kirby Auth plugin on a client website, it basically works this way
User accounts are simple kirby content files with the title serving as the login and a password field containing a bcrypt encrypted version of the users password
On the website, visitors can click on "Customer Area", which goes to a template managed by the modified auth plugin (which redirects to the "login" form).
The website is multilingual. So the accounts file will look like content/extranet/login/login.fr.txt or as an example content/extranet/bastian/bastian.fr.txt, this is what the modified Auth plugin is looking for, it finds the file and reads it, checks the password, and the logins the users.
This system requires account pages title to be the same as their URL, and to always be invisible pages
User is logged in and can only see in the « secure » template the files present in his folder
This all works good here on my local MAMP server as you can see in the screenshots, but on the production server http://www.driving-evolution.com, this doesn’t work, and i don’t know why, i have looked in a lot of places and i don’t understand what is going on. (it doesn’t work on the staging server either)
On the production server, wether you enter a good or a bad login, the form doesn’t show any error message, and doesn’t log the user in either. At first i thought this is maybe because of my bcrypt install, but it is not, as i disabled it (and used plain passwords instead) and it still didn’t work.
The issue seems NOT to be from the plugin here but from a difference between my live PHP stack and local php stack (my guess is on the php session handling).
Remote PHP is 5.3.3
Here is a sample output of CURL on both installations :
WORKING (Local)
curl -d "username=test&password=test" -i devo.loc/fr/login
HTTP/1.1 302 Found
Date: Tue, 27 May 2014 12:59:49 GMT
Server: Apache/2.2.25 (Unix) mod_ssl/2.2.25 OpenSSL/0.9.8y DAV/2 PHP/5.5.3
X-Powered-By: PHP/5.5.3
Set-Cookie: PHPSESSID=9249a942248a2382d8eb10090bf5d825; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: authFrontend=mc06csp25; expires=Wed, 28-May-2014 12:59:49 GMT; Max-Age=86400; path=/
Set-Cookie: PHPSESSID=b38ec0b342356c2c38778e4a6925f085; path=/
Set-Cookie: authFrontend=8qyyn; expires=Wed, 28-May-2014 12:59:49 GMT; Max-Age=86400; path=/
Location: http://devo.loc/fr/extranet
X-UA-Compatible: IE=edge
Vary: Accept-Encoding
Content-Length: 0
Content-Type: text/html; charset=utf-8
FAILING (Remote)
curl -d "username=test&password=test" -i www.driving-evolution.com/fr/login
HTTP/1.1 200 OK
Date: Tue, 27 May 2014 13:01:32 GMT
Server: Apache
X-Powered-By: PHP/5.3.3
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=6j9o1i4djetojtbg444i51efm7; path=/
Vary: Accept-Encoding
X-UA-Compatible: IE=edge
Connection: Keep-Alive, close
Transfer-Encoding: chunked
Content-Type: text/html
USEFUL LINKS
REMOTE PHPVER : http://www.driving-evolution.com/phpver.php
SCREENSHOTS when it works on local
Hope someone will be able to help me on this ! Ask for any further info and i will give it.
Turns out it WAS a problem with the CMS, file caching was turned on and not ignoring the "login", "logout", and "extranet" files (all related to customer area), had to add :
c::set('cache.ignore', array('api', 'sitemap', 'extranet', 'account', 'login', 'logout'));
to my kirby config (api and sitemap are unrelated).
This fixes the problem as the login form was cached and thus not hitting anything on the server. Now form is not cached.

PHPSESSID Cookie gets send multiple times

In my current application the PHPSESSID Cookie gets send multiple times. Here's a sample response:
HTTP/1.1 200 OK
Date: Tue, 11 Jun 2013 08:18:29 GMT
Server: Apache/2.2.17 (Ubuntu)
X-Powered-By: PHP/5.3.15-1~dotdeb.0
Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/ PHPSESSID=625qvi6328pdq2t7psh4t3voi6; path=/ PHPSESSID=625qvi6328pdq2t7psh4t3voi6; path=/ PHPSESSID=625qvi6328pdq2t7psh4t3voi6; path=/
Cache-Control: no-cache
x-debug-token: 9dcc688323f1dad273d4c8fc7117f405a52ce998
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-1
As you can see, there are three PHPSESSIDs.
I tried to reproduce this behavior with a single file with three session_start(); calls:
<?php
session_start();
session_start();
session_start();
but the cookie was send only once.
Any idea how this could happen?
I found the culprit. Somewhere deep in the legacy code was a session_commit which was called multiple times.

No reply when using flush(), session cookies and long execution time

I could reduce my problem to the following script I put on my server:
<?php
session_start();
header('Content-type: text/plain', TRUE);
flush();
sleep(300);?>
When I connect to this script using:
GET /test.php HTTP/1.1
Host: localhost
I get the header back right away as expected:
HTTP/1.1 200 OK
Date: Sat, 03 Nov 2012 20:15:53 GMT
Server: Apache/2.2.22 (Fedora)
X-Powered-By: PHP/5.3.17
Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
Set-Cookie: PHPSESSID=m7bmvblakkil96rqjq7j8f0f42; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain; charset=UTF-8
If I then kill the connection and reconnect using:
GET /proxy/test.php HTTP/1.1
Host: localhost
Cookie: PHPSESSID=knkeaq2ao0cllpcci0rnassqj4
I don't get any header back anymore until I restart my webserver.
I would have expected to again retrieve the response header right away.
I have really no idea why I get this behavior. Maybe it's some kind of a bug? Or I'm misunderstanding some behavior.
It would be great if somebody could help me with this as I really don't have a clue what's going on.
Ps:
Im running Apache/2.2.22 with PHP 5.3.17 on fedora 17, but the server packages are out of the fedora 16 repos as I need zend debugger which does not work with the PHP coming with fedora 17.
Because your session is still open in the first request (for 300 seconds) you cannot start using it in the second. It will wait until the first session is closed and written to the file-system before it will attempt to read it for the second request. Because you cannot be sure the first request wants to modify the same session-variables which are already in use by the second request.
You can use session_write_close() before the sleep so that the session variables become available immediatly. But then you cannot change any session variables after that.

Categories