|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
Re: How to create (hijacking) secure HTTP sessions?
From: ascii (ascii
katamail.com)
Date: Sat Jun 03 2006 - 17:43:04 CDT
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Michael Decker wrote:
> * HTTP session ID joined with IP and SSL session ID
> * Block all session ID usings, that do'nt match IP and SSL session ID
very informative thread, thanks Michael for the initial checklist and
Jason and Ivan for the replies
few things remain to be added
putting remote address into the session is very effective
against session fixation, every type of application (over ssl or not)
should implement this type of check (tcp ip spoofing is more expensive
that user agent spoofing)
if (!isset($_SESSION['remoteip']))
$_SESSION['remoteip'] = $_SERVER['REMOTE_ADDR'];
if (isset($_SESSION['remoteip']))
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['remoteip'])
do_something();
i have seen code that accomplish this task using a db table but it's
easier and better to put the client ip directly into the session
this should play better on https then on http because commonly ssl
connections are direct (while some isp split the http traffic over
different proxy servers and several public ips)
checking the ssl sid is a nice bonus (but as ivan pointed the browser
could reestablish the ssl channel with an other ssl session id)
also making some anti tampering check could be useful (eg: md5 of
user agent, remote ip, accept languages and so on) but this could
harm the session because some browsers modify request header values
runtime/per-page
another issue is that user agent and in general all request headers
are very predictable, so this system mainly relay on the ip address
anyway there are a lot of things you can do to improve the security of
a session but most of them will compromise the usability of the webapp
(and you have to find a trade-off between security and usability, arg!)
auto expiring is useful if the user forgot the browser open and authed
if (isset($_SESSION['lastseen']) &&
time() > $_SESSION['lastseen'] + 300) // five minutes
do_something();
else $_SESSION['lastseen'] = time();
limit the session max duration make impossible to maintain a certain
session active forever
if (!isset($_SESSION['firstseen']))
$_SESSION['firstseen'] = time();
if (isset($_SESSION['firstseen']))
if (time() > $_SESSION['firstseen'] + 3600) // one hour
do_something();
session_regenerate_id() or equivalent should be called both randomly
and on privilege changes/login, also the system should destroy the old
session as in php 5.1.0 after an ilia's commit (you have to issue a TRUE
as first argument)
then using strict mode sessions make you sure that the session id has
been chosen by the application, you can archive this result with
if (!isset($_SESSION['fromapp']) || (isset($_SESSION['fromapp'])
&& $_SESSION['fromapp'] !== TRUE))
session_regenerate_id(TRUE);
$_SESSION['fromapp'] = TRUE;
note that do_something() could be destroy_user_session() as
trigger_error('woop!', E_USER_NOTICE), this is something that needs
specific tuning (on an internet banking you might want session drops
and a super restrictive set of checks, on ebay you cannot force users
to install a browser != than IE to chain the session with their accept-*
request headers)
i have not verified my code, but it has passed the thunderbird
spelling check : )
so the complete checklist could be:
- use ssl
- use a long and really random string as session id
- ssl private certs
- ssl digest (DSA* uses a 160 bit prime and SHA, witch is much better
than md5 i think)
- total time limited sessions
- set http session timeout
- auto expiring sessions (inactive user)
- auto expiring requiring user iteration (captcha, image recognition,
otp) (if anal also on an active user)
- chain the session id with the client ip (and block others)
- if applicable chain the session id with the ssl session id (and block
others)
- regenerate the session id after login/privilege changes (eg:
session_regenerate_id(TRUE) see ilia's patch for php 5.1.0)***
- logout destroy the session
- allow only one active login (with 'timeouts' or something better)
- strictly set all cookie's options (path, domain, secure)**
setcookie (string name [, string value [, int expire [, string path [,
string domain [, bool secure]]]]])
- do not mix ssl and non-ssl
- store sessions on memcached or on the fs but with a different path for
every vhost
- strict mode sessions (esser wrote this article on the
topic http://www.hardened-php.net/index.48.html)
correct me if needed (-;
Regards, Francesco 'ascii' Ongaro - http://www.ush.it/
* DSS (Digital Signature Standard)
http://www.itl.nist.gov/fipspubs/fip186.htm
** es: with mod_rewrite and cookie path we can issue two different
sessions for bank.tld/site/ and bank.tld/panel/ and an xss on site/
will never reveal the panel/ cookie
*** ilia session_regenerate_id patch
http://ilia.ws/archives/47-session_regenerate_id-Improvement.html
http://it.php.net/session_regenerate_id
-------------------------------------------------------------------------
Sponsored by: Watchfire
Watchfire named worldwide market share leader in web application
security assessment by leading market research firm. Watchfire's AppScan
is the industry's first and leading web application security testing
suite, and the only solution to provide comprehensive and consolidated
remediation task lists at every level of the application. See for
yourself.
Download a Free Trial of AppScan 6.0 today!
https://www.watchfire.com/securearea/appscansix.aspx?id=701300000007t9c
--------------------------------------------------------------------------
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]