用户刷新页面时,表单标记不匹配

时间:2011-04-05 00:05:07

标签: php session session-hijacking

我编写了以下三个函数,试图阻止会话劫持。他们工作。我在脚本的开头调用了set_auth_token。然后在html表单中我调用get_auth_token。表单发布后,我调用check_auth_token。但是,有时在用户填写表单后,如果填写不正确,他们往往会按F5 / Refresh。这会导致页面“死亡”。填写表单之前不会发生这种情况。

我可以做些什么来改善这些,以便每次用户按下刷新时它们都不会消亡?

function set_auth_token()
{
   if (!isset($_SESSION['auth_token']))
   {
      $_SESSION['auth_token'] = hash('sha256',rand().time().$_SERVER['HTTP_USER_AGENT'].$_SERVER['REQUEST_URI']);
   }
}

get_auth_token总是在调用set_auth_token后调用,因此如果找不到auth令牌就会死掉:

function get_auth_token()
{
   if (isset($_SESSION['auth_token']))
   {
      return $_SESSION['auth_token'];   
   }
   else
   {
      die('"No auth token."');
   }
}

导致页面死亡的函数:

function check_auth_token()
{
   if (array_key_exists('auth_token', $_SESSION) && array_key_exists('auth_token', $_POST))
   {
      if ($_SESSION['auth_token'] == $_POST['auth_token'])
      {
         $_SESSION['auth_token'] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REQUEST_URI']);
      }
      else
      {
         die('Woah! It seems like you pressed Refresh (or Back/Forward). Just click here to sort it out.'); # TODO: hyperlink silly
      }
   }
   else
   {
      die('no auth token');
   }
}

干杯。

1 个答案:

答案 0 :(得分:1)

我的猜测(基于你的评论)是当用户刷新时,他们再次发送他们的POST数据,但auth_token正在脚本的开头更新,因此$_POST中的值{1}}(在上一页生成)将不再等于新值(在脚本开头生成)。

您应该查看Post/Redirect/Get以停止重新发送过帐数据。

在验证现有密钥或使其无效之前,您还可以考虑不重新生成密钥。