2

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

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

有哪些方法可以防止这种情况发生,同时仍然允许用户相互发送链接?

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

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;
    }
}

问题是,如果有人使用由其他人创建的链接,页面将作为他们加载。我没有使用 cookie,我记得过去有人告诉我 CGI perl cookie 处理很差。

4

3 回答 3

4

如果查询字符串包含您用于会话身份验证的所有信息,那么您就是设计的。您将需要找到某种方法将用户名或会话 ID,或者最好将两者都放入 cookie;否则,您将成为 SOL,因为您无法阻止用户发送的链接包含您的代码用来告诉它正在与哪个用户交谈的所有内容。

如果我是你,我会首先找出 CGI.pm 在 cookie 方面的表现是否像我被告知的那样糟糕,如果是这样,我会继续滚动我自己的 Cookie: headers。我能看到的唯一另一种选择是将应用程序中的所有链接都转换为 POST 请求,这既更糟糕,也太可怕了,无法考虑。

于 2012-10-02T04:10:35.143 回答
3

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

其次,您应该在一定量的不活动后使会话过期。

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

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

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

当您收到请求时,请检查您收到的请求是否与next_request_id您为该会话存储的请求相同。如果不是,请重新进行身份验证。

现在,这将干扰用户使用具有多个选项卡或使用重新加载/刷新的站点的能力,但在特定用例中,这对我来说是一个合适的解决方案。

但是,在一般情况下,您最好使用 cookie。

在普通 HTTP 上使用 cookie 时,会话仍然可以被劫持,但是,至少,您要防范这种特殊的失败。

于 2012-10-02T15:24:15.187 回答
3

在切换到 cookie 之前,我曾经非常像现在这样处理会话管理。现在,我使用CGI::Session,并且对它非常满意。

但是,如果您想在短期内更快地解决您的问题,您可以做的一件事是将每个会话的 IP 地址与会话 ID 一起存储。然后,如果传入的 IP 地址/会话 ID 对与您存储的不匹配,您可以重定向到您的登录页面。

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

于 2012-10-02T20:18:11.563 回答