编辑现场更新脚本安全性

时间:2008-10-28 01:18:47

标签: php jquery ajax security edit-in-place

我正在使用 Edit in Place jquery插件,该插件需要将数据发布到将执行实际数据库更新的脚本。

此更新脚本的URL可以在html源代码和Firebug中轻松查看,因此我需要在处理更新之前添加某种身份验证检查。这当然是因此用户不能只传入他们想要的任何旧的用户ID /字段/值并且弄乱其他人的记录。

我最初也传递了他们的用户名和密码,但这并不理想,因为它在GET请求中,所以它都在URL中。该网站本身至少是SSL,但在任何情况下都不是最佳做法。

验证此类更新的最佳方法是什么?

FWIW,更新脚本是PHP格式,“就地编辑”插件是:jeditable

编辑:澄清一下:实际的数据有效负载是POST给脚本的,但是就地编辑插件没有明确的身份验证方法,因此我将身份验证作为URL的一部分传递给更新脚本,然后通过GET获取这些变量并使用它们进行检查。

编辑2:是的,我可以从更新脚本访问会话信息,所以我决定只提取以前保存的用户ID并在db update语句中使用它。这似乎是最安全的方法。

4 个答案:

答案 0 :(得分:3)

我认为你最好将脚本切换到POST方法,因为大多数编辑就地使用太大而无法实际使用GET。您永远不应该使用SessionId或密码作为URL参数,除了查看公共配置文件之外,我不会使用用户名。如果你的AJAX URL是一个PHP文件,我很确定它应该能够访问会话而无需在GET或POST数组中传递它。另外,请确保在更新数据库之前验证并清理所有信息。

答案 1 :(得分:2)

更新(根据评论和问题更新):您可以将用户名/密码作为submitdata选项传递给Jeditable,如下所示:

$(".edit_area")
    .editable("http://www.example.com/save.php", { 
         submitdata: { userid:'johnsmith',  passwd:'god' }
         // ..other settings, etc.
      });

快速和解决方案 - 脏,因为它以明文(通过查看源)公开用户的私有。

由于你可以访问服务器上的userid / sessionid,所以使用到目前为止的sanest选项。

嗯...既然你说Jeditable使用GET,我只能假设你使用的是loadurl选项(因为Jeditable使用$.post()来保存更改,并且{{ 1}} 总是使用POST)。

那么,您是否尝试将Jeditable的$.post()设置切换为“POST”,并像以前一样发送用户名/密码?

loadtype

这听起来像是快速而肮脏的解决方案 - 授予您在服务器端没有任何标准用户/会话处理。

答案 2 :(得分:2)

如果您只是在会话中查找用户,该网站是否仍然容易受到跨网站请求伪造的攻击?

如果您包含根据不可编辑POST字段的值计算的盐渍哈希字段,则可以发布所有需要的信息。如果包含时间戳,则也可以阻止脚本重放。

示例:

$(".edit_area")
  .editable("http://www.example.com/save.php", { 
    submitdata: { 
      userid: 'johnsmith',
      pageid: '123',  // or other value unique to the page
      timestamp: '1324354657',  // time when page loaded
      hash: '0bee89b07a248e27c83fc3d5951213c1' }
    // ..other settings, etc.
});

散列可以是例如MD5为'johnsmith$123$1324354657$' + $secret_salt。保存之前检查它是否匹配。如果时间太少或太多,可以选择拒绝。

ditch-pycrypto branch of django-magicforms将此实现为Django的可重用Form基类。它不直接适用于AJAX请求,但文档和单元测试应该为其他实现提供良好的基础。

答案 3 :(得分:-2)

要传递信息,您应该在实际的GET字符串中使用会话ID。这样,php脚本可以连接到会话,验证用户,并查看用户是否有权编辑他们发布的内容。然后,如果他们拥有权限,请继续,否则返回错误消息。

我相信你可以在javascript中获取会话ID,因此不需要公开传递。