简体   繁体   中英

php $_SERVER['HTTP_HOST'] is always same domain no matter from which domain i request

Right now for example i have this domains:

domain1.com domain2.com domain3.com domain4.com

I try to use cURL from domain1.com,domain2.com,domain3.com to domain4.com and block the cURL request.

Example code file on domain1.com:

try{
  $ch = curl_init();
  if (FALSE === $ch){
    throw new Exception('failed to initialize');
  }
  curl_setopt($ch, CURLOPT_URL,"http://domain4.com/test3.php?v=1.4");
  curl_setopt($ch, CURLOPT_POST, TRUE);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  $p_result = curl_exec($ch);
  var_dump($p_result);
  print_r($p_result);
  if (FALSE === $p_result) {
    throw new Exception(curl_error(), curl_errno());
    curl_close($ch);
  } else{
    curl_close($ch);
    return $p_result;
  }
}catch(Exception $e) {
  trigger_error(sprintf('Curl failed with error #%d: %s',$e->getCode(), $e->getMessage()),E_USER_ERROR);
}

Example code file on domain4.com:

  $domains = array("domain1.com"); //blacklisted

  $domainIsValid = array_filter($domains, function ($var) use ($_SERVER) {
        return strpos($var, $_SERVER['HTTP_HOST']) !== false;
    });

$_SERVER['HTTP_HOST'] // is always domain1.com even if i request from domain3.com

Do i missing something? is it Apache server configuration?

Host: DigitalOcean Ubuntu 16.04 with Apache server.

PHP documentation says: http://php.net/manual/en/reserved.variables.server.php

'HTTP_HOST'  Contents of the Host: header from the current request, if there is one.

Potentially you are sending the same headers from all domains.

I think REMOTE_ADDR or REMOTE_HOST would be more appropriate to use for blacklisting as HTTP headers can be easily spoofed.

EDIT: Note: Your web server must be configured to create REMOTE_HOST variable. For example in Apache you'll need HostnameLookups On inside httpd.conf for it to exist. See also gethostbyaddr().

I'v finally develop a answer to my self.

The answer is to send a cURL request to the update server with the real domain HTTP_HOST in referer, After In the update server generate a token:

     $token =  md5(uniqid($domain, true));//Create token
     $stmt4 = $dbh->prepare("INSERT INTO tokens (domain) VALUES (?)");//Store just to know from where the request for later use
     $stmt4->bindParam(1, $dm);
                                                // insert one row       
     $dm =  json_encode(array('domain'=>$domain,'token'=>$token),true);                    
     $stmt4->execute();

Then on request from domain create a file with that token that return,then check the token if found on the request domain its okay can continue update and delete the token.

    $exists = checkRemoteFile($domain.'/'.$token);
    if ($exists) {
        echo "found";   
    } else{
      /*  header("HTTP/1.1 401 Unauthorized");
        exit();*/
    }

function checkRemoteFile($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if(curl_exec($ch)!==FALSE)
    {
        return true;
    }
    else
    {
        return false;
    }
}

So basically there is 2 functions,

  1. Generate token with cURL request from the update server and update server return the token and create it as a file.
  2. Download from server side, but before check if the token is exist and valid on request cURL domain,Token can be used only 1 time - after used delete it immediately from database of server-side.

re-generate token the same for every request and delete the token after done request.

No one can fool you with this logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM