几个月前,我的同事通过获取工作时间表创建了日历订阅。我相信他是通过cURL完成的。
现在我正在建立一个网站,以概述今天应该完成的任务。
我想检索时间表,以便我可以用它来显示在特定日期工作的人的姓名。
我在网上找到了一个教程,解释了如何在登录后获取数据。 我所做的是我复制了登录表单中输入字段的名称,以及名为 signin [_csrf_token]
的隐藏字段的名称使用这些名称,我创建了以下代码:
<?php
$username = "myusername";
$password = "mypassword";
$url = "http://planner.a-mac.nl/employeeSchedule";
$cookie= "koekje.txt";
$token = "2e4c16f2b664f3ed01827dd38dc11d22";
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/'.$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/'.$cookie);
curl_setopt($ch, CURLOPT_POSTFIELDS, "signin[username]=" . $username ."&signin[password]=" . $password . "&signin[_csrf_token]=" . $token);
//stuur de gegevens uit het formulier door naar de link
curl_exec($ch);
//Zet de output op het scherm
if (curl_errno($ch))
{
print curl_error($ch);
//Als er een fout is geef deze dan
}
else
{
curl_close($ch);
//Sluit de link met de website
}
?>
当我使用上面的代码加载我的页面时,我收到了包含错误消息的登录表单:
检测到CSRF攻击
有人可以帮我解决这个问题,以便我可以从网站上获得哪些数据?
我联系了我的老同事,但他说&#34;他不再知道&#34; ......
答案 0 :(得分:7)
CSRF令牌字段值不固定,但是为新创建的会话随机生成的值。你需要一个&#34;清洁&#34;首先调用网页以获取CSRF令牌值,然后才能将用户名/密码与CSRF令牌一起发布,如下所示:
<?php
$username = "myusername";
$password = "mypassword";
$url = "http://planner.a-mac.nl/employeeSchedule";
$cookie= "koekje.txt";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/'.$cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/'.$cookie);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) die(curl_error($ch));
$doc = new DOMDocument();
$doc->loadHTML($response);
$token = $doc->getElementById("signin__csrf_token")->attributes->getNamedItem("value")->value;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_POST, true);
$params = array(
'signin[username]' => $username,
'signin[password]' => $password,
'signin[_csrf_token]' => $token
);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_exec($ch);
if (curl_errno($ch)) print curl_error($ch);
curl_close($ch);
?>
答案 1 :(得分:1)
CSRF防御背后的想法是基于为每个页面加载生成一个唯一的标记,您必须通过该表单传递。
您必须使用表单加载页面,从页面中提取令牌并将其与POST请求一起传递。通常,在任何尝试之后,令牌都会失效,您必须再次请求表单以获取新令牌。
CSRF令牌存储在会话中,因此服务器可以查看表单上生成的令牌是否与发送表单的请求一致。
答案 2 :(得分:0)
我觉得你应该像这样添加令牌:
$headers[] = 'X-CSRF-Token:' . $token;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);