【问题标题】:Ajax Security (i hope)Ajax 安全性(我希望)
【发布时间】:2011-07-17 09:46:36
【问题描述】:

我正在构建一个浏览器游戏,并且我使用大量的 ajax 而不是页面刷新。我正在使用 php 和 javascript。经过大量工作后,我注意到 ajax 并不完全安全。我担心的威胁是有人想在我的 SQL 服务器上查找某人的信息,他们只需要在与我的 ajax 调用关联的 .php 文件中键入正确的信息。我使用的是 GET 风格的 ajax 调用,这是一个坏主意。无论如何,经过大量研究,我采取了以下安全措施。我切换到 POST(这实际上并不安全,但它的威慑力很小)。我也有一个推荐的地方,它又可以被伪造,但又是另一种威慑。

我采取的最后措施是这个问题的重点,当我的网站加载时,我在会话中生成并保存了一个 80 字符的十六进制密钥,当我发送 ajax 调用时,我也在发送挑战

形式的键
challenge= <?php $_SESSION["challenge"]; ?>

现在,当 ajax php 文件读取此内容时,它会检查发送的质询是否与会话质询匹配。现在这本身不会做太多,因为您可以简单地打开萤火虫并轻松查看正在发送的挑战。所以我要做的是,一旦使用了该挑战,它就会在会话中生成一个新挑战。

所以我的问题是,从我站立的位置来看,这有多安全从另一个来源发送伪造的请求。是否有人看到此安全方法的任何漏洞或有任何其他想法或想法。

【问题讨论】:

    标签: php javascript jquery html ajax


    【解决方案1】:

    您对“安全”的定义含糊不清。您似乎对防止数据被拦截不太感兴趣,而对阻止人们向您的服务器提交自定义请求更感兴趣。这不是安全,这只是好的应用程序设计——你的程序不应该接受导致内部状态中断的请求。你绝对不能做任何事情来阻止人们提交他们想要的任何数据。解决方案是在服务器端验证他们提交的数据,而不是试图阻止他们在客户端提交数据,这总是会失败。

    我切换到 POST

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

    假设有人想在我的 SQL 服务器上查找某人的信息,他们只需将正确的信息键入到我的关联 .php 文件中

    您应该对所有请求进行身份验证,以确保他们能够访问他们正在查询的数据。 SSL 将帮助您安全地执行身份验证。

    当我的网站加载时,我在会话中生成并保存了一个 80 字符的十六进制密钥,当我发送 ajax 调用时,我也在发送挑战密钥

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

    【讨论】:

    • 也许你可以帮我澄清一下,我的数据怎么会被截获,如果他们有萤火虫,他们可以只看我的会话数据吗?我以为那是保存在服务器端的,无法查看。
    • 可以通过本地网络上的数据包嗅探来截取数据
    • 把东西放到本地网络上会不会很困难?
    • @tye 你是对的,会话数据存储在服务器端。问题是您将 80 个字符的密钥发送给客户端;他们是否可以读取存储在会话中的版本并不重要,您正在以纯文本形式向他们发送相同的内容。
    • 是的,我明白这一点,这就是我担心的原因,但现在我更改了它,以便一旦它在 ajax php 文件中使用,它就会将其更改为另一个随机数,这一切都在服务器端完成,无需将其发送回客户端。在再次发送ajax请求之前,它不会再次发送给客户端。这有意义吗?应该这样做吗?
    【解决方案2】:

    查看“meagar”的答案。

    我想提一下:

    通过在 Session 中传递一个标识符,您正在做 Session 已经在做的事情。通常有一个 cookie,其唯一标识符类似于您生成的那个,它本质上告诉您的应用程序该人是谁。一般而言,这就是 PHP 会话的工作方式。

    在这种情况下,您需要做的是检查给定请求 - POST GET - 特定用户(其唯一用户 ID 或类似的,是否存储在Session) 有权根据该特定请求添加/更改/删除/任何内容。

    因此,对于“搜索”请求,您只会返回用户 X 有权查看的结果。这样,您就不必担心他们发送的内容 - 如果用户无权执行某项操作,系统就会知道不让他们执行此操作。

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

    有人可以随意添加。

    【讨论】:

    • 这听起来和我想要的完全一样,你能告诉我如何使用这个唯一标识符对某人进行身份验证吗?
    • 如果您正在开发游戏,我假设您可能已经解决了用户和注册问题。除此之外,您正在寻找通常称为“ACL”的东西。本质上,用户(或用户组)被赋予了他们被允许做的事情的权限集(“可以添加小部件”、“可以编辑拥有小部件”、“不能删除小部件”等) .对于另一个问题来说,这是一个很好的话题——而且可能已经被问到/回答得很好。
    【解决方案3】:
    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(){}
    

    【讨论】:

    • 你试过了吗?用firebug检查页面,你会发现"&amp;challenge=之后的值永远不会改变,不管你改变了多少次$_SESSION['challenge']服务器端的值。您必须手动根据 AJAX 请求的结果更新值。它不会自动发生。这意味着您必须每次都将新密钥发送回以响应 AJAX 请求,这违背了密钥的用途。
    • 顺便说一句,您是否通过value 参数将SQL 查询传递给服务器?这是一个可怕的、可怕的、不可原谅的坏主意。任何人都可以编写他们想要的任何 SQL 查询,然后发送。这是这里的根本误解——解决方案不是“保护”向服务器发送 SQL 查询;解决方案是从不发送 SQL 查询。
    • 是的,这些是我计划做出的改变,哈哈。好的,感谢您提供有关该代码不会发送更新的会话变量这一事实的信息。所以你不认为我应该将 ajax 用于 sql 目的。我制作的这款游戏的整个基础是消除页面刷新的需要。它将成为 MMO 风格的 RTS。
    • 您应该使用 AJAX,但您也应该在服务器端构建 SQL 语句。例如:您不应在查询字符串中传递查询 SELECT * FROM UNITS WHERE ID = 3`,而应使用类似 mysite.com/units.php?id=3 的 URL。重点是防止人们更改您的查询以插入诸如DELETE 语句之类的内容。
    • 现在可以接受将 WHERE = (var) 语句的信息发送到 sql 查询,只要它们经过注入验证。对于我的任何 ajax 请求,我通常会发送一些信息以供查询,用户可以选择要匹配的数据,但要匹配的值。这是可以接受的正确吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    相关资源
    最近更新 更多