Detecting Ajax in PHP and making sure request was from my own website

前端 未结 7 1287
臣服心动
臣服心动 2020-11-29 23:31

I use my PHP back-end to detect AJAX requests by checking for a value in $_SERVER[\'HTTP_X_REQUESTED_WITH\'].

This gives me a reliable detection, making

相关标签:
7条回答
  • 2020-11-30 00:09

    Regarding your last question: "Does it even matter, in these days?" This is a case by case question. If the ajax request is doing something that does not require security (e.g. loading latest stock quotes) then it really doesn't matter IMHO. If the request is loading information that should be secured (e.g. returning identifying information or doing something on the server) then you should treat it as such.

    I personally don't use the server variables to know when something is an ajax request. Instead I just add a query parameter to the ajax call (e.g. http://domain.com/?ajax=true). If I need to secure the ajax call then I would use the same methods as securing a regular page request (using both client and server). As Lucas Oman pointed out, anything on the client side can be faked. Bottom line don't trust any request even if you think it is coming from your site or database. Always follow the mantra "filter input - escape output".

    0 讨论(0)
  • 2020-11-30 00:11

    Check the $_SERVER['HTTP_REFERER']. This will work in many cases, but shouldn't be confused for a completely-secure solution.

    0 讨论(0)
  • You can check the HTTP_REFERRER, but not all browsers set it. The best way is to write a wrapper for your ajax calls on the JavaScript side which sends part of document.cookie back to the server--only your domain has access to the cookie. You can compare the cookie in the request headers with the cookie in the AJAX call in php.

    In response to, "does it even matter, these days"--YES, it does! Read this.

    0 讨论(0)
  • 2020-11-30 00:19

    Let you Controller

    • generate access token
    • store in session for later comparison

    In your View

    • declare the access token as JS variable
    • send the token with each request

    Back in your Controller

    • validate HTTP_X_REQUESTED_WITH
    • validate token

    Check these security guidelines from OpenAjax.
    Also, read the article on codinghorror.com Annie linked.

    0 讨论(0)
  • 2020-11-30 00:22

    Really, the most secure way to do this is to, as you suggested, use server-side sessions, as these cannot be crafted as cookies can.

    Granted, someone can still hijack a session ID, but if you also store the user's IP address in their session and check it on each request, you can weed out a lot of hijacks. Only someone on the same LAN or proxy could hijack it.

    Any other method mentioned--cookies, javascript, http referer--depends on client-side data, which is insecure and should always be suspected of being fake, forged, hijacked and maliciously constructed.

    0 讨论(0)
  • 2020-11-30 00:28

    Use POST session secured requests:

    Inside the Webpage (e.g. index.php) we need to store the sessionid

    <?php
    // Create Session
    $session = session_id();
    if(empty($session)) session_start();
    ?>
    <head>
    ...
    <script type="text/javascript">
      sid = '<?php echo session_id(); ?>';
    </script>
    <script type="text/javascript" src="ajaxrequest.js"></script>
    ...
    </head>
    

    The ajax requests (ajaxrequest.js)

    /* simple getAjax function 
     * @param $url       request url
     * @param $param     parameter (dont use ?)
     * @param callback  function on success
     */
    var spinnerid = '#spinner'; // Spinner as long ajax requests running
    $(document).ajaxStart(function() { $(spinnerid).show(); });
    $(document).ajaxStop(function() { $(spinnerid).hide(); });
    function getAjax( url, param, callback ) {
        var data = null;
        url += "?sid=" + sid + "&" + param;
        $.ajax({
            url: url,
            method: "POST", // uncomment to use GET, POST is secured by session
            cache: false,
            async: true,
            success : function(data){
          callback(data);
        },
    }
    
    getAjax( 'http://domain.com/', 'data=foo', function( data ) {
     // do stuf with data 
     var jsonobj = eval("(" + data + ")");
     var data = jsonobj[0][ 'data' ];
    });
    

    Responsible php side:

    if( isset( $_GET['sid'] ) ) $client_sid = $_GET['sid'];
    
    if( session_id() == null ) session_start();
    
    if( session_id() != $client_sid ) {
        // noID or wrongID, redirect to mainindex
        ignore_user_abort(true);
        header( "HTTP/1.1 403 Forbidden" );
        header("Connection: close", true);
        exit;
    } else {
    
        // get data
        if( isset( $_GET['data'] ) ) {
            $data = $_GET['data'];
        } else if( isset( $_POST['data'] ) ) {
            $data = $_POST['data'];
        } else {
            $data = null;
        }
    
        // do stuff with data
    
        // return data as json
        $resp[0]['data'] = $data; 
        print_r( json_encode( $resp ) );
    }
    
    0 讨论(0)
提交回复
热议问题