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

Php 关于会议的几个问题/议题,php,session,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 = esc

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

  // 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");
}
它工作正常,但并不完美

问题:

  • 当我执行会话时,重新生成会话id();会话id会更改,但旧的会话id也会保持活动状态。所以这很没用。当安全级别更改时,我会这样做。我也考虑过定期这样做。我在PHP5.3.6中使用MAMP

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


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

  • 我是否正确地破坏了会话


该网站应该有一个相当高的安全水平,因为真正的钱将涉及到用户帐户。我也在考虑在会话中保存页面点击,当这种情况发生变化时,就意味着其他人已经接管了会话。会话将被终止。

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

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

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

如果用户空闲,这也适用

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


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

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


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

不使用会话\u REGENATE\u id():用户可以提交自己的会话。在其他问题上我明白了。我选择了用户代理而不是ip,因为ip可以更改。“我注意到,如果我在登录之前修改会话cookie,那么除了使用用户信息重新生成的新id之外,同一会话文件还会保存在会话文件文件夹(空)中”-我的意思是,如果我编辑PHPSESSION cookie,然后登录,具有用户提交名称的会话文件保存在会话文件文件夹中。但它是空的。用户将始终能够提交他们自己的会话,即使您重新生成。重新生成只会向他们发送一个新的会话id——如果他们真的是恶意的,他们将忽略它并继续使用任意会话id与您联系。您的工作是确保会话id与客户端的某个唯一标识符相匹配。我认为IP地址比用户代理好,但是IP地址会受到MITM攻击,除非您通过SSL。另外,在PHP中防止会话劫持是一个研究得相当充分的主题。我在发布这篇文章之前读过这两篇文章,还有很多其他文章。我已经做了家庭作业但还有一件事我不明白。当我重新生成id时,两个会话都保持活动状态。我很肯定,年长的人应该立即被解雇。