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: 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
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 19, 2013 at 18:01
\$\endgroup\$

1 Answer 1

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.

answered May 21, 2013 at 12:32
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.