More secured getURLContent method. Add PHPUnit on getURLContent
This commit is contained in:
parent
d750dc48a1
commit
80d13e711c
@ -147,7 +147,7 @@ if (GETPOST('target') == 'remote')
|
||||
$xmlarray = getURLContent($xmlremote);
|
||||
|
||||
// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '404')
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404')
|
||||
{
|
||||
$xmlfile = $xmlarray['content'];
|
||||
//print "xmlfilestart".$xmlfile."xmlfileend";
|
||||
|
||||
@ -431,7 +431,6 @@ print '<br>';
|
||||
print '<strong>';
|
||||
print $form->textwithpicto($langs->trans("CompressionOfResources"), $langs->trans("CompressionOfResourcesDesc"));
|
||||
print '</strong>: ';
|
||||
//$tmp=getURLContent(DOL_URL_ROOT.'/index.php','GET');var_dump($tmp);
|
||||
print '<br>';
|
||||
// on PHP
|
||||
print '<div id="httpcompphpok">'.img_picto('', 'tick.png').' '.$langs->trans("FilesOfTypeCompressed", 'php (.php)').'</div>';
|
||||
|
||||
@ -54,7 +54,7 @@ $version = '0.0';
|
||||
|
||||
if ($action == 'getlastversion')
|
||||
{
|
||||
$result = getURLContent('http://sourceforge.net/projects/dolibarr/rss');
|
||||
$result = getURLContent('https://sourceforge.net/projects/dolibarr/rss');
|
||||
//var_dump($result['content']);
|
||||
$sfurl = simplexml_load_string($result['content']);
|
||||
}
|
||||
|
||||
@ -1634,7 +1634,7 @@ class Setup extends DolibarrApi
|
||||
$xmlarray = getURLContent($xmlremote);
|
||||
|
||||
// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '404')
|
||||
if (!$xmlarray['curl_error_no'] && $xmlarray['http_code'] != '400' && $xmlarray['http_code'] != '404')
|
||||
{
|
||||
$xmlfile = $xmlarray['content'];
|
||||
//print "xmlfilestart".$xmlfile."endxmlfile";
|
||||
|
||||
@ -18,11 +18,13 @@
|
||||
|
||||
/**
|
||||
* \file htdocs/core/lib/geturl.lib.php
|
||||
* \brief This file contains functions dedicated to get URL.
|
||||
* \brief This file contains functions dedicated to get URLs.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to get a content from an URL (use proxy if proxy defined)
|
||||
* Function to get a content from an URL (use proxy if proxy defined).
|
||||
* Support Dolibarr setup for timeout and proxy.
|
||||
* Enhancement of CURL to add an anti SSRF protection.
|
||||
*
|
||||
* @param string $url URL to call.
|
||||
* @param string $postorget 'POST', 'GET', 'HEAD', 'PUT', 'PUTALREADYFORMATED', 'POSTALREADYFORMATED', 'DELETE'
|
||||
@ -125,6 +127,7 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation =
|
||||
$newUrl = $url;
|
||||
$maxRedirection = 5;
|
||||
$info = array();
|
||||
$response = '';
|
||||
|
||||
do
|
||||
{
|
||||
@ -132,8 +135,43 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation =
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $newUrl);
|
||||
|
||||
// TODO Test for $localurl on $newUrl
|
||||
// Parse $newUrl, check server address, then set parsed value with CURLOPT_CONNECT_TO
|
||||
// Parse $newUrl
|
||||
$newUrlArray = parse_url($newUrl);
|
||||
$hosttocheck = $newUrlArray['host'];
|
||||
$hosttocheck = str_replace(array('[', ']'), '', $hosttocheck); // Remove brackets of IPv6
|
||||
|
||||
if (in_array($hosttocheck, array('localhost', 'localhost.domain'))) {
|
||||
$iptocheck = '127.0.0.1';
|
||||
} else {
|
||||
// TODO Resolve $iptocheck to get an IP and set CURLOPT_CONNECT_TO to use this ip
|
||||
$iptocheck = $hosttocheck;
|
||||
}
|
||||
|
||||
if (!filter_var($iptocheck, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) { // This is not an IP
|
||||
$iptocheck = 0; //
|
||||
}
|
||||
|
||||
if ($iptocheck) {
|
||||
if ($localurl == 0) { // Only external url allowed (dangerous, may allow to get malware)
|
||||
if (!filter_var($iptocheck, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$info['http_code'] = 400;
|
||||
$info['content'] = 'Error bad hostname IP (private or reserved range). Must be an external URL.';
|
||||
break;
|
||||
}
|
||||
if (in_array($iptocheck, array('100.100.100.200'))) {
|
||||
$info['http_code'] = 400;
|
||||
$info['content'] = 'Error bad hostname IP (Used by Alibaba metadata). Must be an external URL.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($localurl == 1) { // Only local url allowed (dangerous, may allow to get metadata on server or make internal port scanning)
|
||||
if (filter_var($iptocheck, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
|
||||
$info['http_code'] = 400;
|
||||
$info['content'] = 'Error bad hostname. Must be a local URL.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Getting response from server
|
||||
$response = curl_exec($ch);
|
||||
|
||||
@ -297,9 +297,9 @@ if (!empty($_SESSION['dol_loginmesg']))
|
||||
if (!empty($conf->global->MAIN_EASTER_EGG_COMMITSTRIP)) {
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
if (substr($langs->defaultlang, 0, 2) == 'fr') {
|
||||
$resgetcommitstrip = getURLContent("http://www.commitstrip.com/fr/feed/");
|
||||
$resgetcommitstrip = getURLContent("https://www.commitstrip.com/fr/feed/");
|
||||
} else {
|
||||
$resgetcommitstrip = getURLContent("http://www.commitstrip.com/en/feed/");
|
||||
$resgetcommitstrip = getURLContent("https://www.commitstrip.com/en/feed/");
|
||||
}
|
||||
if ($resgetcommitstrip && $resgetcommitstrip['http_code'] == '200')
|
||||
{
|
||||
|
||||
@ -634,7 +634,7 @@ class MultiCurrency extends CommonObject
|
||||
|
||||
dol_syslog("Call url endpoint ".$urlendpoint);
|
||||
|
||||
// TODO Use getURLContent() function instead.
|
||||
// FIXME Use getURLContent() function instead.
|
||||
$ch = curl_init($urlendpoint);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
@ -395,7 +395,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
global $conf;
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
|
||||
$url = 'ftp://aaaa';
|
||||
$url = 'ftp://mydomain.com';
|
||||
$tmp = getURLContent($url);
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertGreaterThan(0, strpos($tmp['curl_error_msg'], 'not supported')); // Test error if return does not contains 'not supported'
|
||||
@ -408,9 +408,34 @@ class SecurityTest extends PHPUnit\Framework\TestCase
|
||||
$url = 'https://www.dolibarr.fr'; // This is a redirect 301 page
|
||||
$tmp = getURLContent($url); // We DO follow
|
||||
print __METHOD__." url=".$url."\n";
|
||||
//var_dump($tmp);
|
||||
$this->assertEquals(200, $tmp['http_code'], 'GET url 301 with following -> 200'); // Test error if return does not contains 'not supported'
|
||||
|
||||
$url = 'http://localhost';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that resolves to a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
|
||||
$url = 'http://127.0.0.1';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that is a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
|
||||
$url = 'https://169.254.0.1';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that is a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
|
||||
$url = 'http://[::1]';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that is a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
|
||||
/*$url = 'localtest.me';
|
||||
$tmp = getURLContent($url, 'GET', '', 0, array(), array('http', 'https'), 0); // Only external URL
|
||||
print __METHOD__." url=".$url."\n";
|
||||
$this->assertEquals(400, $tmp['http_code'], 'GET url to '.$url.' that resolves to a local URL'); // Test we receive an error because localtest.me is not an external URL
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user