Curl: Location redirect while open_basedir is set

If you need to follow redirects within your php code using Curl and the open_basedir is set you came into some trouble. If you disable this directive all your directories with a 777 permission are not safe (if one or more website on the same server has some security issues). If you don’t have additional protections you should NEVER disable the open_basedir directive (at least if you’re using 3rd party applications).

A simple link checker

If you need to check URLs and if you need a script that has to follow possible redirects, you  need to use Curl. The option CURLOPT_FOLLOWLOCATION will follow each redirect until the curl client has reached the target website. This option rocks if you need to check URLs. The following simple snippet will check an URL and returns the HTTP_CODE:

$ch = curl_init('http://www.domain.com');
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
$info = curl_getinfo($ch);
echo $info['http_code'];
curl_close($ch);

Running this code with the directive open_basedir is set you get this error:

Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in /home/user/public_html/script.php on line …

What if you can’t disable this nasty directive and you need this function? There are some alternative functions inside the PHP manual but according other comments on that place those are not perfect solutions.
How about executing this script inside the path used by this directive? The default pathes are on my machine (and many others) “/tmp” and “/usr/local/lib/php/”. Do you like to execute your scripts in these directories? If not you need add additional directories to your Apache configuration. Since I like DirectAdmin machines I post the code you need to add to your DA user account (Admin Level -> Custom HTTPD Configurations, you need to ask your hosting provider if you don’t have full access):
|?OPEN_BASEDIR_PATH=`HOME`/:/tmp:/usr/local/lib/php/:/home/superuser/domains/some-domain.com/some_dir/|
With this setting your websites user  has access to the directory “some_dir”, place your link checker script (link_check.php) there after you made this modifications:

$ch = curl_init($argv[1]);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$valid = array(200, 302, 301);
if (in_array($info['http_code'], $valid)) {
    echo 'ok';
}

(don’t forget to add the php tags to this code)
Now inside your web application you can call this script with this code:

$check = shell_exec('/usr/local/bin/php /home/superuser/domains/some-domain.com/some_dir/link_check.php http://domain.com &');
if ($check == 'ok') echo 'URL is valid!';

This code works only if safe_mode = off

Comments

  1. Hi Olaf,

    Note: I am not a PHP programmer, and I am trying to help out my brother that is a Realtor, that has an IDX real estate search for his website and a separate hosting provider.

    I just read your interesting post: Curl: Location redirect while open_basedir is set
    I am having that main problem with a host provider that will not do anything.
    Do you have any type of workaround for this problem when the hosting provider sets their server as follows for security issues?
    What this is, is a Real Estate IDX company that provides a script that can make the real estate searches appear to be hosted on the Realtor’s website.
    Is there another way of doing it so the pages could all look like they are coming from the Realtor’s website and not the IDX company.

    Note the IDX company allows you to point to a custom directory at the Realtor’s website. But, because the script is using the curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // required for many of the IDX pages This is when it hangs up.

    This is from the hosting provider when I told them about the problem.

    From Hosting Company

    I have investigated this issue at our end.

    This is not a issue at the server.

    The script cloakURL.php cannot get execute when Open_basedir has been enabled in the server.

    Openbase_dir cannot be disabled as this is a security feature in the server.

    You will have to contact the application developer to resolve this issue as this is a issue related with the code in file cloakURL.php.

    They don’t want to Open_basedir disable. Here is the message I get when trying to execute the script.
    Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in /home/hiswebsite/public_html/cloakURL.php on line 98

    EDIT: please post support requests to our forum.

  2. Hello Jim,

    I removed your code and pointed you to the forum.
    I’m sure I can help ;)
    Actually you need to ask your provider if he will help you as explained in this tutorial (he need to add some open_basedir directory where the script has to be executed).

    You say that you’re not a php programmer, I hope you’re able to edit the code? See you at the forum…

  3. Excellent tutorial. Saved to my del.icio.us bookmarks :)

  4. Works nicely on my shared hosting with open_basedir enabled! Luckily, my +open_basedir path includes my ‘home’ directory, so I placed the CURL script there and called it from my web-page as described in this article.

  5. Hello Alex, great that it works this way!

Because of all the spam attemps I've decided to close the comment form at this time. If you have have any questions or comments please post them by using Google+ or Twitter (the links to my profiles are located at the top of this page).