Rename PHP session cookie with __Secure-/__Host- prefix - php

I'm trying to rename my PHP session cookie from PHPSESSID to __Secure-PHPSESSID as per https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Examples.
Since PHP does not offer this mechanism, I am doing it through Apache server configuration:
RequestHeader edit Cookie ^__Secure-PHPSESSID(.*)$ PHPSESSID$1
Header edit Set-Cookie ^PHPSESSID(.*)$ __Secure-PHPSESSID$1
Header edit Set-Cookie ^(.*)(?<!SameSite=Strict)(?<!SameSite=Lax)$ "$1;SameSite=Lax"
This works correctly in Firefox, Edge, and Safari, but not Chrome. On Chrome, I can see that the cookie is set with the correct name and flags but I cannot log in to my site.
Upon login, the output of var_dump($_SESSION['internal']['user_name']) is NULL on Chrome but shows the correct username on Firefox and other browsers. I can also see that the session ID is being regenerated every time I try to log in and the value is set in the __Secure-PHPSESSID cookie.
I tried removing the SameSite flag (line 3 above) and it still does not work.
Any ideas?

PHP does indeed offer this mechanism. You can change it in php.ini. Just set this and restart the site:
session.name = __SECURE-PHPSESSID
To confirm it's right, restart your browser to clear previous session cookies.
As for Chrome not letting you log in, this page may give you some clues (see "Option Secure" and "Prefixes" sections): https://www.mon-code.net/post/108/Secure-cookie-of-you-web-application-with-PHP-or-Symfony
They are not well known, but supported by all browsers except those of
Microsoft. With prefixes, it's possible to force the browser to not
accept a cookie if it's misconfigured. There are two prefixes
"__Secure-" and "__Host-".
__Secure- forces the developer to add the secure flag to his cookie, otherwise it will be ignored by the browser.
setcookie('__Secure-user_id', 10, 0, '/', 'orion.dev', true);
__Host- is more restrictive, cookie must have the secure flag but also path to root and blank domain.
setcookie('__Host-user_id', 10, 0, '/', '', true);

I'm not familiar with Cookie Prefixes but PHP should support it out of the box:
<?php
session_name('__Secure-PHPSESSID');
session_start();

You can actually achieve it using PHP, changing session.name parameter. You can do it:
using session_name() in your PHP script
in .htaccess file
directly into CPanel table that shows PHP options (if you run CPanel)
Examples:
// Example way 1
session_name('Secure-PHPSESSID');
session_start();
// Example way 2
php_value session.name "Secure-PHPSESSID"

Related

PHPSESSID rejected non-HTTPS cookie

I'm using Apache 2.4.41 with PHP 7.4.3.
I've this script that write a session
<?php
// uno.php
session_start();
$_SESSION['chiave'] = 'TEST';
echo session_save_path();
?>
Due
When i click to Due link
<?php
// due.php
session_start();
print_r($_SESSION);
?>
I get that $_SESSION is empty.
Session.save_path is writeable and i see session file.
I see in firefox debug the messagge
Cookie PHPSESSID has been rejected because a non-HTTPS cookie can't be set as secure.
How can i solve this problem?
Thanks
Thanks
You have two options
Be secure
Use HTTPS instead of plain HTTP
Be insecure and tell PHP you don't care.
Keep using HTTP and change the session.cookie_secure option to off (which is its default value but one that must have been changed on your server).

How to set session cookies to http only in php.ini file

In my Ubuntu server, I modified the php.ini file to try and set my session cookies to http only to be more secure. I modified the line in the php.ini file from session.cookie_httponly = to session.cookie_httponly = 1, but still no success. When I view the inspect the page in chrome, my session cookies are still not flagged httponly. Are there any other steps I am missing to set the httpOnly flag on my session cookies? I've also tried adding ini_set("session.cookie_httponly", 1); before starting sessions, but still no success.

why cookie delete not working on my server but working fine on my local system?

The cookie is not deleting on my Debian apache server but deleting fine on my local xampp.
Here is the code i used for setting cookie
$token = substr(hash('sha512', mt_rand() . microtime()), 0, 50);
$extime = time()+86500;
$url_parts = parse_url(current_url());
$domain = str_replace('www.', '', $url_parts['host']);
// set cookie
setcookie('rememberme',$token,$extime,"/",$domain);
This code works on the server and rememberme cookie is created on the server.
Here is the code I used for deleting it
// Delete Cookie
setcookie('rememberme',"",0,"/");
The above code work fine on local but not working on my server.
I hosted the test application as subdomain with url like http://example.com/myproject and $domain give value .example.com
If someone knows why it not working properly on server please help me.
As per my comment: (and add the domain as an argument).
setcookie('rememberme',"",0,"/",$domain);
Many a times, it needs the domain.
From the manual on cookies: http://php.net/manual/en/function.setcookie.php and from User Contributed Notes:
"if you are having problems seeing cookies sometimes or deleting cookies sometimes, despite following the advice below, make sure you are setting the cookie with the domain argument. Set it with the dot before the domain as the examples show: ".example.com". I wasn't specifying the domain, and finally realized I was setting the cookie when the browser url had the http://www.example.com and later trying to delete it when the url didn't have the www. ie. http://example.com. This also caused the page to be unable to find the cookie when the www. wasn't in the domain. (When you add the domain argument to the setcookie code that creates the cookie, make sure you also add it to the code that deletes the cookie.)"

Is session.cookie_secure in php.ini automatic?

Simple answer requested:
If I put
session.cookie_httponly=On
session.cookie_secure=On
in the php.ini file for my website, will that automatically turn all the php cookies to secure and httponly, or will I still need to put in true, true into parameter slots 6 and 7 in the cookie itself?
The answer is yes. Setting this in php.ini is enough (however, I only saw "True" as the setting used instead of "On").
Session Cookie without HttpOnly flag set
https://www.owasp.org/index.php/HttpOnly#Using_PHP_to_set_HttpOnly
You can verify this by setting these values, restarting your webserver and accessing your site with a browser, e.g. Firefox. Then open "site information", and choose "security" tab and click on cookies. There you can see if it's marked as secure.

Can't access Session variables on different servers

I have dedicated a server to maintain Memcached and store sessions, so that all my servers can work on the same session without difficulties.
But somehow I think I may have misunderstood the meaning of Memcached possibilities about PHP sessions.
I thought that I would be able to stand on Apache 1 a.domain.com and create a session e.g. $_SESSION['test'] = "This string is saved in the session" and then go to Apache 2 b.domain.com or c.domain.com and simply continue the session and type echo $_SESSION['test']; and it would output the string.
It doesn't, but i am sure that I was told that memcached would be a great tool if you have multiple webservers to share the same session.
What have I done wrong?
By the way. We seriously need a fully detailed tutorial or ebook to describe how to set up the server, using php, building clusters etc. based on Memcached.
In my php.ini file it says:
session.save_path = "192.168.100.228:11211"
Tutorials told me not to define a protocol, and the ip address has been given to the Apache 3 - memcached Server
Here is an image of phpinfo()
The domain in session.cookie_domain is not called domain but it is a .local.
It has been changed for this image.
EDIT:
Just for information. When I am using a simple Memcached based PHP command - everything works perfectly. But somehow when I am trying to save a session, the memcached server doesn't store the item.
This works:
<?php
$m = new Memcached();
$m->addServer('192.168.100.228', 11211);
$m->set('int', 99);
$m->set('string', 'a simple string');
$m->set('array', array(11, 12));
/* expire 'object' key in 5 minutes */
$m->set('object', new stdclass, time() + 300);
var_dump($m->get('int'));
var_dump($m->get('string'));
var_dump($m->get('array'));
var_dump($m->get('object'));
?>
This doesn't work
<?php
session_start();
$_SESSION['name'] = "This is a simple string.";
?>
EDIT 2: THE SOLUTION
I noticed that after deleting the cache history including cookies etc. the browser didn't finish the job. The problem continued due to the fact, that it hang on to the original individual session id, which made each subdomain separated from each other.
Everything defined here is correct, just make sure your browser resets its cookies when you ask it to. >.<
By default (session) cookies are domain specific, so set the cookie domain in your php.ini
session.cookie_domain = ".domain.com"
Also see here
Allow php sessions to carry over to subdomains
Make sure to restart your webserver and clear all of your browser cookies after making the change. Your browser could get confused if you have cookies with the same name but different subdomains.
Other things to check:
That the sessions work fine on each individual server.
Make sure the session handler is set properly by using phpinfo() if you are working with a large codebase especially inherited / 3rd party stuff there may be something overriding it.
If you are using 3rd party code - like phpbb for instance - check that the cookie settings are correct in there too.
(please note this answer tidied to remove brainstorming, kept all relevant info)

Categories