22

我可能在这里完全是个菜鸟,但我仍然不确定 CSRF(跨站点请求伪造)攻击到底是什么。那么让我们看看三种情况......

1) 我有一个 POST 表单,用于编辑我网站上的数据。我希望这些数据只能由登录的用户编辑。

2)我有一个网站,既可供登录用户使用,也可供访客使用。该网站的某些部分仅供登录用户使用,但也有可供所有用户使用的 POST 表单 - 匿名而不是匿名(例如标准联系表单)。是否应该保护联系表免受 CSRF 攻击?

3) 我有一个站点,它根本没有身份验证系统(嗯,这可能是不现实的,所以可以说它有一个与其他站点分开的管理站点,并且管理部分得到了适当的保护)。该网站的主要部分仅供匿名用户使用。上面的 POST 表格是否需要保护?

在 1) 的情况下,答案显然是肯定的。但是在 2 和 3 的情况下,我不知道(2 和 3 之间的差异甚至显着吗?)。

4

1 回答 1

36

只要将针对网站的恶意 HTML 或 JavaScript 嵌入到另一个已成功执行的 HTML 页面(或电子邮件)中,就有CSRF的手段。

下面是一个示例,它被放置在另一个网页中,该网页在继续之前会无辜地询问您的姓名和年龄:

<form action="http://yoursite.com/transferfunds" method="post">
    Your name: <input type="text"><br>
    Your age: <input type="text"><br>
    <input type="submit">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="toaccount" value="12345678">
</form>

请注意,该操作指向您的网站,并且隐藏的输入包含所需的 POST 信息。此示例将尝试将 1000 的资金(以任何货币)转移到帐号 12345678。如果您需要在表单上登录并实际检查,那么上述内容当然只有在不知情的用户有最近登录您的网站,但尚未注销,或会话尚未过期。

为了防止这种情况发生,最好的办法是向表单添加一个基于请求的令牌并在服务器端对其进行验证。即生成一个长的、唯一的且无法猜测的随机字符串,您将其存储在会话中并作为<input type="hidden">表单元素嵌入。提交表单后,将提交的令牌值与会话中的值进行比较(并立即删除会话中的值)。要更进一步,请使用CAPTCHA

在您的特定情况下,我认为您实际上更担心XSS,这与 CSRF 相反,但反过来也可以成为 CSRF 的来源。XSS 的一个示例是,当用户在输入字段中输入以下内容时,该输入字段迟早会在同一网站上重新显示:

<form name="delete" action="admin/deleteusers" method="post"></form>
<script>document.form.delete.submit();</script>

每当您(作为管理员)查看带有(不可见!)表单和脚本的评论的页面时,它将成功执行。

防止 XSS 实际上很容易。在网页上显示它们之前,只需对任何用户控制的输入(即请求 URL、请求标头、请求参数和请求正文)进行HTML 转义。在 PHP 中,您可以使用htmlspecialchars()它,在 Java/JSP 中,您可以使用 JSTL fn:escapeXml()。这种方式下,将<被转换为任何输入的 HTML/JS 将按原样显示,因此无法执行。&lt;>&gt;

于 2010-03-08T01:19:29.910 回答