How to secure cookies in php? - php

How does session_set_cookie_params work?
I want to ensure all cookies are set with httponly=true, and secure=true.
But instead of adding these arguments to every call to setcookie(), I can
just - before session_start() - set them in session_set_cookie_params()?
And henceforth, every call to setcookie sets those params i each and every cookie?
That would save a lot of tedious work (and surely error-prone).
I would imagine something like this
$cookieParams = session_get_cookie_params();
$cookieParams['httponly'] = true;
$cookieParams['secure'] = true;
session_set_cookie_params($cookieParams);
session_start();
So now, if I do:
setcookie("ABC_user", "", time()+3600);
That cookie has those params in argument 6 and 7 set? Is there a way to check that it works? Or is there an even better way to accomplish this?

This simple code will give you what you want.
function set_cookie($name,$content,$time){
$http_only = true;
$secure = true;
$path = "/";
$domain = ".example.com"; // Include All Subdomains
setcookie($name,$content,$time,$path,$domain,$secure,$http_only);
}
set_cookie("ABC_user", "", time() + 3600);

Related

Detecting a cookie set using setcookie without a page reload

I am maintaining the code for an eCommerce website, they use a highly modified version of osCommerce v2.2 RC2. Was noticing an issue where the session isn't started for a new user until they visit the 2nd page of the site.
Looking at the code, before starting the session, it tries to set a cookie. If it detects the cookie it starts the session. Something along this line:
setcookie('cookie_test', 'please_accept_for_session', time()+60*60*24*30, $cookie_path, $cookie_domain);
if (isset($_COOKIE['cookie_test'])) {
session_start();
...
I found an article here that talks about a situation like this, it states:
The first time you only tell the browser to set the cookie, at the time, there is no cookie data in the request header (which could get from $_COOKIE).
Which explains why it takes two page loads for the session to be started. One to set the cookie and one to get notification from the browser that the cookie is set.
My question is, is there anyway around having to go through two page loads to detect the cookie was successfully set on the users browser?
I found this question that didn't really answer my question completely. The highest voted solution was:
setcookie('uname', $uname, time()+60*30);
$_COOKIE['uname'] = $uname;
Which may make it "work" but it doesn't truely tell me that the script was able to set a cookie successfully.
I also found this question, that suggested accessing the headers_list to find the cookie information like so:
function getcookie($name) {
$cookies = [];
$headers = headers_list();
// see http://tools.ietf.org/html/rfc6265#section-4.1.1
foreach($headers as $header) {
if (strpos($header, 'Set-Cookie: ') === 0) {
$value = str_replace('&', urlencode('&'), substr($header, 12));
parse_str(current(explode(';', $value, 1)), $pair);
$cookies = array_merge_recursive($cookies, $pair);
}
}
return $cookies[$name];
}
// [...]
setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . getcookie('uname');
Which, again, doesn't seem to be verifying that the cookie was set successfully. All this appears to do is search the headers being sent to the browser for the cookie value.
The only solution I can think of is to redirect on the first visit after setting the cookie. Is there any other way?
Here is the answer:
<?php
function set_cookie($name, $value) {
if (!isset($_COOKIE[$name]) || ($_COOKIE[$name] != $value)) {
$_COOKIE[$name] = $value;
}
setcookie($name, $value, strtotime('+1 week'), '/');
}
// Usage:
set_cookie('username', 'ABC'); //Modify the value to see the change
echo $_COOKIE['username'];

Retrieving wrong cookie (I'm using codeigniter)

I never worked with cookies before so I'm probably messing up really hard.
Thing is. I set a cookie and then try to echo it for testing. If I inspect my browser, it shows me the cookie is there, but the cookie being fetched is always one cookie previous to the one last created. Here is what I'm doing:
function set_cookie_test($user_id)
{
$this->load->helper('cookie');
$this->load->module('site_security');
$this->load->module('site_settings');
$now_time = time();
$one_day = 86400;
$one_week = $one_day * 7;
$one_week_ahead = $now_time + $one_week;
$data['cookie_code'] = $this->site_security->generate_random_string(128); // the cookie_code on the table is 128 chars long
$data['user_id'] = $user_id;
$data['expiry_date'] = $one_week_ahead;
$this->_insert($data);
$cookie_name = $this->site_settings->_get_cookie_name();
set_cookie($cookie_name, $value = $data['cookie_code'], $expire = $data['expiry_date'], $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE);
$cookieVal = get_cookie($cookie_name);
echo $cookieVal; die();
}
This is what happens after I log in (when I call this function)
As you can see, the cookie in the browser has a value of 8XvaQZjWX7... This is the current cookie, it matches my DB.
The previous cookie value in my db is the one being echoed out. I need to figure this out for the following reason:
Whenever I use sessions for the login, I set userdata so I can retrieve the user's info to display his name and avatar on the screen, for example.
I need to be able to do the same when I use cookies...
Any help is very much appreciated.

Too many redirects - cookies JS + php implementation

I have a simple website where you need only a password to access the contents. Then there are 3 fields where user inputs data, which are then stored in cookies. In the end - there is a logout script that resets the session and unsets cookies.
Please find the relevant code below:
Login page (index)
<?php
session_start();
$password = '';
$wrongPassword = '';
if (isset($_POST['sub'])) {
$password = $_POST['login_passcode'];
if ($password === 'PASSCODE') {
$_SESSION['login'] = true;
header('LOCATION:/personal.php');
die();
} else {
$wrongPassword = true;
}
}
if (isset($_COOKIE['m_username'])) {
header('LOCATION:/personal.php');
die();
}
?>
The page with contents, where user inputs name, department and start date
<?PHP
session_start();
if (!(isset($_SESSION['login']) && $_SESSION['login'] != '')) {
header("Location:/index.php");
die();
}
?>
and the logout script:
<?PHP
session_start();
if (isset($_COOKIE[session_name()])):
setcookie(session_name(), '', time() - 7000000,'/');
endif;
if (isset($_COOKIE['m_username'])):
setcookie('marriott_username', '', time() - 7000000,'/');
endif;
if (isset($_COOKIE['m_startdate'])):
setcookie('marriott_startdate', '', time() - 7000000,'/');
endif;
if (isset($_COOKIE['m_department'])):
setcookie('m_department', '', time() - 7000000,'/');
endif;
$_SESSION = array();
session_destroy();
header ("Location:/index.php");
die();
?>
jQuery to create cookies below:
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
Cookies do expire (at least on chrome), however after trying to access website after a few hours or days, I get the error about too many redirections. I believe this might be due to some differences between session expiration time and cookies expiration time (5 days for cookies), but I don't really know where to start fixing these...
Also, on Internet Explorer (IE8) the redirects problem occurs even when I go through logout directly.
Will be grateful for any help,
E.
You are correct in thinking different cookie expirations are behind the too many redirects problem.
If isset($_COOKIE['m_username']) is true in the index page, then you are redirected to the personal page, in which if if (!(isset($_SESSION['login']) && $_SESSION['login'] != '')) is also true, it sends you back to the index, therefore creating a loop. This would be caused by the session cookie expiring before the cookies you set.
The $_COOKIE and $_SESSION superglobals refer to two different sets of cookies. One solution is to use just the PHP session and store all your session data in the $_SESSION superglobal.
For example:
$_SESSION['m_username'] = 'whatever_value';
This will however generate an overhead in extra memory usage. If you still want to use your own cookies then just make sure any logic determining redirects is based on the session, not the presence of cookies you set.
For example:
// When logging in
$_SESSION['logged_in'] = true;
// On every page that requires login
if(!$_SESSION['logged_in']) // Redirect

Unset cookies php

I have this code that setted when login check is fine:
if((isset($_POST["remember_me"]))&&($_POST["remember_me"]==1))
{
setcookie('email', $username, time()+3600);
setcookie('pass', $pass, time()+3600);
}
Now, when I click on logout link (logout.php)
i did this:
<?php session_start();
setcookie("email", '', 1, "");
setcookie("pass", '', 1, "");
$_SESSION["login"] = "";
header("location: aforum/enter_furom.php");
?>
I didn't use destroy session because I don't want to destroy all sessions....
now destroying a session is working fine... but when I try to unset cookies, the browsers (all browsers: explorer, chrome, firefox, mozilla) give me an error saying that the new cookies cant be setted...any help to unset the above cookies ?
either use the superglobal _COOKIE variable:
unset($_COOKIE['mycookiename']);
or call setcookie() with only the cookies name
setcookie('mycookiename');
To reset your cookies at logout use:
setcookie('pass');
setcookie('email');
For you login check:
if(
isset($_POST["remember_me"]) &&
$_POST["remember_me"]==1 &&
$_COOKIE['pass'] != NULL &&
$_COOKIE['email'] != NULL &&
)
setcookie('cookiename', '', time()-3600);
unset($_COOKIE['MYCOOKIE']);
//
setcookie('MYCOOKIE', '', -1, '/');
Care for header "Cannot modify header information.." you can also
use html or javascript for redirect
header("Location: /");
//
echo '<meta http-equiv="refresh" content="0;URL=/">';
//
echo '<script>window.location.replace("/");</script>';
I prefer to check with isset and than unset | setcookie
if(isset($_COOKIE['MYCOOKIE'])) { unset($_COOKIE['MYCOOKIE']); }
//
if(isset($_COOKIE['MYCOOKIE'])) { setcookie('MYCOOKIE', '', -1, '/'); }
this seems to work too, but don't use it in my opinion
setcookie('MYCOOKIE', '', -1, '/') ?? '';
!isset($_COOKIE['MYCOOKIE']) ?: setcookie('MYCOOKIE', '', -1, '/');
Check in your browser for the directory where the cookie operates. And unset it by specify the path the cookie have. Like in the example if the cookie directory is /aforum/
setcookie ("email","",time()-1,"/aforum/","http:// yourdomain.com");
Just set the value of cookie to false in order to unset it,
setcookie('cookiename', false);
That's the easiest way to do it.
To unset cookies in PHP, simply set their expiry time to a time in the past. For example:
$expire = time() - 300;
setcookie("email", '', $expire);
setcookie("pass", '', $expire);
try this
setcookie ("email", "", time() - 3600);
setcookie ("pass", "", time() - 3600);
You need to set your expire time to the past, e.g.
setcookie('email', '', time()-3600);
Also you should be using an Absolute URI for your header('Location:' ....).
In Chrome and IE8+ at least, the following will remove the cookie from the browser. It will not be reflected in the $_COOKIE array until the page is reloaded however.
setcookie('cookiename','',0,'/',$cookieDomain)
you may be able to leave off a few parameters here, but the important thing is you are setting an empty string, and that removes the cookie from the browser.

Cookies are not removing on Log Out

I've got a problem, user can't Log Out because the $_COOKIE's are not actually deleting. I can't find out what could be the problem.
This code is used only once at Log In:
// Log In
$_SESSION['user_id'] = $row['user_id'];
$_SESSION['username'] = $row['username'];
setcookie('user_id', $row['user_id'], time() + 2592000);
setcookie('username', $row['username'], time() + 2592000);
The code below is checking if cookies are set up to make users to be logged in when they relaunch their browser (the "keep me logged in" effect).
// Starting Session
session_start();
// If the session vars aren't set, try to set them with cookies
if (!isset($_SESSION['user_id'])) {
// This check always equals true because cookies are not deleting on Log Out
if (isset($_COOKIE['user_id']) && isset($_COOKIE['username'])) {
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['username'] = $_COOKIE['username'];
}
}
This code is launched only once on Log Out:
// Log Out
session_start();
if (isset($_SESSION['user_id'])) {
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 2592000, '/');
}
session_destroy();
}
setcookie('user_id', '', time() - 2592000);
setcookie('username', '', time() - 2592000);
Don't use relative times for cookies. if you want to expire a cookie, then use Jan 1 1970 00:00:00. You're assuming that the user's clock is accurate and within an hour of your server's. Given how many people have their VCRs blinking 12:00, this is a bad assumptiong.
As well, why are you storing login information in a client-side cookie? The only cookie you should really be setting is the session cookie, which session_start() already does for you, then store all that information in $_SESSION only.
I think you're doing it way too complicated.
My example where it's just an admin login:
login.php
#session_start();
if (isset($_GET['login'])) {
if($_GET['name'] == $s['admin']){
if($_GET['pw'] == $s['adminpw']){
$_SESSION['isadmin'] = true;
}
}
}
logout.php
#session_start();
unset ($_SESSION['isadmin']);
use session_set_cookie_params() to set the lifetimes
I found why cookies were not removing!
To make sure your cookies will remove, set the same path on removing cookies as on setting them.
// Setting Cookie
setcookie(session_name(), '', time()-2592000, '/'); // The path here is "/"
// Removing Cookie
setcookie(session_name(), '', time()+2592000, '/'); // The path here is "/"

Categories