0

I am trying to make a site which has some media content, which I want to protect in various ways. I do know that you can never be 100%, but i like to be able to serve the images by imagejpeg, so i don't supply the viewer with the actual address of the media address as well as not being able to copy the address and see images this way.

The primary is to hide the actual media link address.

I output the image like this NEW_SIZE_IMAGE.PHP / NEW_SIZE_IMAGE_THUMB.PHP :

    // Content type
    header('Content-Type: image/jpeg');

    // Output
    imagejpeg($thumb);

This i can only do within an iframe due to the nature of the header. With an iframe i run into the problem of passing the dynamic variable to the page, since this is not POST. The images is loaded within seperates iframes on the page.

So that is my problem for the thumb pictures, and then i have a similar problem for the high res picture, which i run via tiny box.

I run the image navigation like this MAIN_SITE.PHP:

    <a onclick="TINY.box.show({url:'../image_holder_pop.php',width:800,height:600})">
    <iframe width="300" height="200" src="../new_size_image_thumb.php"></iframe>
    <br />
    <h2><br />HIGH RES LINK</h2></a>

IMAGE_HOLDER_POP.PHP

   <iframe width="800" height="600" src="../new_size_image.php"></iframe>

I need to pass a variable to the new_size_img.php / new_size_img_thumb.php files for this to work.

Edit: Picture of problem: picture of my problem - php image in tinybox

Niels
  • 635
  • 3
  • 9
  • 23

2 Answers2

1

You can obfuscate your IDs using a database that make the relation between a hash and your image id.

Instead of putting new_img.php?id=123, you'll do new_img.php?hash=0guww7g4ow, like on Youtube for example.

You'll need to add a column hash to your current image table (I assume you'll already have one if you're using ids), and you will need to create hash for each existing image.

To generate a hash of 10 chars in base 36 (10^36 combinations, I assume this is enough), I'm used to :

$hash = substr(str_shuffle(base_convert(str_shuffle(sha1(str_shuffle(md5(rand() . microtime())))), 16, 36)), 0, 10);

Then, create a reader.php taking the hash as GET argument, and make it do the relationship between the hash and the image. Finally, display it using imagejpeg (or even simpler, readfile).

Hope this helps.

Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
  • Hi Ninsuo. Thanks - Yes, i do find image relation for images by a table. I came into trouble when starting to using the iframe for to able to output the image... if i do a php/html page and using the imagejpeg i only get the image encoded data. That is maybe the start of all this trouble.. – Niels Mar 03 '13 at 08:39
  • Well, you probably missed `header("Content-type: image/jpeg");` just before `imagejpeg($handle);` if you're seing your image as plain text. – Alain Tiemblo Mar 03 '13 at 08:43
  • Hi Ninsuo.. I have added a picture to explain my problem in another way. – Niels Mar 03 '13 at 09:40
  • Why not using `` instead of an iframe? – Alain Tiemblo Mar 03 '13 at 12:08
  • Ok, now my brain hurts... Why would i not think about this from the start.. I actually think you solved most of my problems with just this.. – Niels Mar 03 '13 at 12:23
0

It is somewhat unclear exactly what you expect this variable that you would like to pass to PHP to do. I'm assuming that you simply want to indicate which image it is that you would like, or some sort of user identifier etc...

If you want to pass a variable like that to PHP, you can use the querystring of the request. (Which works for GET requests)

For example, you could create an <img> element with the following src: http://example.com/new_size_image.php?image=imagename&otherparam=1&otherparam2=2

Where imagename is an identifier for the image, and otherparam1 and 2 are optional arguments. You can access these variables in PHP like so:

$imagename = $_GET['image'];
$otherparam = $_GET['otherparam'];
$otherparam2 = $_GET['otherparam2'];

Which you can then use to figure out which image to serve to the client.

Next, I'm confused as to why you think you need iframes. They won't obfuscate anything or stop the user from copying the link. Much better to just use images -- you just need to set the right headers. For example, try this function which takes $filename as an argument which is a path to the image you want to load.

function outputImage( $filename ) {
    header('Content-Description: File Transfer');
    header("Content-type: image/jpeg");
    header('Content-Disposition: attachment; filename='.basename($filename ));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($filename ));
    ob_clean();
    flush();
    readfile($filename );
    exit;
}

(This is from a related question: URL to a random image)

A note on security: If you use the querystring to pass which image you'd like to the script (aka the ?image= from the first block) make sure you aren't passing the location of the file on disk, otherwise a sufficiently savvy user could formulate a request that would cause your script to send any file of their choosing. Instead, I recommend using some kind of an identifer such as ?image=123456.

This would allow you to use the url to this script as an <img> element, like so:

<img src="http://example.com/new_size_image.php?image=imagename&otherparam=1&otherparam2=2" width="300" height="200" />

EDIT

If you really don't want to use GET, you could potentially use jQuery with AJAX to load in the image. You could then create a POST request to the server which would return a base64 encoded image which would then be inserted in the page. This would mean that the <img> tag would not actually contain an image URL, but instead the raw base64 encoded data. Not super clean, but somewhat obfuscated.

For loading an image with jQuery and AJAX, check out this response: https://stackoverflow.com/a/12714338/747811

If you took this approach I would recommend storing the images as base64 encoded files rather than calculating their encoding each time you serve the image. To encode the images you could using something like this: http://www.freeformatter.com/base64-encoder.html

To encode them in PHP, use base64_encode(): http://php.net/manual/en/function.base64-encode.php

Community
  • 1
  • 1
Mike Blouin
  • 290
  • 4
  • 15
  • Hi Mike.. I try to never use GET as to not pass on to much information to the user about what is going on... IF i would use a GET variable.. a user could get images from the new_img.php?id=123 - by putting this into the url - That is excactly what i want to avoid. – Niels Mar 02 '13 at 21:42
  • If i put in your code and pass a image filename to it - it outputs nothing.. no fault .. same image as passed is allready on the page i want to try your code with.. – Niels Mar 02 '13 at 21:54
  • Try ensuring that your path to the image is correct and local, ie not a URL. You could potentially also try giving the full path to the image like `/var/www/img.jpg`. You may also need to change the `Content-type` header if the file is not a jpg (such as `image/png` for png). This code should work as it worked here: http://stackoverflow.com/questions/15151051/url-to-a-random-image/15151292#15151292 If it still doesn't work can you post a link to this script? For a method using POST, check my edit. – Mike Blouin Mar 02 '13 at 22:24
  • Hi Mike.. Within the same file i try to output either you way or the current way... the file path is the same. My current method outputs the image. Thanks for the tip about saving the image as code. That is offcourse the way to keep the serverload in reasonable levels. – Niels Mar 02 '13 at 22:36