2011-03-17 202 views
8

我正在构建一个浏览器游戏,并使用大量的ajax代替页面刷新。我使用的是PHP和JavaScript。在做了很多工作之后,我注意到ajax并不完全安全。我担心的威胁是说某人想要查看我的SQL服务器上的某些信息,他们只需将正确的信息输入到与我的ajax调用相关联的.php文件中即可。我正在使用GET风格的ajax调用,这是一个坏主意。无论如何,经过大量的研究,我有以下安全措施。我切换到POST(这不是真的更安全,但它是一个小错误)。我也有一个提到的地方,它又是伪造的,但又是另一个威慑力量。Ajax安全(我希望)

最后的措施我已经到位,并且是这个问题的焦点,当我的网站被加载时,我有一个80个字符的十六进制密钥生成并保存在会话中,当我发送ajax调用时,我也发送在

challenge= <?php $_SESSION["challenge"]; ?> 

形式的挑战,现在关键当AJAX的PHP文件中读取这一点,检查是否发送的询问配衬会话的挑战。现在这本身不会做太多,因为你可以简单地打开萤火虫,看看发送的问题很容易。所以我所做的就是一旦使用了这个挑战,它会在会话中产生一个新的挑战。

所以我的问题是,从这个地方看,只有看到挑战关键字发送后什么时候才能看到什么,然后它会更新并且在发送之前再也看不到它,这使得它成为不可能从另一个来源发送伪造的请求。所以没有人看到任何这种安全方法的循环漏洞或有任何额外的想法或想法。

回答

1

查看'meagar'的回答。

我想提一提:

通过传递在会话的识别符,你在做什么的会议已经在做。通常会有一个cookie与您生成的唯一标识符类似,这个标识符告诉您的应用程序,实质上是该人是谁。一般来说,这就是PHP会话的工作方式。

在这种情况下,您需要做的是检查对于给定请求 - POST GET - 特定用户(其唯一用户ID或类似名称存储在会话中)具有权限添加/更改/删除/具有该特定请求的任何内容。

因此,对于“搜索”请求,您只会返回用户X有权查看的结果。这样,你不用担心他们发送了什么 - 如果用户没有权限做某件事,系统就知道不让他们这样做。

因此,“您应该验证所有请求”。

有人随意添加到此。

+0

这听起来就像我想要的那样,你能给我一些关于如何使用这个唯一标识符来验证他人的信息吗? – tye 2011-03-17 13:53:10

+0

如果您正在制作游戏,我会假设您可能已经制定了用户和注册。除此之外,你正在寻找通常被称为“ACL”的东西。从本质上讲,用户(或用户组)被赋予许可权限(“可以添加小部件”,“可以编辑*自己的小部件”,“不能删除小部件”等)。对另一个问题来说,这是一个很好的话题,而且这个问题可能已经被很好地提出来了。 – 2011-03-17 14:08:01

10

您对“安全”的定义很模糊。您似乎对阻止数据被拦截感兴趣较少,并且更感兴趣的是防止人们向您的服务器提交自定义请求。这不是安全性,这只是良好的应用程序设计 - 您的程序不应该接受导致内部状态中断的请求。绝对没有办法阻止人们提交他们想要的任何数据。解决方案是验证他们提交服务器端的数据,而不是试图阻止他们提交数据客户端,而这往往会失败。

我切换到POST

不应该去;这与安全无关。使用适合于请求的HTTP动词。你在查询信息吗?使用获取请求。你正在更新/插入/删除信息?使用帖子。

说有人想查询某人的信息,我的SQL服务器上他们刚刚需要正确的信息给关键相关的我的PHP文件

你应该认证的所有要求,以确保他们有权访问他们正在查询的数据。 SSL将帮助您安全地执行身份验证。

当我的网站加载我有产生80字符内六角扳手,并保存在会话中,当IM发送Ajax调用我也送关键挑战

这不会帮助。您的问题的整个前提似乎是用户安装了Firebug或类似的HTTP调试工具。如果他们这样做,你的会话密钥将变得毫无用处。

+0

也许你可以帮助我清理一些东西,我的数据如何被拦截,如果他们有萤火虫,他们可以看看我的会话数据?我认为这是保存在服务器端,无法查看。 – tye 2011-03-17 13:49:28

+0

数据可以通过本地网络上的数据包嗅探拦截 – 2011-03-17 14:02:37

+0

不会很难在本地网络上获取某些东西吗? – tye 2011-03-17 15:25:55

0
function mysqlRequest(type,server,name,value,sync){ 
    $.ajax({ 
      type: 'POST', 
     url: 'sql.php', 
     data: "server=s"+server+"&type="+type+"&name="+name+"&value="+value+"&challenge=<?php echo $_SESSION['challenge']; ?>", 
     cache: false, 
     dataType: 'json', 
     async: sync, 
     success: function(data){ 
      }, 
     complete: function(){} 
+0

你试过这个吗?使用萤火虫检查页面,无论您改变$ _SESSION ['challenge']'服务器端的值多少次,''&challenge ='都不会改变,根据AJAX请求的结果更新值,它不会自动发生,这意味着您必须每次发送新的密钥以响应AJAX请求,这会破坏密钥的用途 – meagar 2011-03-17 18:43:18

+0

另外,你是否通过'value'参数将SQL查询传递给服务器?这是一个糟糕的,糟糕的,不可原谅的坏主意。任何人都可以编写他们想要的任何SQL查询并发送它。这是根本的误解 - 解决方案不是' t来“安全”的SQL查询发送到服务器;解决方案是*永远不会*发送SQL查询 – meagar 2011-03-17 18:46:29

+0

是啊这些是我打算做的变化lol。和好的感谢您的信息关于该代码将不会发送更新的会话VA可变结构。所以你不认为我应该为sql目的使用ajax。我在做的这个游戏的整个基础是消除页面刷新的需要。它将采用MMO风格的RTS。 – tye 2011-03-17 18:50:25