如何在PHP中有效地防止跨站点请求伪造(CSRF) [英] How to prevent Cross-site request forgery (CSRF) effectively in PHP

查看:395
本文介绍了如何在PHP中有效地防止跨站点请求伪造(CSRF)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试防止 CSRF / php class = post-tag title =以以下方式显示标记为'php' rel = tag> php 的问题:

I am trying to prevent CSRF in php in the following way:


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

  1. A $_SESSION['token'] is generated at the start of each page. I already know that using $_COOKIES is completely wrong since they are send automatically for each request.

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

In each <form>, the following input: <input type="hidden" name="t" value="<?php echo '$_SESSION['token']; ?>"> is appended.

$ _ SESSION ['token']; 已通过 $ _ POST ['t']

现在我有几个小问题:


  • 这很好吗预防CSRF的方法?如果没有,请解释。

  • 同时打开另一个设置相同的 $ _ SESSION 变量的页面时,上一个(仍处于打开状态)页面变得无效,如何防止这种情况?

  • 对于表单,此方法很明显,但是如何处理普通链接?

  • Is this a good way to prevent CSRF? If not please explain.
  • When another page is opened as well that sets the same $_SESSION variable, the previous (still open) page becomes invalid, how to prevent this?
  • For forms this method is clear, but how to handle normal links? Is it necessary to append the token to each link as well?

非常感谢。

推荐答案


这是防止CSRF的好方法吗?

Is this a good way to prevent CSRF?

是。这样做是强制客户端在对表单处理程序执行POST之前先对表单执行GET。这可防止CSRF在现代浏览器中出现 ,因为浏览器将阻止客户端Javascript向外部域发出XHR GET请求,因此第三者无法在其网站上模仿您的表单并成功获取有效的令牌

Yes. What this does is to force the client to do a GET on the form before it can do a POST to your form handler. This prevents CSRF in modern browsers since browsers will prevent client-side Javascript to do an XHR GET request to a foreign domain, so a 3rd party cannot imitate your form on their site and successfully get a valid token for the submission.


同时打开另一个设置了相同$ _SESSION变量的页面时,上一个(仍处于打开状态)页面将无效,如何防止这种情况?

When another page is opened as well that sets the same $_SESSION variable, the previous (still open) page becomes invalid, how to prevent this?

一次允许多个令牌有效,并在会话中保留一系列有效令牌。或者,根本不存储任何令牌,而使用令牌签名方案。我涉足并解释了此处。替代方案2:在整个会话中仅使用一个令牌,而不会使令牌无效。 (在注释中给@SilverlightFox戴上帽子)

Allow several tokens to be valid at a time, keeping an array of valid tokens in the session. Alternatively, store no tokens at all and use a token signing scheme instead. I've dabbled in and explained that here. Alternative 2: just use a single token for the whole session, without invalidating tokens. (tip o' the hat to @SilverlightFox in the comments)


对于表单,此方法很明显,但是如何处理普通链接?

For forms this method is clear, but how to handle normal links? Is it necessary to append the token to each link as well?

否。是否也需要将令牌附加到每个链接上?您只需要保护POST请求,因为大概只有POST请求才能更改敏感数据(眨眼眨动一下,您坚持使用REST约定,对吗?!),并且XHR GET请求已被浏览器阻止-一侧。

No. You only need to protect POST requests since presumably only POST requests can alter sensitive data (wink wink nudge nudge, you're sticking to REST conventions, right?!) and XHR GET requests are already blocked browser-side.

这篇关于如何在PHP中有效地防止跨站点请求伪造(CSRF)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆