令牌不匹配(CSRF)

时间:2015-04-30 11:29:44

标签: php csrf

我已输入以下代码以防止CSRF但发出和检查令牌。 顶部部分在login.php上,第二部分在登录页面上。令牌的发布有效,当我在他们匹配的登录页面上打印$ _SESSION ['令牌]时。但是,当我替换其他代码时,它表示他们不匹配并显示“已过期”。

<?php
session_start();
$_SESSION['token'] = $token;
$_SESSION['token'] = uniqid(md5(microtime()), true); 
print $_SESSION['token'];
?>

<html>
<head>
    <title>My first PHP website</title>
</head>
<body>
    <h2>Please login here to see your tour</h2>
    <form action= "checklogin.php" method="post">
        Enter Username: <input type="text" name="username" required="required"/> <br/>
        Enter Password: <input type="password" name="password" required="required" /> <br/>
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
    <input type="submit" value= "login" />

    </form>
</body>

<?php
session_start();

print $_SESSION['token'];
session_start(); 
if ($_POST['token'] !== $_SESSION['token']) { 
die('expired'); 
} 
?>

2 个答案:

答案 0 :(得分:1)

表单操作是login.php,因此当用户登录时,POST数据被提交到login.php页面。您的问题没有说明用户如何定向到他们的目标网页。

一种选择是尝试以下方法。

替换:

<form action="login.php" method="post">

使用:

<form action="landingpage.php" method="post">

通过这种方式,您可以在目标网页上获得

的价值
$_POST['token']

答案 1 :(得分:1)

根据我们在您的问题评论中的讨论,我发布了这个答案,以便汇总信息。

您的代码基本上是正确的,但您遇到的问题是因为在重定向到用户的唯一目标网页后,您再也无法访问原先在{1}}中的数据了$_POST,即在提交登录表单后。

因此,在checklogin.php脚本中,您可以选择其他选项:

  1. 在您重定向到的网址中加入令牌,然后针对checklogin.php检查$_SESSION['token']

  2. $_GET['token']中设置一个标志,表示已允许使用该系统。像$_SESSION(我推荐的那样)

  3. 注意:此处您面临的另一个问题是:您必须考虑将每个用户的访问权限限制在他们自己的页面上。想象一下,如果用户以某种方式知道另一个用户的主页的URL,他们可以轻松地编辑URL并到达它。我的建议是将用户的ID保存在$_SESSION['loggedIn'] = true;中,然后保存在每个用户主页的顶部,以检查当前登录的用户是否可以打开所述页面。 / p>

    我希望这更清楚!