# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Usage: Call isolated_session_start at the beginning of your script, # and call isolated_session_write_close at the end. # # Both functions take an optional secret HMAC key. # # NOTE: This probably won't protect you if you use register_globals. require_once "hmac_sha1.php"; require_once "netstrings.php"; function isolated_session_uniqueid() { $s_cookie_params = session_get_cookie_params(); ksort($s_cookie_params); $s_cookie_params_packed = array(); foreach($s_cookie_params as $k => $v) { $s_cookie_params_packed[] = netstrings_implode(array($k, $v)); } $s_cookie_params_packed = netstrings_implode($s_cookie_params_packed); $s_id = session_id(); $s_name = session_name(); $s_host = $_SERVER['HTTP_HOST']; return netstrings_implode(array( '1f450a52-04a4-11db-8ef0-0002a50ec775', 'isolated_session/0.2', $s_cookie_params_packed, $s_id, $s_name, $s_host)); } function isolated_session_destroy() { # Session data is invalid or unprotected. Start a new session. unset($_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775']); session_destroy(); foreach(array_keys($_SESSION) as $k) { unset($_SESSION[$k]); } session_regenerate_id(); } function isolated_session_start($key=null, $session_uniqueid=null) { if (!isset($key) or is_null($key)) { $key = ""; } @session_start(); if (is_null($session_uniqueid)) { $session_uniqueid = isolated_session_uniqueid(); } # Try to restore an existing session do { if (!isset($_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775'])) { break; } $raw_data = $_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775']; $a = netstrings_explode($raw_data); if (!$a) { break; } $stored_data = $a[0]; $stored_expire = $a[1]; $stored_hash = $a[2]; $hash_input = netstrings_implode(array( $session_uniqueid, $stored_data, $stored_expire)); #print "orig: $orig_hash_input\n"; #print "this: $hash_input\n"; # Check the hash $real_hash = hmac_sha1($hash_input, $key); if ($real_hash !== $stored_hash) { break; } # Check the expiry time if ($stored_expire != 0 and $stored_expire < time()) { break; } # Everything looks OK. Wipe the existing session data and load the # authenticated data. foreach(array_keys($_SESSION) as $k) { unset($_SESSION[$k]); } session_decode($stored_data); # Restore the raw session data $_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775'] = $raw_data; return; } while(0); # Session data is missing, invalid, or expired. Start a new session. isolated_session_destroy(); session_start(); return; } function isolated_session_write_close($key=null, $session_uniqueid=null) { if (!isset($key) or is_null($key)) { $key = ""; } if (is_null($session_uniqueid)) { $session_uniqueid = isolated_session_uniqueid(); } # Prepare the session data unset($_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775']); ksort($_SESSION); # Pack the session variables $s_data = session_encode(); # Wipe the original session variables foreach(array_keys($_SESSION) as $k) { unset($_SESSION[$k]); } # Get the expiry time $s_cookie_params = session_get_cookie_params(); if ($s_cookie_params['lifetime'] > 0) { $s_expire = time() + $s_cookie_params['lifetime']; } else { $s_expire = 0; } # Calculate the hash/MAC of the session data $hash_input = netstrings_implode(array( $session_uniqueid, $s_data, $s_expire)); $s_hash = hmac_sha1($hash_input, $key); # Add the packed session variables to $_SESSION $_SESSION['1f450a52-04a4-11db-8ef0-0002a50ec775'] = netstrings_implode( array($s_data, $s_expire, $s_hash)); # Commit the session data session_write_close(); } if (!defined('ISOLATED_SESSION__SILENCE_REGISTER_GLOBALS_WARNING') and ini_get('register_globals')) { trigger_error("register_globals is enabled. This is insecure!", E_USER_WARNING); }