Search code examples
phpgdhotlinking

PHP GD leech with watermark


I was wondering if someone can provide me with a tutorial or source code of a way to make it so if people are leeching my sites images and embedding them in their forums or sites it will show a watermark, but if they view it on my site their wont be a watermark?


Solution

  • First, a small detour into HTTP

    HTTP is, essentially, the core protocol of the Web - used to transfer hypertext (web pages), images and other media. From the beginning, HTTP was designed to be stateless - amongst other things, this means that it's not possible to find if a request for an image "belongs to" a page or another.

    There are basically two workarounds for this in HTTP, but neither is 100% reliable: cookies and the Referer header.

    With cookies, you could set a cookie when a user accesses your page, and then check that when serving the images. This may run into concurrency problems when entering the page for the first time.

    With Referer, the browser sends in he request for the image an URL from which the image is loaded. Unfortunately, the referer can be easily modified or removed by the user or by security software.

    What that means for you

    I suggest that you use the Referer field - although it's not 100% reliable, most people won't bother messing with it, and those who will bother, well, they would overcome any other protection.

    You'll need to serve your images through a script (e.g. PHP).

    http://example.com/img.php?id=12345 - pseudocode for the check, PHP for the watermark itself:

    check if the image with given ID exists, else throw a 404 and end
    check the referer - if it matches your site, just readfile() the relevant image and exit
    if we're here, referer is wrong - you'll need the watermark:
    // PHP code from now on
    $original = imagecreatefromjpeg($original_image_path);
    $watermark =  imagecreatefromjpeg($watermark_image_path);
    imagecopymerge ( $original, $watermark, 0,0,0,0, $watermark_width, $watermark_height, $opacity);
    header('Content-Type: image/jpeg');
    imagejpeg($original);
    exit;