关于会议的几个问题/问题

时间:2011-11-07 13:09:57

标签: php session

我编写了我的第一个会话系统。问题如下。

  // INDEX.PHP
    include("db.php"); // this file starts session with session_start(); also changes the default session name

    if($_POST['login']){ $login = escape($_POST['login']); }
    if($_POST['password']){ $password = escape($_POST['password']); }

    if(isset($login) && isset($password)){ // LOGIN ATTEMPT

    // check for brute force attacks 
    $btime = $time-600; // 10 minutes
    $pull = $DB->query("SELECT * FROM logins WHERE user='$login' AND time>$btime");
    if($DB->num_rows($pull) > 5){ // more than 10 tries in the last 10 minutes


            $error = "Too many login attempts have been made with this login. ";
    // maybe lock the account for x hours

        }else{

        // AUTHENTICATE
        $sql = $DB->query("SELECT * FROM users WHERE user='$login' AND password='$password'");
        if($DB->n

um_rows($sql) == 1){  // AUTHENTICATED
    $user = $DB->fetch_array($sql);
    $ok = 1;    
            session_regenerate_id();
            $_SESSION['userid'] = $user['id'];
            $_SESSION['agent'] = md5($_SERVER['HTTP_USER_AGENT']);
            $_SESSION['idle'] = $time; 
            header("Location: welcome.php"); // REDIRECT TO USER AREA

    }else{  // NOT AUTHENTICATED
        $ok = 0;
        $error = "Wrong pass or login.";
    }
    // log all attempts (removed)
    }
    }

检查会话的功能:

function checksession(){
    global $DB, $time;

    if($_SESSION['userid'] > 0){

        $userid = intval($_SESSION['userid']);
        $user = $DB->fetch("SELECT * FROM users WHERE id=$userid");
        $idle = $time-$_SESSION['idle'];

        if(!$user){ header("Location: index.php"); }
    elseif($_SESSION['agent'] != md5($_SERVER['HTTP_USER_AGENT'])){ session_destroy(); header("Location: ".$site."index.php"); } // check user agent
    elseif($idle > 7200){ session_destroy(); header("Location: ".$site."index.php"); } // destroy session if no activity for 2 hours
    else{ 
        $_SESSION['idle'] = $time;
    }
    }else{ header("Location: ".$site."index.php"); // user id not set
    }
    return $userid;
}

退出功能

function logout(){
session_destroy();
header("Location: index.php");
}

它工作正常,但并不完美。

的问题:

  • 当我做session_regenerate_id();会话ID更改,但旧的ID也保持活动状态。所以这很没用。我在安全级别更改时执行此操作。我也考虑过定期做。我在php 5.3.6中使用MAMP。

  • 如果用户不想破坏会话并只是关闭浏览器,则会话文件似乎永远留在系统中。我想知道如何在X小时后使会话死亡,即使用户处于活动状态。 2)如果用户空闲,会话会死(有点像我现在的系统,但是来自系统方面)。

  • 我注意到,如果我在登录之前修改了会话cookie,那么除了带有用户信息的新重新生成的id之外,会在会话文件文件夹(空)中保存。不确定这个,只是觉得很奇怪。

  • 我是否正确销毁了会话?

该网站应具有相当高的安全级别,因为真实资金将涉及用户帐户。我正在考虑在会话中保存页面点击次数,当它发生变化时,意味着其他人已经完成了会话。会议将被杀死。

1 个答案:

答案 0 :(得分:1)

session_regenerate_id():会话ID实际上只是大型随机数。 PHP实现其会话ID非常随机,以防止人们简单地猜测或增加有效的会话ID。尽管如此,如果攻击者获得有效的会话ID,他们可以“劫持”您的会话。更改有效会话的会话ID实际上无法解决此问题。您需要添加另一层安全性,可能是通过将客户端的IP地址与会话ID相关联。这样,您几乎可以发布会话ID(不推荐),但是攻击者无法利用它,因为他们无法使用欺骗性IP地址完成TCP连接。

如果用户不想破坏会话并只是关闭浏览器,则会话文件似乎永远留在系统中。 会话cookie将保留在客户端计算机上,直到他的浏览器认为它已过期。我认为默认时间是24分钟。会话文件将保留在服务器上,直到被PHP的会话垃圾收集器收集。

我想知道如何1)在X小时后使会话死亡,即使用户处于活动状态。这可以通过PHP的配置参数来控制:session.gc-maxlifetime。请注意,您还需要更改其他session.gc选项以强制清除。 See this also

如果用户空闲,这也适用。

编辑:我读错了。这不适用于活动用户。对于活跃用户,您必须手动跟踪他们登录的时间并“注销”。

我注意到如果我在登录之前修改了会话cookie,那么除了使用用户信息的新重新生成的ID 之外,会在会话文件文件夹(空)中保存该文件我是不知道这意味着什么。也许你可以详细说明。

我是否正确销毁了会话? 并不是的。在删除服务器端cookie之前,您还需要尝试强制客户端删除其会话cookie。这是here

作为最后一点,我不确定检查客户端的USER_AGENT是个好主意,特别是因为它很容易欺骗。您应该考虑检查完整(非散列)IP地址,因为它需要3次握手。 (请注意,除非您通过SSL进行通信,否则仍然容易受到MITM攻击)