WebApp Sec mailing list archives
Re: How to create (hijacking) secure HTTP sessions?
From: ascii <ascii () katamail com>
Date: Sun, 04 Jun 2006 00:43:04 +0200
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 --------------------------------------------------------------------------
Current thread:
- How to create (hijacking) secure HTTP sessions? Michael Decker (Jun 02)
- Re: How to create (hijacking) secure HTTP sessions? Jason Muskat (Jun 02)
- Re: How to create (hijacking) secure HTTP sessions? Adam Tuliper (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? Michael Decker (Jun 07)
- Re: How to create (hijacking) secure HTTP sessions? Adam Tuliper (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? Ivan Ristic (Jun 03)
- Re: How to create (hijacking) secure HTTP sessions? Michael Decker (Jun 07)
- Re: How to create (hijacking) secure HTTP sessions? Nathan Keltner (Jun 08)
- Re: How to create (hijacking) secure HTTP sessions? Michael Decker (Jun 07)
- Re: How to create (hijacking) secure HTTP sessions? ascii (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? Robin Wood (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? ascii (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? Rogan Dawes (Jun 05)
- Re: How to create (hijacking) secure HTTP sessions? ascii (Jun 07)
- Re: How to create (hijacking) secure HTTP sessions? stefano (Jun 05)
- Re: How to create (hijacking) secure HTTP sessions? Robin Wood (Jun 04)
- Re: How to create (hijacking) secure HTTP sessions? Jason Muskat (Jun 02)
- <Possible follow-ups>
- RE: How to create (hijacking) secure HTTP sessions? Evans, Arian (Jun 08)
- RE: How to create (hijacking) secure HTTP sessions? Evans, Arian (Jun 08)