如何使用CGI Perl中的用户会话防止会话劫持?

时间:2012-10-02 01:43:16

标签: perl session cgi

我有一个由少数人使用的网络应用程序(仅限内部),并使用存储在用户记录下并放置在各种链接中的随机会话ID。

我遇到了一个问题,即用户互相发送链接,允许他们劫持发件人的会话。

在让用户互相发送链接的同时,有哪些方法可以防止这种情况发生?

编辑: 链接中的会话ID(也包含$ username)与User表中存储的内容进行比较。 & incorrectLogin只会打印一个错误,然后死掉;

if ($sid) {

    $sth = $dbh->prepare("SELECT * FROM tbl_User WHERE UserID = '$username'");
    $sth->execute();

    $ref         = $sth->fetchrow_hashref();
    $session_chk = $ref->{'usr_sessionID'};

    unless ($sid eq $session_chk) {

        &incorrectLogin;
    }
}

问题是,如果某人使用其他人创建的链接,该页面将按其加载。我没有使用cookies,我记得过去曾被告知CGI perl cookie处理非常差。

3 个答案:

答案 0 :(得分:4)

如果查询字符串包含您用于会话身份验证的所有信息,那么您就会受到设计的影响。您将需要找到一种方法将用户名或会话ID,或更优选两者都放入cookie中;否则,你将只是SOL,因为你无法阻止用户发送的链接包含你的代码用来告诉与之通话的用户的所有内容。

如果我是你,我首先会发现CGI.pm是否会像我被告知的那样做差事,如果是这样的话,我会继续滚动我自己的Cookie:标题。我能看到的唯一另一种选择是将应用程序中的所有链接转换为POST请求,这更加破碎,而且太可怕了。

答案 1 :(得分:3)

首先,查询字符串(或会话ID)不应包含用户ID。当您收到会话ID时,您会查看存储在服务器端的会话信息,以检索与该会话ID相关联的用户ID。

其次,您应该在一定程度的不活动后过期。

第三,您可以在服务器端会话中存储两个额外的项目,以帮助您在仍未使用Cookie的情况下解决此问题。解决方案并不完美,即仍然有机会劫持会话,但会使其变得更加困难。

在服务器端,存储用户登录的IP地址。如果您从其他IP收到对同一会话的后续请求,请再次请求凭据。请勿在查询字符串中包含IP地址。

此外,对于每个响应,生成next_request_id。将其存储在服务器端会话中,并将其发送回客户端。您返回的网页上的所有链接都必须包含此next_request_id

收到请求后,请检查您收到的next_request_id是否与您为该会话存储的{{1}}相同。如果没有,请重新进行身份验证。

现在,这会影响用户使用多个标签或使用重新加载/刷新的网站的能力,但在特定用例中,这对我来说是一个合适的解决方案。

但是,在一般情况下,你最好使用cookies。

使用cookies over plain HTTP时,会话仍然可能被劫持,但至少,您正在防范此特定失败。

答案 2 :(得分:3)

在切换到Cookie之前,我过去常常像现在这样处理会话管理。现在,我使用CGI::Session,对此非常满意。

,如果您希望在短期内稍微快速解决问题,您可以做的一件事就是存储每个会话的IP地址以及会话ID。然后,如果传入的IP地址/会话ID对与您存储的不匹配,则可以重定向到您的登录页面。

这种方法确实存在一些缺陷并且并不完美,但它确实关闭了目前的大安全漏洞。