我特别接受POST
前验证用户的会话。如果你的意思是“会话”通常意味着:存储在识别用户的cookie中的持久令牌和相关联的会话数据,那么不,这还不够。即使POST请求被另一个(攻击者)站点激发,该cookie也会被浏览器自动发送。
您在这里寻找的关键字是跨站点请求伪造或XSRF,其中经过身份验证的用户可以由攻击者(通过脚本或其他方法)向您的站点发出GET或POST请求。这些请求通常不会与合法请求区分开来。 (有些人通过检查HTTP引用数据尝试这样做,但这是不可靠的。)
这些攻击不像服务器端(SQL,命令)或客户端(HTML,JavaScript)那样立即造成损害,注射,但它们比两者更普遍:不幸的是,很少有网络程序员都采用适当的对策。直到他们的网站被XSRF漏洞攻陷。
有多种方法可以抵御XSRF,但唯一真正有效的方法是在每个提交表单中包含第三方攻击者不会知道的秘密值。正如Eimantas所提到的,这通常被称为邮政钥匙。
有多种方式可以产生这样的秘密信息。一种简单的方法是为每个用户的帐户详细信息添加一个随机生成的代码,然后将其放在表单的隐藏字段中,并检查其在提交中的存在。例如在PHP中:
<form method="post" action="delete.php"><div>
<input type="hidden" name="key" value="<?php echo(htmlspecialchars($user['key'])); ?>"/>
<input type="submit" value="Delete" />
</div></form>
if ($_POST['key']!=$user['key'])
// error
攻击者不会知道该用户的密钥,因此无法创建包含该密钥的链接/表单。
您也可以在服务器密钥上对用户的ID使用加密哈希函数,而不是保留单独的代码。使用散列,您还可以投入其他内容,例如到期时间,以便表单必须在特定时间范围内提交。或者,您可以生成一次性交易密钥,您也可以使用它来确保无法两次提交相同的表单(用于停止重复发布)。
+1表示“安全性必须在服务器上执行”。这不能说得太多。 – 2009-09-13 13:39:52