2009-09-13 74 views
3

我有一个Web应用程序,它具有基本身份验证 - 用户名,密码,会话和内容。不过,我特别需要防止用户欺骗POST请求(即使是登录用户)。在我的应用程序中,我正在验证用户的会话,然后才接受POST数据(还要照顾XSS和其他东西)。在web应用程序中保护POST数据

像:

if(user session exists) 
{ 
    // handle the data POSTed 
} 

else { 
    // ... 
} 

我在数据库中存储会话标识。还有什么我应该注意防止虚假的POST请求,或者这是足够的吗?

回答

2

您可以尝试为每个帖子请求生成帖子密钥。显示发布请求有效且从页面上的表单执行的附加参数排序。

1

如果您正在用户的浏览器中使用Javascript构建有效的POST请求,那么可以避免确定的用户向您的服务器提交伪造POST邮件。该用户有一个有效的会话ID,可用于发出POST请求。他还可以访问代码有权访问的所有代码和所有其他数据以构建请求。

您不能依靠浏览器端代码来保护您的系统。安全性必须在服务器上执行。例如,对象的所有操作都应该进行身份验证和授权。

+0

+1表示“安全性必须在服务器上执行”。这不能说得太多。 – 2009-09-13 13:39:52

0

在我目前的应用程序中,我有一些代码被发送到浏览器,浏览器然后回发,并且不能修改它。我所做的就是向该值追加一个秘密字符串,获取该完整字符串的SHA1校验和,然后要求浏览器返回值和校验和。我很确定这也是.NET的视图状态。

0

如果用户会话很长,您仍然易受XSRF的影响。你也需要采取措施。

如果你是在.NET中,检查出AntiForgeryToken,

http://msdn.microsoft.com/en-us/library/dd492767.aspx

+0

反篡改令牌仅仅意味着该页面是从先前的GET发布的,这限制了基本的欺诈性POST。各种屏幕录像机都可以录制/播放这些页面。 – bryanbcook 2009-09-16 13:35:57

0

在接受用户输入,则需要在数据库中存储以前的事情要做,零级的事情是确保你通过mysql_real_escape_string($ MyPostData)函数运行数据。

另外,它对每个想要通过POST接受的变量/数据都有好处,可以根据其类型以及您打算如何使用它进行编程验证。

这些是确保用户没有“有趣”业务的两条主要规则:确保您使用有效变量并确保数据到达数据库得到验证并正确转义。

1

使用CAPTCHA图像。

该网站建立在REST上,它根据定义是从一个点向另一个点转移状态。有足够时间的人可以制作模拟活动会话的POST请求。

与所有安全请求一样,CAPTCHA在服务器端得到验证。

0

对于您的模型(尤其是如果您使用整数作为会话ID),攻击者可以很容易地代表其他用户提交请求。递减你自己的会话ID,并且你已经有其他人提供了这个会话ID存在)。 您需要具有与每个会话ID关联的唯一会话密钥/ guid,并将其存储在数据库和客户端中的Cookie中。每次您的客户端提交请求时,您都应该读取会话ID以及会话GUID,然后根据数据库值验证它们。 除此之外,您可能还需要考虑一些XSRF缓解策略。

3

我特别接受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使用加密哈希函数,而不是保留单独的代码。使用散列,您还可以投入其他内容,例如到期时间,以便表单必须在特定时间范围内提交。或者,您可以生成一次性交易密钥,您也可以使用它来确保无法两次提交相同的表单(用于停止重复发布)。

相关问题