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: Mon, 26 Jul 1997 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:Sun, 19 May 2013 17:50:00 GMT Expires:Mon, 26 Jul 1997 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