Session Creation and Resumption using Cookies
ss.com
w/ no cookiesSet-Cookie
response header)ss.com
until the expiry dateSession Maintenance using Cookies
theme=yellow
)bool setcookie ( string $name
[, string $value
[, int $expire = 0
[, string $path
[, string $domain
[, bool $secure = false
[, bool $httponly = false ]]]]]] );
options
.<html>
, <head>
; or even just a whitespace)
Set-Cookie: sessionid=cj3v5cpkj3lwc3q; expires=Wed, 09 Jun
2021 00:00:00 UTC; path=/; domain=.example.com; secure; httponly
document.cookie = "sessionid=cj3v5cpkj3lwc3q;
expires=Mon, Feb 14 2015 00:00:00 UTC; httponly";
xhr = new XMLHttpRequest();
xhr.open("POST", "/somewhere", true);
xhr.setRequestHeader("Cookie"," sessionid=cj3v5cpkj3lwc3q");
somewhere
has set a cookie already, it'll be sent by defaultCookie: sessionid=cj3v5cpkj3lwc3q
HttpOnly
flag but become vulnerable, thus not recommended)document.cookie === "sessionid=cj3v5cpkj3lwc3q; name=value" // true
xhr.getResponseHeader("Set-Cookie")
Set-Cookie
headersetcookie(string $name [,string $value="" [,int $expires = 0
[,string $path ="" [,string $domain="" [, bool $secure = FALSE
[, bool $httponly = FALSE ]]]]]] ) : bool
Options | Description |
---|---|
name | cookie name |
value | value of this cookie |
expires | Expiry date of the cookie in GMT (see next slide) If not specified or set to 0, it's a "session cookie" |
path | Path for the cookie (default: "/") |
domain | Domain name for the cookie (default: the domain name of the app) |
secure | Marks the cookie to be sent over HTTPS only |
httpOnly | Accessible only by the web server but not thru JS |
escape()
to sanitize them)www.example.com
)
.example.com
: all *.
example.com receive the cookie
Ref.: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
C.com
, an advertisement downloaded from ad.com
will send a cookie back to ad.com
with a request header Referer
being the current URL at C.com
D.com
hosting the same adC.com
but only an iframe
visited ad.com
and being asked to write a cookie), but ad networks can still work around themtotalAmount
" in cookieshttp://weak.example.com
https
anyways).example.com
, even (you were told that) there is a PATH
attributehttps://secure.example.com
will receive both valid and malicious cookies// Given that list is an object that stores your data (e.g. key-value tuples: (pids, qtys))
// Encode it to a string before storing it in localStorage
localStorage.setItem('list', JSON.stringify(list));
// When page starts, restore and decode to get the original object
var list = localStorage.getItem('list');
list = list && JSON.parse(list);
// Remove the object if needed
localStorage.removeItem('list');
/tmp/sess_" + req.cookies.sessionid
/tmp/sess_" + req.cookies.sessionid
'SELECT data FROM sessions WHERE id = ?',
[req.cookies.sessionid]
'UPDATE sessions SET data = ? WHERE id = ?',
[data, req.cookies.sessionid]
session_start()
, PHP restores the superglobal array $_SESSION
based on the unique PHPSESSID token<?php
// setting a variable at pageA.php
session_start();
$_SESSION['username'] = 'niki'; ?>
<?php
//accessing the variable at pageB.php
session_start();
echo $_SESSION['username']; ?>
?PHPSESSID=x
)session_write_close()
is implicitly called to serialize $_SESSION
and store it in a server-side temp. file
PHPSESSID
code> expires when the browser terminates (i.e., header
expires:0
)hash_hmac()
is a keyed function to calculate a MAC $storedPW = hash_hmac('sha1', $password, $salt);
<?php
session_start();
function ierg4210_login() {
/* apply server-side validations here */
global $db;
$q = $db->prepare(
'SELECT salt, password FROM users WHERE email = ?');
if ($q->execute(array($_POST['em']))&&($r=$q->fetch())
&& $r['password']==hash_hmac('sha1',
$_POST['password'], $r['salt'])){
// When successfully authenticated,
// 1. create authentication token
// 2. redirect to admin.php
} else {
throw new Exception('auth-error');
}
} ?>
// if successfully authenticated
$exp = time() + 3600 * 24 * 3; // 3days
$token = array('em'=>$r['email'], 'exp'=>$exp,
'k'=> hash_hmac('sha1', $exp . $r['password'], $r['salt']);
// create the cookie
setcookie('auth', json_encode($token), $exp);
// put it also in $_SESSION
$_SESSION['auth'] = $token;
// change the PHPSESSID after login
session_regenerate_id();
return true;
function auth() {// returns email if valid, otherwise false
if (!empty($_SESSION['auth']))
return $_SESSION['auth']['em'];
if (!empty($_COOKIE['auth'])) {
if ($t = json_decode($_COOKIE['auth'], true)) {
if (time() > $t['exp']) return false;
global $db; // validate if token matches our record
$q = $db->prepare(
'SELECT salt, password FROM users WHERE email = ?');
if ($q->execute(array($t['em']))
&& ($r = $q->fetch())
&& $t['k'] == hash_hmac('sha1',
$t['exp'] . $r['password'], $r['salt'])) {
$_SESSION['auth'] = $_COOKIE['auth'];
return $t['em']; }
return false; // or header('Location: login.php');exit();
} } }
Ref.: https://www.owasp.org/index.php/Authentication_Cheat_Sheet