如何不允许 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...
}
我已经设置了在线 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...
}