Curl: Location redirect while open_basedir is set


f 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

 

There are two ways to disable open_basedir restriction in php.

Site wide
*******
Open your php.ini and look for the open_basedir line and comment it.

Save your php.ini changes and restart your web server

By specific site
***********
This configuration works only on apache web servers.

Open your apache web server’s configuration file (httpd.conf) and at the bottom type this line.

php_admin_value open_basedir “none”

Save and restart your apache web server.

service httpd restart

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s