在 php 中防止 csrf
要求在GET和POST参数中进行身份验证,而不仅仅是cookie;
检查 HTTP 引用标头;
在维基百科上看到这篇文章,想知道我如何应用它们
还行。。。我正在使用Kohana PHP框架,并且我有确定引荐来源网址标头的工具,但是我究竟要检查引荐来源网址标头的什么?框架函数仅返回引荐来源网址
以及如何验证 GET 和 POST 参数?针对什么?存储的信息?预期类型?
要求在GET和POST参数中进行身份验证,而不仅仅是cookie;
检查 HTTP 引用标头;
在维基百科上看到这篇文章,想知道我如何应用它们
还行。。。我正在使用Kohana PHP框架,并且我有确定引荐来源网址标头的工具,但是我究竟要检查引荐来源网址标头的什么?框架函数仅返回引荐来源网址
以及如何验证 GET 和 POST 参数?针对什么?存储的信息?预期类型?
为了防止CSRF,您需要验证一次性令牌,POST'ed并与当前会话相关联。像下面这样. . .
在用户请求删除记录的页面上:
确认.php
<?php
session_start();
$token = isset($_SESSION['delete_customer_token']) ? $_SESSION['delete_customer_token'] : "";
if (!$token) {
// generate token and persist for later verification
// - in practice use openssl_random_pseudo_bytes() or similar instead of uniqid()
$token = md5(uniqid());
$_SESSION['delete_customer_token']= $token;
}
session_write_close();
?>
<html>
<body>
<form method="post" action="confirm_save.php">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
Do you really want to delete?
<input type="submit" value=" Yes " />
<input type="button" value=" No " onclick="history.go(-1);" />
</form>
</body>
</html>
然后,当涉及到实际删除记录时:
confirm_save.php
<?php
session_start();
// validate token
$token = isset($_SESSION['delete_customer_token']) ? $_SESSION['delete_customer_token'] : "";
if ($token && $_POST['token'] === $token) {
// delete the record
...
// remove token after successful delete
unset($_SESSION['delete_customer_token']);
} else {
// log potential CSRF attack.
}
session_write_close();
?>
令牌应该很难猜到,对于每个删除请求都是唯一的,仅通过 $_POST 接受,并在几分钟后过期(此示例中未显示过期)。
通过推荐检查,您所做的一切都是为了确保推荐人来自您的网站/系统。如果引用站点不存在或来自外部站点,则引用检查将失败,您可能不希望遵守正在发出的任何请求。
在过去,各种技术和浏览器(flash..等)允许伪造引用标头。这是需要考虑的事情。有几种方法使用javascript链接到引用数据不存在/传递在请求标头中的资源。
此行为在浏览器之间略有不同。如果你使用javascript来提交一个表单,你通常没问题。如果您使用类似 window.location 之类的内容,则很可能不应期望存在引用数据。
CSRF预防的一种流行方法是不使用cookie,并且总是在引用之间传递状态...在整个应用程序的所有链接中传递会话令牌。