如何不允许 PHP 中的 cURL 访问本地地址?

How to not allow cURL in PHP to access local addresses?

我已经设置了在线 php curl http header 检索器。

工作原理:用户转到 url https://www.example.com/header/,然后有一个输入字段,用户可以在其中输入域名。然后点击提交。然后 PHP 使用 curl 检索网站的 http headers。它检索那里输入的任何内容的 headers,仅当网站有效时,否则,它等待 5 秒,然后关闭连接。如果 url 无效,则不会执行 curl(PHP 使用正则表达式来获取)。

但是,如果用户在输入字段中输入任何本地地址,它会检索本地地址。如何阻止它从本地网络检索网站?我找不到关于此的任何问题。

它使用的 cURL 选项是:

curl_setopt($ch, CURLOPT_URL, $domain);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
//Is there any option I could use to not allow local network connection?

编辑

以防万一如果你有完整的代码会更容易:

<form action="" method="get">
<p><b><label for="domain">Domain/IP Address:</label></b> <input type="text" name="url" id="url" value="<?=htmlentities($_GET["url"], ENT_QUOTES);?>"> <input type="submit" class="btn home" value="Lookup"></p>
</form>
<?php
$domain = htmlentities($_GET["url"], ENT_QUOTES);

$ch = curl_init();

// set url
curl_setopt($ch, CURLOPT_URL, $domain);

//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//enable headers
curl_setopt($ch, CURLOPT_HEADER, 1);
//get only headers
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// $output contains the output string
$output = htmlentities(curl_exec($ch), ENT_QUOTES);
$curlinfo = curl_getinfo($ch);

// close curl resource to free up system resources
curl_close($ch);

if($domain) {
    if (!preg_match("~^(?:f|ht)tps?://~i", $domain)) { 
          
        // If not exist then add http 
        $domain = "http://" . $domain; 
    } 
    if (filter_var($domain, FILTER_VALIDATE_URL)) {
        $result = $output;
        echo "<div id='result'>";
        if (trim($result) != "") {
        echo "<pre style='background-color: #EEEEEE; overflow: auto;'><b>\n" . $result . "\n</b></pre>\n";
        echo "Took ". $curlinfo["total_time"]. "seconds.";
        } else {
            echo "<b>Couldn't fetch website. This might be because the website takes more than 5 seconds to load or because the website does not exist.</b>";
        }
        echo "</div>";
    } else {
        echo "Invalid Domain/IP!";
    }
}
?>

也许在 "building" 卷曲之前添加一个像 if ($_GET['url'] == "localhost") {//give an error} 这样的测试。

首先使用parse_url从完整的URL

中获取主机名
$host = parse_url( $domain, PHP_URL_HOST );

然后使用gethostbyname获取对应于给定互联网主机名的IPv4地址

$ip = gethostbyname( $host );

最后检查ip地址是否在private network ip ranges

里面
// split ip into its components

$ip = explode( '.', $ip );

// check for private addresses

$local_network = ( $ip[0] == 10 ) ||
                 ( $ip[0] == 192 && $ip[1] == 168 ) ||
                 ( $ip[0] == 172 && $ip[1] >= 16 && $ip[1] <= 31 );

if( $local_network )
{
    // manage access to local network...
}