Petruza
Petruza

Reputation: 12276

Is prepending "http://" to a filename for PHP's fopen() safe enough to prevent reading local files?

I have a PHP script that accepts a file URL by GET and opens it with fopen.
Is this solution safe enough or is it a security breach?

$filename = $_GET['file'];
if( substr( $filename, 0, 7 ) !== 'http://' )
    $filename = 'http://'.$filename;

fopen( $filename, 'r' );
// etc...

This way you can't force a local path to the script to read from it.

Upvotes: 1

Views: 267

Answers (4)

aaz
aaz

Reputation: 5196

It's sort of fragile, as the security depends on the http handler being registered. What if in a future version of PHP it will be removed or optional?

Here's the problem. This actually works (after a warning):

stream_wrapper_unregister('http');
file_get_contents('http://../../../../../etc/passwd');

Upvotes: 1

Jesse Cohen
Jesse Cohen

Reputation: 4040

another safety measure / option is to use chroot() http://php.net/manual/en/function.chroot.php

Upvotes: 0

payne
payne

Reputation: 14177

That should work, but here are two more things to think about:

  • Giving access to other servers. If your server is behind a firewall, someone could use this to fetch data from another server behind your firewall (or hit a service, etc.) using HTTP, FTP, etc.

  • Recursive denial of service. Make sure that there's not a way for someone to give you the URL of the script itself to fetch in a way that makes a recursion loop.

Upvotes: 4

timh
timh

Reputation: 1590

Not exactly sure, but you might need to escape it also to be safe.

$filename=escapeshellarg ( $filename );

See: http://php.net/manual/en/function.escapeshellarg.php

Upvotes: 1

Related Questions