I have setup an online php curl http header retriever.
How it works: a user goes to the url https://www.example.com/header/, then there is an input field where the user can enter a domain name. And click Submit. Then PHP uses curl to retrieve http headers of the website. It retrieves the headers of whatever is entered there, only if the website in valid, if not, it waits for 5 seconds, and closes the connection. If the url is not valid, curl is not performed (PHP uses regex to get that).
But, if the user enters any local address in the input field, it retrieves local address. How can I stop it from retrieving websites from local network? I can't find any question about this.
The cURL options it uses are:
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?
Just in case it is easier if you have the whole code:
<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!";
}
}
?>
First use parse_url
to get the host name from the full URL
$host = parse_url( $domain, PHP_URL_HOST );
Then use gethostbyname
to get the IPv4 address corresponding to the given Internet host name
$ip = gethostbyname( $host );
Finally check if the ip address falls inside 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...
}