Wednesday, March 30, 2011

How to create temporary urls to prevent hotlinking in php?

Im looking to build a simple upload site, that will generate temporary URLS to video files after a captcha has been entered. I need to protect the true location of the files, so they cannot be hotlinked directly. A time based url, that expires after x minutes seems like the best option, but Im not sure on the actual implementation.

Any tips?

From stackoverflow
  • Make your urls like this:

    http://myvid.com/video?id=1&timestamp=12341561234&hash=1203941h23jk479sdf87sdf

    Where timestamp is the unix timestamp and hash is an md5 hash, say, of the timestamp appended to a secret string on the server.

    Then, when you play that video, check if the timestamp field is valid (by using the hash), and then check to see how old the timestamp is.

    Yegor : But then it will still show the link to the actual file. On many sites, I see paths like: www.domain.com/g34g43g4f32f/filename.txt and this will only work for an hour, after which you will just get a 404 error.
    csjohnst : In the case of the example above, have the php script at http://myvid.com/video generate headers to download the file eg: header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"video.mov\"");
  • Yegor, they use Mod Rewrite. So when someone enters www.domain.com/video/1234567890/theLongHashCode you write in .htaccess that the url should be treated as video.php?timestamp=12341561234&hash=1203941h23jk479sdf87sdf

    This allows you prevent from showing the actual url.

    Some sources on mod rewrite: http://www.modrewrite.com/

    What you would need to put in .htaccess file, considering you have mod_rewrite module enabled on Apache:

    RewriteEngine On
    RewriteRule ^video/([0-9]+)/(.*)  video.php?timestamp=$1&hash=$2
    

    This only takes in 2 values: timestamp and hash. The video id is not sent. I would not even send the timestamp. For temporary url, I only generate a hash, store it in the database along with the timestamp. So when someone visits an url, I look up the hash from the database. If the hash exists, then I compare the timestamp from the database with the current time, and if it is within the time limit, then the url is considered valid, otherwise it is invalid and write to the page "This link has expired."

    So I would have the url look like: http://hsbsitez.com/video/thehashcodehere

    With the following .htaccess file to interpret that url.

    RewriteEngine On
    RewriteRule ^video/(.*)  video.php?hash=$1
    

    Where video.php is the file that checks if the hash exists in the database or not.

  • Use a FORM with method set as PUT

    Have you thought about using a form with PUT method? This is exactly one of the cases that PUT is designed for - not being able to revist the page with the same URL. Just create a simple form that has a few hidden fields and you can make a javascript link that submits it. This way you don't have to worry about users trying to revist the links or having the links in their history.

    Example:

    <form id="myform" method="put" action="viewimage.php">
    <input type="hidden" name="id" value="uniquevalue" />
    <input type="hidden" name="filename" value="foo.jpg" />
    
    <a href="javascript:myFunctionToInvokeSumit()">Image foo.jpg</a>
    </form>
    

    Superficially, no one will be able to revisit the image without having to do some HTTP magic beyond your typical user. However, to further verify that the image is only launched after a click, you can register the id in the session and timestamp it, then check against the timestamp when the image is viewed.

0 comments:

Post a Comment