PHP libcurl example

In one of the sections on my “One Year of PHP at Yahoo!” talk I’m giving next week, I mention the security implications of the allow_url_fopen config setting.

I recommend that people set allow_url_fopen off, and instead use the libcurl extension to do server-side HTTP fetches.

Here’s a comparison of a simple HTTP fetch using both techniques.

allow_url_fopen = On

<?php

$str = file_get_contents("http://www.example.com/");

if ($str !== false) {

// do something with the content

$str = preg_replace("/apples/", "oranges", $str);

// avoid Cross-Site Scripting attacks

$str = strip_tags($str);

echo $str;

}

?>

allow_url_fopen = Off

<?php

$ch = curl_init("http://www.example.com/");

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$str = curl_exec($ch);

if ($str !== false) {

// do something with the content

$str = preg_replace("/apples/", "oranges", $str);

// avoid Cross-Site Scripting attacks

$str = strip_tags($str);

echo $str;

}

curl_close($ch);

?>

It’s not that much additional work to use the curl extension, and you shield all of your regular file I/O against the possibility of accidentally acting as an open proxy. You avoid having to scrutinize every usage of fopen(), readfile(), file_get_contents(), include(), require() and related functions for the possibility that they might be used with a URL.

6 thoughts on “PHP libcurl example

  1. Michael J. Radwin

    If your code is written carelessly, there are two major classes of problems that allow_url_fopen=On might open you up to:

    1. Cross-Site Scripting
    2. Open Proxy. At a minimum an annoyance when someone uses your bandwidth without your permission. Worse, your webserver could be used to proxy content that the remote browser shouldn’t have access to.

    On the other hand, if your code is written securely, it’s entirely possible that allow_url_fopen could be used safely. It’s just very difficult to guarantee that.

    If you’d like to learn more, you’ll have to come to Portland next week to hear my talk. 🙂

  2. Sterling Hughes

    I agree, cURL and the cURL extension are the mostest bestest, and should be used everywhere possible 🙂

    Btw…

    $ch = curl_init(‘file:///etc/passwd’);

    curl_exec($ch);

    Woopsy daisy! 😉

    (you can of course disable such behaviour in cURL at compile time, just make sure to do so…)

  3. nobody

    I don’t understand. How is Cross Site Scripting a security ramification of allow_url_fopen verus curl? In both examples, didn’t you have to call strip_tags? Should that not be in there in curl example?

  4. jr

    Ultimately, it’s possible to make anything insecure. The problem I have with allow_url_fopen is that it makes any file based operation potentially vunerable. If you’re very careful regarding any given operation (you strip tags, always initialize variables, filter any input, etc.) then there’s no problem at all.

    By turning off allow_url_fopen and using curl, you’re merely limiting the number of vulerable points from fourteen to one. Yes, it’s rewarding lazy programming. Yes, it’s better to always be paranoid when you code and trust yourself less than you trust unverified outside input. Humans, however, tend not to code like that.

    Hackers have endless time on their hands to fiddle, poke and prod. They will find flaws in your code. It’s just safer not to give them any more help.

Comments are closed.