1
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.