I'm making a WordPress plugin that obfuscates the real file URL and forces the download of one of this 3 types of URL:
- Local:
http://example.com/wp-content/custom/filename.zip
- Dropbox:
https://www.dropbox.com/s/DBOX-KEY/filename.zip?dl=1
- Google Drive:
https://docs.google.com/uc?export=download&id=GDOCS-KEY
The final URL that's provided to the user has a code which is checked against the database (http://example.com/private/?download_file=SITE-KEY
). If correct, there are other checks in place and at the end the file is served through the script below with a read_file
to the real URL:
$download_url = "LOCAL-GOOGLE-DROPBOX-URL";
@ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if ( ini_get( 'zlib.output_compression' ) ) ini_set( 'zlib.output_compression', 'Off' );
header( 'Content-Type: ' . $mime);
header( "Content-Disposition: attachment; filename=\"".$final_name."\";" );
header( "Content-Transfer-Encoding: binary" );
header( 'Accept-Ranges: bytes' );
header( "Cache-control: private" );
header( 'Pragma: private' );
header( "Expires: 1997年7月26日 05:00:00 GMT" );
flush();
readfile( $download_url );
I'm inspecting the headers and response and there's no trace of the real URL.
Doubts:
- Is this really a "secure" method?
- Can the real URL be sniffed by other means?
For completeness, here are the inspection results for a Google Drive file:
Request URL:http://example.com/private/?download_file=1310819c43 Request Method:GET Status Code:200 OK Request Headers Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Host:example.com User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1366.0
Safari/537.22 FirePHP/4Chrome X-FirePHP-Version:0.0.6
Query String Parameters pvdn_file:1310819c43 Response Headers Accept-Ranges:bytes Access-Control-Allow-Origin:http://example.com Cache-control:private Connection:Keep-Alive Content-Disposition:attachment; filename="Test File"; Content-Transfer-Encoding:binary Content-Type:image/png Date:2013年5月19日 17:50:00 GMT Expires:1997年7月26日 05:00:00 GMT Keep-Alive:timeout=5, max=100 Pragma:private Server:Apache Transfer-Encoding:chunked X-Pingback:http://example.com/xmlrpc.php X-Powered-By:PHP/5.3.6
1 Answer 1
The server is fetching the contents of the URL and then sending it to the user. Unless you accidentally output the URL, via an error or similar, there is no way the user could see it. The server is effectively sitting between them and the remote server.
If you can, it would probably be better to host the files locally otherwise you will be using twice the bandwidth and also have the risk that one of the remote servers might go down.
As long as the user can't specify the remote URL or edit the contents of it, it should be secure.