3

I'm confused why these two things are, or appear to be, mutually exclusive, and wonder if there is a way around being able to use both on PHP-5.4. Trying to set this option, I get the following error:

curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set

I am using a MailChimp API library that requires CURLOPT_FOLLOWLOCATION to be set. Redirects can happen, and should be followed, and that is just the way the Internet works.

I am also using open_basedir on the domain. I want to ring-fence the directories that the site is able to access. It is just a security thing, and belt-and-braces along with other security measures.

So, is there any way to use both together? I want CURL to follow redirections, but also keep local file access of the PHP scripts to defined directories. The only approach I have seen that attacks this problem is one that emulates CURL following redirects, but that seems clumsy, then CURL is already designed to do that.

Edit:

In case it is not clear, this is the line throwing the error in the package I am using:

curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);

IMO PHP is being overly protective, and it should allow me to do this. So is there a way - without hacking/forking this package - to tell PHP, "look, I know what I am doing here"?

I have raised it as an issue with the package developers, but not got a response to date. If the package supported injection of the transport layer, then I could just work around it by using an alternative to PHP's curl functions.

hakre
  • 193,403
  • 52
  • 435
  • 836
Jason
  • 4,411
  • 7
  • 40
  • 53
  • 1
    Most threads I have found just say, "turn off open_basedir". Well, no I don't want to do that. That is one of the things we do to lessen the risk of damage spreading between domains if the worst happens and someone gets into the site back end. – Jason Oct 23 '13 at 11:16
  • Maybe the problem is that curl bypasses the open_basedir setting in PHP by operating in the curl library outside of PHP's control, and PHP is just trying to be helpful by stopping me making a mistake. However, I trust the URL where curl is being sent, so it should be my decision. Can I not tell PHP that the redirects can be trusted so "butt out" and let me do this? ;-) – Jason Oct 23 '13 at 11:27
  • This questions seems to say I am stuck having to hack the external package, which was something I wanted to try and avoid: http://stackoverflow.com/questions/3890631/php-curl-with-curlopt-followlocation-error Other blogs also provide example code to follow the redirects from outside of the curl call. – Jason Oct 30 '13 at 11:25

2 Answers2

4

I'm going to withdraw this question as it seems to be confusing people (edit: sorry, sounded condescending, which was not intended; I'm not explaining properly the problem, and the limitations imposed by both me and others on any suggested solution).

The answer appears to be, "no you can't do that". The CURLOPT_FOLLOWLOCATION option on PHP curl (curl_setopt) and the open_basedir option in php.ini are basically incompatible, and there is no programmatical way to make them work together.

I will fork the third-party package replace the CURLOPT_FOLLOWLOCATION option with a manual redirect workaround in code, for which there are a few examples on SO. I'll keep pushing for the package developers to fix this bug too.

Thanks for spending the time to respond.

Edit: the real problem here is the blunt-instrument solution imposed by PHP due to a bug raised a DECADE ago:

https://bugs.php.net/bug.php?id=30609

The problem is in the curl library - it should not be allowed to dive into the local filesystem if PHP tells it not to (except, perhaps, for the open_basedir directories). Since curl and PHP have not got together to sort this out in a full decade, then is is time to stop using curl - it is not fit for purpose. IMO.

Jason
  • 4,411
  • 7
  • 40
  • 53
  • Ok, but in this case can't you just change `open_basedir` at runtime and only when you're doing this cUrl call? – Borislav Sabev Nov 01 '13 at 06:17
  • 1
    If that is possible, then that would certainly do the trick. If you want to put that up as an answer, I'll revoke mine. – Jason Nov 01 '13 at 11:08
  • Answer edited. I was really sure I've mentioned this in one of my comments but that seems not to have been the case. Anyway, the most important thing is: Is the problem solved? – Borislav Sabev Nov 01 '13 at 15:24
  • I've been researching this and tried a variety of things and I also came to the same conclusion, you cannot have both for some reason that escapes logic. Really a shame, because `open_basedir` is actually a useful security measure. – Mahn Jun 20 '16 at 02:53
0

Curl is separate lib and should not be affected directly by PHP's open_basedir. How are you calling this? Can you provide some code and a more detailed explanation?

"the Curl target app has a restrictive open_basedir"

and

"the Curl source app has a restrictive open_basedir"

are two different things. PHP's open_basedir should affect incoming requests only.

Edit: After PHP 5.3.0 open_basedir can be changed runtime. It is listed in the manual. This is also explained in the general section, but the explanation is very, very vague:

Name:         Default:  Changeable:     Changelog:
open_basedir    NULL    PHP_INI_ALL     PHP_INI_SYSTEM in PHP < 5.3.0

If you have access to or power over the source just call it only where needed. Cheers!

Borislav Sabev
  • 4,776
  • 1
  • 24
  • 30
  • Given this, I can see the logic behind what PHP has done: if open_basedir is set, then the ability for an external site that curl is pointed at, to redirect to an internal path (using file://whatever) is disabled from within PHP. However, when I know and trust the site my PHP curl is requesting data from, then that "protection" gets in the way. Is there a way around it in PHP? I realise there are methods other than curl, but I'm pulling in an external library that just happens to use it and requires redirect support. – Jason Oct 30 '13 at 11:00
  • Yes, curl is a separate lib and is not affected by PHP's settings. However, PHP is raising errors if an attempt is made to pass certain options to curl, given certain PHP settings, most likely with the aim to keep me out of potential trouble. – Jason Oct 30 '13 at 11:12
  • @Jason can you explain again? I can't get your problem? Is it that when you call _appDestination_ that app tries to do an internal redirect? Then that redirect gets "black-holed" because of a `open_basedir` setting? If so, do you have control over the source of that app? – Borislav Sabev Oct 31 '13 at 13:48
  • In the original post I have pasted the line of code that generates the error and the error that it generates. I do not want it to generate the error when that line of code is executed. The line of code is in a third-party package that I don't want to change, and the server uses open_basedir which I also do not want to change. The answer may be simply, "tough - you will have to fork the third-party package". But there mat also be some way to tell PHP curl to behave differently so the error that I pasted is not generated when the line of code I pasted executes. – Jason Oct 31 '13 at 14:01
  • 1
    I have raised this also as an issue on the third-party package. They should either not require this curl option and work around it themselves, or use DI for the transport so it can be fixed outside of the package. This was a warning in PHP5.3 but seems to have turned into a fatal error in PHP5.4. Regardless, the redirect functionality is needed one way or another. – Jason Oct 31 '13 at 14:03
  • 1
    The documentation mentions that open_basedir can be *tightened* at run-time, i.e. made more restrictive, but not that it can be turned off, unless I am looking in the wrong place. I may just need to turn it off for this virtual host - at least it does not need to be turned off for the whole server. – Jason Nov 01 '13 at 19:24
  • @Jason you're right - it does say that. Let's see what the third party app says on this. – Borislav Sabev Nov 02 '13 at 07:02