33

Whats the recommended way to set httponly and secure flags on the PHPSESSID cookie?

I found http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly. Any better suggestions?

thanks

Steve
  • 3,601
  • 4
  • 34
  • 41
  • 6
    That and [`session.cookie_secure`](http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-secure) is basically it. I don't think there are any easier / better methods. – Wrikken Jul 25 '11 at 20:29
  • Are you aware that ini_set() works just fine with session.cookie_httponly and session.cookie_secure? Just set them before you call session_start(). – jorisw Jan 16 '13 at 13:51

8 Answers8

24
ini_set('session.cookie_httponly', 1);

more information here on the PHP docs

msturdy
  • 10,479
  • 11
  • 41
  • 52
user2741089
  • 241
  • 2
  • 2
22

In my opinion the best would be: http://www.php.net/manual/en/function.session-set-cookie-params.php

void session_set_cookie_params ( int $lifetime [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]] )
Johan
  • 1,958
  • 11
  • 20
  • yeah but this affects all cookies? – Steve Jul 26 '11 at 06:36
  • This will only affect session cookies (PHPSESSID) for a single site. Did you want a server wide setting? – Johan Jul 26 '11 at 07:18
  • my bad. temporary blindness... combining session_get_cookie_params() to get the lifetime, path, etc then passing those back to session_set_cookie_params() will do all that i need. thanks! – Steve Jul 26 '11 at 22:04
  • I recommend setting this at the php.ini level. The reason is that it is fairly easy to mess up PHP code. For example, some complex PHP applications can be accessed through direct HTML document request, AJAX requests, cron tasks, etc. that may have multiple places where `start_session()` is called. Additionally, configuration may be off. Just my input, I think this makes the most sense as `session.cookie_domain=1` and `session.cookie_secure=1` in php.ini. Simple, and done. – ryanm Jan 24 '18 at 13:58
  • 1
    ryanm : According to php.ini and https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain session.cookie_domain is a string for the domain not a boolean ; The domain for which the cookie is valid. ; http://php.net/session.cookie-domain session.cookie_domain = – jmatos Sep 03 '19 at 09:01
18

I was unable to get the secure flag working with session_set_cookie_params(...), so what I did was, after session_start() set the PHPSESSID cookie, I reset it with setcookie(...). The final parameter, true, makes the cookie have a secure flag.

<?php  
session_start();  
$currentCookieParams = session_get_cookie_params();  
$sidvalue = session_id();  
setcookie(  
    'PHPSESSID',//name  
    $sidvalue,//value  
    0,//expires at end of session  
    $currentCookieParams['path'],//path  
    $currentCookieParams['domain'],//domain  
    true //secure  
);  
?>

When I checked the PHPSESSID cookie in Firefox, its 'Send for' property was set to 'Encrypted connections only' and its 'Expires' property was set to 'At end of session'.

Veger
  • 37,240
  • 11
  • 105
  • 116
allieferr
  • 308
  • 1
  • 6
  • This method worked for me when `session_set_cookie_params` would not. – Sharlike Jan 28 '14 at 17:21
  • There's a more concise alternative: `session_regenerate_id()`. See http://stackoverflow.com/a/27242745/560114. (Not sure whether such a workaround [either yours or session_regenerate_id()] is still needed in newer versions of PHP.) – Matt Browne Jun 15 '16 at 17:55
  • Never mind, it turns out I was being thrown off by caching - simply using ini_set() to set session.cookie_httponly and session.cookie_secure or putting the settings in an htaccess file should be sufficient, at least as of PHP 5.3.3. – Matt Browne Jun 15 '16 at 18:07
6

A more elegant solution since PHP >=7.0

session_start(['cookie_lifetime' => 43200,'cookie_secure' => true,'cookie_httponly' => true]);

session_start

session_start options

Hein
  • 71
  • 1
  • 2
2

I use Apache httpd over HTTPS, set session.cookie_httponly = 1 & session.cookie_secure = 1 works for me.

hyjiacan
  • 76
  • 2
2

For a WordPress website, I fixed it using the following PHP code:

add_action('init', 'start_session', 1);
function start_session() {
    if(!session_id()) {
        session_start();
        $currentCookieParams = session_get_cookie_params();
        $sidvalue = session_id();
        setcookie(
            'PHPSESSID',//name
            $sidvalue,//value
            0,//expires at end of session
            $currentCookieParams['path'],//path
            $currentCookieParams['domain'],//domain
            true //secure
        );
    }
}

add_action('wp_logout','end_session');
add_action('wp_login','end_session');
function end_session() {
    session_destroy();
}

Paste the code in the functions.php file.

Manik Malhotra
  • 614
  • 6
  • 10
0

If you are using Apache, try this on your .htaccess

php_value session.cookie_httponly 1
Trac Nguyen
  • 486
  • 4
  • 8
0

Using .htaccess for this purpose just slows down your application.

I think its better to add this snippet in your main config file ( example config.php ) or main include file ( example global.php )

    // Prevents javascript XSS attacks aimed to steal the session ID
    ini_set('session.cookie_httponly', 1);

    // Prevent Session ID from being passed through  URLs
    ini_set('session.use_only_cookies', 1);

If you are using https:// instead of http:// , then also do

     // Uses a secure connection (HTTPS) 
     ini_set('session.cookie_secure', 1); 

This method is also suitable for thos who dont have access to php.ini

MarcoZen
  • 1,556
  • 22
  • 27