views:

52

answers:

4

I'm trying to write some code that various sites will embed, calling a script on my server. That script streams the binary data for an image and spits it into an image tag.

However, I'm trying to control who has access to that script. So if I hand out my embed code to, say, yourwebsite.com, I want to make sure the client requesting this script got it from "yourwebsite.com".

Any suggestions?

+4  A: 

Have you tried $_SERVER['HTTP_REFERER']?

This will work most of the time but please take the fllowing into account:

The REFERER is sent by the client's browser as part of the HTTP protocol, and is therefore unreliable indeed. It might not be there, it might be forged, you just can't trust it if it's for security reasons.

If you want to verify if a request is coming from your site, well you can't, but you can verify the user has been to your site and/or is authenticated. Cookies are sent in AJAX requests so you can rely on that.

via @Seldaek

Lizard
@Lizard: Don't use code blocks for quotes.
Josh K
fixed my answer..
Lizard
A: 

HTTP Referrers

See Determining Referrer in PHP.

You can use the $_SERVER variable as such:

 $ref = $_SERVER['HTTP_REFERER'];

More on HTTP Referrers.

Josh K
A: 

I'd rather use

$_SERVER['REMOTE_ADDR'];

instead of the easily spoofable REFERER. You might have to assign multiple IPs for a client, but that shouldn't be an issue.

If you don't want to use a Server Variable, simply hand out an API key and have them submit it on each request to your serving script.

Gordon
won't do any good in his case: as far as I understood, he want's to grant the access on the website that is using this image and not on who is watching this website.
jigfox
@Jens The OP said he was going to use Data URLs and ask the websites to embed code. So the request will come from the server, not the viewer. It will only come from the viewer, if he does something like `<img src="example.com/image.php"/>` which he cannot do when using [inline data URLs](http://www.websiteoptimization.com/speed/tweak/inline-images/).
Gordon
Okay, I think this is a matter of interpretation, I interpret is Question the other way.
jigfox
@Jens *That script streams the binary data for an image and spits it into an image tag* sounds pretty much like Data URIs to me - but I am not going to start a fight about it :)
Gordon
+1  A: 

easiest way is to check the referer $_SERVER['HTTP_REFERER']. But this can be falsified.

More secure is using some kind of authorization, i.e.

You give every client allowed to see this picture an unique secret key (or salt). Then your client must create a standardized time string like 20100701170821.

Then your client can do something like this:

<?php
  $public_identifier = "yourclient.com";
  $secret = "1234567890ABCDFGHIJKLMNOPQRSTUVWXYZ";
  $time_string = date("YmdHis");
  $signature = hash_hmac('sha256',$time_string,$secret)
  $url_to_access_the_images += "?time=$timestring&signature=$signature&client_id=$public_identifier"
?>

this will generate an URL like this:

yourdomain.com/secret_image.php?time=20100701170821&signature=e9de9112433944188b5da9fa7157bf167bfdd6af95120aea2674424838154ea9&client_id=yourclient.com

On your site you can do the checking like this:

<?php
  $secret = get_secret_for_client_id($_GET['client_id']);
  // check if the request time is within a tolerance of 15 minute
  // time difference between client server and your server
  // and check if he's authorized (signature is valid).
  if(abs(int($_GET['time']) - int(date("YmdHis"))) < 1500) &&
     $_GET['signature'] == hash_hmac('sha256',$_GET['time'],$secret)) {
    // do what ever you do to ouput the picture
  } else {
    // do what ever you do for unauthorized access.
  }
?>
jigfox