【问题标题】:PHP and AJAX security questionPHP 和 AJAX 安全问题
【发布时间】:2011-03-22 16:34:24
【问题描述】:

我目前正在构建一个 Web 应用程序,其中使用 jQuery 的 $.ajax 函数将 PHP 文件加载到主文件中。但是,PHP 文件显然仍然可以在应用程序之外访问,只需在地址栏中输入文件名即可。

所以我的问题是最好的方法是什么,以便被“ajaxed”的PHP文件知道它包含在正确的页面中并且可以正常运行,但是如果以任何其他方式访问它(即使有人要在我的 PHP 文件中创建自己的网站和 AJAX),那么文件应该显示“访问被拒绝”或其他内容。

提前致谢

【问题讨论】:

    标签: php ajax security


    【解决方案1】:

    只需在应用中设置会话并检查会话是否已设置

    session_start();
    if(!isset($_SESSION['gebruikersnaam'])) {
      header('Location: path/to/app/home');
    }
    //Do stuff
    

    你也可以用这个:

    if(!$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
     header('Location: path/to/app/home');
    }
    

    但并非所有浏览器都支持 HTTP_X_REQUESTED_WITH

    为了获得额外的安全性,您可以检查 ajax 调用是否来自您的应用

      if(@isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER']=="http://yourdomain/path/to/ajax/file") {
       header('Location: path/to/app/home');
    }
    

    【讨论】:

      【解决方案2】:

      谷歌搜索后得出结论!

      第 1 步:为所有 Web 服务生成令牌系统:

      生成令牌:

      <?php
        session_start();
        $token = md5(rand(1000,9999)); //you can use any encryption
        $_SESSION['token'] = $token; //store it as session variable
      ?>
      

      第 2 步:在发送 ajax 调用时使用它:

      var form_data = {
        data: $("#data").val(), //your data being sent with ajax
        token:'<?php echo $token; ?>', //used token here.
        is_ajax: 1
      };
      
      $.ajax({
        type: "POST",
        url: 'yourajax_url_here',
        data: form_data,
        success: function(response)
        {
          //do further
        }
      });
      

      第 3 步:现在,让我们来保护 ajax 处理程序 PHP 文件,

      session_start(); //most of people forget this while copy pasting code ;)
      if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
        //Request identified as ajax request
      
        if(@isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER']=="http://yourdomain/ajaxurl")
        {
         //HTTP_REFERER verification
          if($_POST['token'] == $_SESSION['token']) {
            //do your ajax task
            //don't forget to use sql injection prevention here.
          }
          else {
            header('Location: http://yourdomain.com');
          }
        }
        else {
          header('Location: http://yourdomain.com');
        }
      }
      else {
        header('Location: http://yourdomain.com');
      }
      

      注意:对于嵌套的 IF..ELSE 感到抱歉,但它增加了可理解性。 如果 ELSE,您可以将所有三者合二为一。 85% 的安全性增强!

      【讨论】:

      • $token = md5(rand(1000,9999));行使我的本地 PHP 20 秒重新加载页面。
      • 这将如何防止有人通过控制台发送呼叫?会有相同的 HTTP_REFERER 吗?
      • 在这种情况下,令牌是无用的,因为用户可以读取 JS 脚本(步骤 2)。
      • @zeuf:服务器在页面加载时“每次(每个请求)”都会生成令牌。所以没关系。
      • @HardikThaker @zeuf 如果您担心 javascript 中的令牌 - 您可以在服务器端使用盐。例如:$randomNumber = rand(1000, 9999); $browserToken = hash("sha256", $randomNumber); $saltValue = "abc123456"; $serverToken = $browserToken . $saltValue; $serverToken = hash("sha256", $serverToken); $_SESSION["token"] = $serverToken; 然后在验证时您只需重新创建 serverToken 并验证它是否匹配。
      【解决方案3】:

      安全连接 ajax 和 php 需要某种方式。 你可以使用

      if(@isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER']=="http://yourdomain/ajaxurl")
      {
       //Request identified as ajax request
      }
      

      不要忘记保护 php 文件,因为 cURL 可以欺骗标题。

      【讨论】:

        【解决方案4】:

        在另一个域上运行的 JavaScript 无法访问您域上的任何页面,因为这违反了 Same-Origin Policy。攻击者需要利用 XSS 漏洞才能实现这一目标。简而言之,您无需担心这种特定的攻击,只需担心影响每个 Web 应用程序的旧攻击即可。

        【讨论】:

          【解决方案5】:

          如果您担心其他人可能会在未经您同意的情况下访问您的内容,您也可以阻止盗链

          见: http://www.htmlbasix.com/disablehotlinking.shtml

          【讨论】:

            【解决方案6】:

            这并不简单,而且可能根本没有办法做到这一点。您可以在您的 php 文件中要求一些 POST 变量并将它们发送到您的 AJAX 请求中。这将保护您免受将 URL 粘贴到浏览器中的人的影响。

            没有人可以从其他域对您的网站进行 AJAX(安全问题),但始终可以连接并直接发送 http 请求,例如通过 cURL。

            您可以在 cookie 中创建一些令牌,这也可以从 jquery 请求中看到,但该解决方案也可能被黑客入侵。

            【讨论】:

              【解决方案7】:

              从类似的discussion 中引用Eran Galperin

              正如其他人所说,Ajax 请求可以 被模仿创造适当的 标题。如果你想拥有一个基本的 检查请求是否是 Ajax 请求您可以使用:

              if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
               //Request identified as ajax request
              }
              

              但是,您永远不应该将您的 这张支票的安全。它会 消除对页面的直接访问 如果这是你需要的。

              请同时考虑Jeremy Ruten 的回答:

              没有办法保证 他们通过 AJAX 访问它。 直接访问和 AJAX 访问 来自客户端,所以它可以很容易地 假的。

              你为什么要这样做?

              如果是因为 PHP 代码不是 非常安全,让PHP代码更加安全 安全的。 (例如,如果您的 AJAX 将用户 ID 传递给 PHP 文件, 在PHP文件中编写代码来制作 确保这是正确的用户 ID。)

              上面链接的讨论中有更多聪明的想法。

              【讨论】:

              • 那么究竟应该如何使用 XMLHttpRequest 访问此页面?你知道同源政策吗?
              • 我知道同源政策。可以检查 XMLHttpRequest 以查明脚本是否已通过 AJAX(即您自己的脚本)调用,或者是否有人将他的浏览器指向该位置。不过,从您自己网站的 Firbug 控制台调用脚本是另一回事。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-12-10
              • 1970-01-01
              • 1970-01-01
              • 2011-11-08
              • 1970-01-01
              相关资源
              最近更新 更多