jquery 为服务器提供安全的HTTP GET/POST请求

oyjwcjzk  于 12个月前  发布在  jQuery
关注(0)|答案(4)|浏览(115)

假设我使用某种API,我的文件server.php处理到API服务的连接。在我的客户端,我使用AJAX调用如下:

$http({
         url : 'server/server.php',
         method : 'GET',
         data : { getContent : true }
     });

字符串
在server.php中,我这样处理它:

if(isset($_GET['getContent'])){
    $content = get_content();
}

function get_content(){...}


我只是想知道是什么阻止了任何一个使用相同的getContent参数发送AJAX调用并获取我所有的数据?我如何才能确保它的安全,并确保只有来自我的应用程序的调用才能获取相关的数据?
谢谢你!

pb3skfrl

pb3skfrl1#

我猜你很担心CSRF攻击。在这里阅读更多信息:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
保护您的请求的最常用选项之一是:-生成令牌并将其与会话请求一起发送。此令牌可以由您的Web服务器识别为来自特定会话的特定客户端

hjqgdpho

hjqgdpho2#

2022更新

  • 这是一个7岁的职位和链接中的链接只有“接受”的答案被打破。*

所以,我将提供一个基本的演练和一个完整的模型。
记住,如果$_SESSION都来自同一个域,那么即使在AJAX处理程序中,$_SESSION也会被保留。

使用$_POST

  • 我假设你使用的是$_POST而不是$_GET,因为你担心安全性。如果不是,那么这可能并不重要。*
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $post_method = true;
}

字符串

确保$_SERVER['HTTP_REFERER']来自您自己的站点

if ( (!empty($_SERVER['HTTP_REFERER']))
&&   ($_SERVER['HTTP_REFERER'] === "https://example.tld/my_sending_page.php") ) {
  $from_my_server = true;
}


如果你不确定这应该是什么,在你自己的服务器上运行一个测试,看看这应该是什么:

echo $_SERVER['HTTP_REFERER'];

使用token

这是最难的部分,但不是太难。
1.创建令牌
1.在$_SESSION中设置令牌
1.将令牌放在AJAX头中

  1. AJAX responder:使用$_SESSION令牌确认AJAX头令牌

send_from_me.PHP

// Create the token
//$token = md5(rand(10000,99999));  // Not recommended, but possible
$token = bin2hex(random_bytes(64));

// Store in SESSION
$_SESSION["token"] = $token;
// Assuming your AJAX is this
const AJAX = new XMLHttpRequest();

...
AJAX.open(...);

// This goes inside your AJAX function somewhere after AJAX.open and before AJAX.send
//
AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");
//
// That creates $_SERVER['HTTP_AJAX_TOKEN'] which we can use later

...
AJAX.send(...);

的字符串

apache_responder.php

session_start(); // Must have

if ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"]) {
  $token_match = true;
} else {
  echo "No script kiddies!";
  exit();
}

// Now it's safe for your AJAX responder to proceed

让我们把所有这些放到一个工作示例中

sending_from.php

<?php

session_start();

$token = bin2hex(random_bytes(64));
$_SESSION["token"] = $token;

?>

<!DOCTYPE html>
<html>
  <head>
    <title>My AJAX Sender</title>
  </head>
  <body>

    <script>
      function ajaxFormData(formID, postTo, ajaxUpdate) {

        // Bind a new event listener every time the <form> is changed:
        const FORM = document.getElementById(formID); // <form> by ID
        const FD = new FormData(FORM); // Bind to-send data to form element
        const AJAX = new XMLHttpRequest(); // AJAX handler

        // This runs when AJAX responds
        AJAX.addEventListener( "load", function(event) {
          document.getElementById(ajaxUpdate).innerHTML = event.target.responseText;
        } );

        // This runs if AJAX fails
        AJAX.addEventListener( "error", function(event) {
          document.getElementById(ajaxUpdate).innerHTML =  'Oops! Something went wrong.';
        } );

        // Open the POST connection
        AJAX.open("POST", postTo);

        // Add your token header
        AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");

        // Data sent is from the form
        AJAX.send(FD);

      }
    </script>

    <div id="ajax_changes">Replace me with AJAX</div>

      <form id="ajaxForm">
        <input type="text" name="the_simple_response">
        <button type="button" onclick="ajaxFormData('ajaxForm', 'ajax_responder.php', 'ajax_changes');">Send my Secure AJAX</button>
      </form>

  </body>
</html>

ajaxcheck.inc.php

<?php

// $mysite = 'https://example.tld'; // manually set host
$mysite = $_SERVER['SERVER_NAME']; // automatically retrieve host

// All in one test
if (($_SERVER['REQUEST_METHOD'] == 'POST')
&& ((!empty($_SERVER['HTTP_REFERER'])) && ($_SERVER['HTTP_REFERER'] === "$mysite/my_sending_page.php"))
&& ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"])) {
  
  $ajax_legit = true;
  
} else {
  
  echo "No script kiddies!";
  exit();
  
}

?>

apache_responder.php

<?php

session_start();

// Do all that checking we're learning about by neatly including the file above
require_once('ajaxcheck.inc.php');

// Process your AJAX
echo $_POST['the_simple_response'];

?>

68bkxrlz

68bkxrlz3#

我只是想知道是什么阻止任何一个发送AJAX调用相同的getContent参数,并获得我的所有数据?
没有。这个URL是公开的,因此任何人都可以向它发出请求。
我怎样才能保护它,并确保只有从我的应用程序调用将获得相关的数据回来?
您可以传递在服务器端验证的其他数据(例如,一些散列值)。

$http({
     url : 'server/server.php',
     method : 'GET',
     data : { getContent : true, hash : '0800fc577294c34e0b28ad2839435945' }
 });

字符串

if(isset($_GET['getContent']))
{
    if(isset($_GET['hash']) && validateHash($_GET['hash']))
    {
        $content = get_content();
    }
}

function get_content(){...}

toe95027

toe950274#

我只是想知道是什么阻止任何一个发送AJAX调用相同的getContent参数,并获得我的所有数据?
就像你在任何其他请求中保护数据一样(例如,使用用户身份验证)。就服务器而言,Ajax在HTTP方面没有什么特别之处。
我怎样才能保护它,并确保只有从我的应用程序调用将获得相关的数据回来?
你不能。用户总是可以检查他们的浏览器向服务器请求什么并复制它。
通常,人们对用户而不是应用程序进行身份验证。

相关问题