/** * Generates a hash/expiry double. If time isn't set it will be calculated * from the current time. */ function csrf_hash($value, $time = null) { if (!$time) { $time = time(); } return sha1(csrf_get_secret() . $value . $time) . ',' . $time; }
/** * Checks if a token is valid. */ function csrf_check_token($token) { if (strpos($token, ':') === false) { return false; } list($type, $value) = explode(':', $token, 2); if (strpos($value, ',') === false) { return false; } list($x, $time) = explode(',', $token, 2); if ($GLOBALS['csrf']['expires']) { if (time() > $time + $GLOBALS['csrf']['expires']) { return false; } } switch ($type) { case 'sid': return $value === csrf_hash(session_id(), $time); case 'cookie': $n = $GLOBALS['csrf']['cookie']; if (!$n) { return false; } if (!isset($_COOKIE[$n])) { return false; } return $value === csrf_hash($_COOKIE[$n], $time); case 'key': if (!$GLOBALS['csrf']['key']) { return false; } return $value === csrf_hash($GLOBALS['csrf']['key'], $time); // We could disable these 'weaker' checks if 'key' was set, but // that doesn't make me feel good then about the cookie-based // implementation. // We could disable these 'weaker' checks if 'key' was set, but // that doesn't make me feel good then about the cookie-based // implementation. case 'user': if ($GLOBALS['csrf']['secret'] === '') { return false; } if ($GLOBALS['csrf']['user'] === false) { return false; } return $value === csrf_hash($GLOBALS['csrf']['user'], $time); case 'ip': if (csrf_get_secret() === '') { return false; } // do not allow IP-based checks if the username is set, or if // the browser sent cookies if ($GLOBALS['csrf']['user'] !== false) { return false; } if (!empty($_COOKIE)) { return false; } if (!$GLOBALS['csrf']['allow-ip']) { return false; } return $value === csrf_hash($_SERVER['IP_ADDRESS'], $time); } return false; }