Menu
Is this code safe?
[code]
<?php echo file_get_contents($_REQUEST[‘url’]); ?>
To the best of my knowledge file_get_contents acts as a 3rd party when requesting so there is no worries about security. Is this correct?
Is this code safe?This is 100% NOT safe. This allows anyone access to the content of every file php has access to just by typing the filename into the address bar of their browser. For example: ?uri=passwords.txt
<i>
</i><?php echo file_get_contents($_REQUEST['url']); ?>
To the best of my knowledge file_get_contents acts as a 3rd party when requesting so there is no worries about security. Is this correct?[/QUOTE]
[code=php]$url = "passwords.txt";
$parts = parse_url($url);
if (isset($parts["scheme"])) {
//good
} else {
//bad
}[/code]
[code=php]$allowed_urls = array('file_one', 'file_two', 'file_etc');
$default_file = 'default_file';
echo file_get_contents(in_array($_REQUEST['url'], $allowed_urls)?$_REQUEST['url']:$default_file);[/code]
I think he wants to allow only web accessible pages and not files on the server [/QUOTE]Whatever you do you need a default action if something is wrong. If you are just looking for an http path you could do this:
[code=php]echo file_get_contents(preg_match('@^http://@i', $_REQUEST['url'])?$_REQUEST['url']:$default_file);[/code]
[code=php]
$url = $_REQUEST['url'];
if(preg_match('/^https?:/i', $url))
{
if(readfile($url) === FALSE)
{
echo "<p class='error'>ERROR: Unable to read URL $url</p>n";
}
}
else
{
echo "<p class='error'>ERROR: '$url' is not a valid URI.</p>n";
}
[/code]
Isn't there some kind of taint mode in PHP that could be enabled?[/QUOTE]
Its a good thing I read this, as it never occurred to me that users could access any file that php can. What would be the best way to determine if the input is a url or a local file? Do you think this would be effective?
[code=php]$url = "passwords.txt";
$parts = parse_url($url);
if (isset($parts["scheme"])) {
//good
} else {
//bad
}[/code]
--Steve[/QUOTE]
<i>
</i><?php
function http_get($url)
{
$url_stuff = parse_url($url);
$port = isset($url_stuff['port']) ? $url_stuff['port'] : 80;
$fp = fsockopen($url_stuff['host'], $port);
$query = 'GET ' . $url_stuff['path'] . " HTTP/1.0n";
$query .= 'Host: ' . [color=blue]'www.yahoo.com'[/color];
$query .= "nn";
fwrite($fp, $query);
while ($tmp = fread($fp, 1024))
{
$buffer .= $tmp;
}
preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts);
return substr($buffer, - $parts[1]);
?>
[code=php]if(false !== (strpos(strtolower($url), 'localhost')))
{
# localhost
}
else
{
# not localhost
}[/code]
Well that would test the URL but my guess is there is something else wrong with your logic if you need to do this.[code=php]$url = "http://localhost/config.php";
if (is_url($url)) {
echo "Valid URL, it is a remote file.";
} else {
echo "Invalid URL! This is a local file!";
}
function is_url($url) {
$parts = parse_url($url);
if(@get_headers($url) && strtolower($parts["host"])!="localhost") {
return true;
} else {
return false;
}
}[/code]
It should be pretty much entirely accurate as to whether the url is a local file or a remote file.[code=php]echo file_get_contents($_REQUEST['url']);[/code]
In one word, yes. It doesn't prevent against a user typing in "config.php" or the like as the url and get that file relative from the working folder. You certainly can't assume the user will put in a URL. Plus, what if it was a valid url, but one of the folders or or the filename contained the string "localhost"? It would still be a perfectly valid URL, but would be rejected. You must pull out the hostname and check if [I]that[/I] is localhost, you can't just assume that any instance of "localhost" will be the hostname.Well personally I think it is an overly intricate answer to deal with a line of code that should never be run in the first place.
--Steve[/QUOTE]
<i>
</i><?
$url = "/var";
if(false !== (strpos(strtolower($url), 'localhost')))
{
echo "localhost";
}
else
{
echo "not localhost";
}
?>
echos "not localhost"[/QUOTE]Thats because /var is not localhost!
[code=php]preg_match('@^^(f|ht)tps?://(?!(localhost|(d{1,3}.){3}d{1,3})).+$@i' $url)) or die();[/code]
Ultimater, your problem is caused because of your methodology. Instead of creating a blacklist you should be creating a whitelist. Don't check what is not allowed, check for what is allowed.[/QUOTE]It would be impossible to create a whitelist for the entire internet. I think the application (or at least one) that ultimater is using it for is getting the source of any website with AJAX. Cerainly a whitelist couldn't be used.
[code=php]@get_headers($url)[/code]
If its true, its a valid url. If its false, it might be a file on your server or may be simply invalid. This should really be the only check necessary, and works the best, IMO. (Note, you must use the "@" to suppress errors when the url is invalid.)"Well I wouldn't want anyone accessing localhost on my server.I have admin files and other things there. It's not just a case of if someone can read the php code. Localhost should be a non public area full stop and I would always work toward maintaining that. Also The domain might have a much tighter open base directory in force than localhost.http://localhost/passwords.php " will not list your passwords (or whatever PHP content that's not echoed.) All you need to do is check the url with this:[/QUOTE]
I don't know if I quite get what you're saying...If you believe a section of your site is private (e.g. localhost) security on that area my be more relaxed because it is a non public area. Localhost runs on a different virtual host and my operated at a lower security level or with a less restictive base directory restriction. For example, on my server I can access the majority of files on the server from localhost, including all my domains whereas if the request is directed at one of the domains opening of files is resticted to the directories that belong to that domain. I'm not saying PHP itself behaves differently on localhost but it can be configure to act differently.
"http://mydomain.com/passwords.php " and "http://localhost/passwords.php " are not treated the same way?
--Steve[/QUOTE]
0.1.9 — BETA 6.17