如何在PHP中有效防止跨站点请求伪造(CSRF)

时间:2015-11-18 09:23:30

标签: php security session session-variables csrf

我试图通过以下方式阻止CSRF中的

  1. 在每页开头生成$_SESSION['token']。我已经知道使用$_COOKIES是完全错误的,因为它们是针对每个请求自动发送的。

  2. 在每个<form>中,添加了以下输入:<input type="hidden" name="t" value="<?php echo '$_SESSION['token']; ?>">

  3. $_SESSION['token'];已通过$_POST['t']

  4. 验证

    现在我有几个小问题:

    • 这是防止CSRF的好方法吗?如果没有请解释。
    • 当打开另一个页面设置相同的$_SESSION变量时,前一个(仍然打开的)页面变为无效,如何防止这种情况?
    • 对于表单这个方法很明确,但是如何处理普通链接?是否有必要将令牌附加到每个链接?

    非常感谢你。

2 个答案:

答案 0 :(得分:5)

  

这是防止CSRF的好方法吗?

是。这样做是为了强制客户端在表单上执行GET,然后才能对表单处理程序执行POST操作。这会阻止现代浏览器中的CSRF ,因为浏览器会阻止客户端Javascript对外域进行XHR GET请求,因此第三方无法在其网站上模仿您的表单并成功获取有效令牌提交。

  

当打开另一个页面设置相同的$ _SESSION变量时,前一个(仍然打开的)页面变为无效,如何防止这种情况?

允许多个令牌一次有效,在会话中保留一组有效令牌。或者,根本不存储令牌,而是使用令牌签名方案。我已经涉足并解释了here。备选方案2:在整个会话中使用单个令牌,而不会使令牌无效。 (在评论中提示o @SilverlightFox的帽子)

  

对于表单这个方法很明确,但是如何处理普通链接?是否有必要将令牌附加到每个链接?

没有。你只需保护POST请求,因为可能只有POST请求可以改变敏感数据(wink wink nudge nudge,你是否坚持REST约定,对吧?!)并且XHR GET请求已被阻止浏览器端。

答案 1 :(得分:0)

CSRF 攻击发生在黑客试图从经过身份验证的用户发送虚假请求时。通常这种攻击发生 在网上商店或银行。

防止php中的csrf攻击我们可以: 1 = 创建一个检查登录函数: 如果登录会话设置为 true Ok,如果不是 false 并返回登录页面。 2 = 创建一个随机的 makeToken 哈希函数:base64_encode(md5(microtime())) 并将其保存到会话中,并创建一个输入隐藏类型,带有令牌名称和名称为令牌函数的值。 3 = 创建一个 checkTocken 函数并检查它,如果它等于 makeToken 函数,然后使用 unset 函数取消设置会话,并创建一个新的。