Automatically get URL of a site displaying my image? - php

I've been trying to get the URL (including GET parameters) of a site that is displaying my image. This is because I want to extract one parameter of the URL.
A friend told me that she knew someone that could achieve this, but I don't know if he was doing it with an image. Also I don't think I can do it with a link because when going to external sites it will appear a warning page saying that you're being redirected outside, so if I put a link to my page and someone clicks, I will get the referrer URL of redirection warning page. I can't assure if my friend was telling the truth about this, but it's very likely that it was true.
All I could get with the image was the IP and other things of the HTTP header, but the referrer part is empty and I thought that the referrer contained the full URL I'm talking about.
This is what I have tried.
First the img tag in the other site in BBCode:
[img]http://______.com/get_image.php?i=myimage[/img]
And in my site this script in PHP, although any language that does the work would be good for me:
<?php
// Get name of image to be displayed (non-sanitized here for simplicity)
$filename = $_GET["i"];
// Here I want to get the site where image is being viewed
if (!empty($_SERVER['HTTP_REFERER'])) {
$visitor_url = $_SERVER['HTTP_REFERER'];
} else {
$visitor_url = "none";
}
// And write the referrer to a file just to test if it works
$fp = fopen('referer.txt', 'w');
fwrite($fp, $visitor_url);
fclose($fp);
// Eventually display the image
header('Content-Type: image/png');
readfile($filename . '.png');
?>
So my questions are:
Is it possible to get full URL of a site that is displaying my image?
If not, is there any other method to get the full URL?
Thank you in advance.
Note: I don't have any permision in the other site where I'm posting the image, I'm just an user there. Please tell me if I'm missing something or I have to ask this in another way, I'm new to StackOverflow.

Try REMOTE_HOST instead of HTTP_REFERER:
// Here I want to get the site where image is being viewed
if (!empty($_SERVER['REMOTE_HOST'])) {
$visitor_url = $_SERVER['REMOTE_HOST'];
} else {
$visitor_url = "none";
}
The web server where you are serving the image will need to be configured properly. If using Apache, this is with HostNameLookups On.
See http://php.net/manual/en/reserved.variables.server.php

Normally browsers are sending full referer with all URL components including query parameters - $_GET params. If they don't then there is no other way to achieve that URL while passing throught an image content.
Sometimes sending referer may be blocked, for eg. in some batch URL processing using some crawler like program/script or on some proxies.
In PHP receiving referer is done by $_SERVER['HTTP_REFERER'] because it's normally just http header from request and it's the only $_SERVER array key with referer info.

You added the .htaccess tag so I think you're using the Apache web server. If you'd like to prevent the issue entirely, you can disable hotlinking entirely by going one layer lower. Instead of managing in PHP, you can configure the web server to not serve content to domains other than the one you are hosting.
Check out the guide for more details.

I fixed this problem by switching my site (where image is hosted) to HTTPS. The code in my question was doing its job correctly.
It looks that HTTP_REFERER was blank because of it coming from an HTTPS site and my site being HTTP it would always send it blank. I was aware that it could be a problem, but didn't make much sense for me because HTTP_REFERER was also blank when coming from another HTTP site (which I think it's not normal) so I thought the error was in another place.
Usually HTTP_REFERER is sent when it comes from and goes to:
from HTTP to HTTP
from HTTPS to HTTPS
from HTTP to HTTPS
But it's not sent when it comes from and goes to:
from HTTPS to HTTP
And in my case, I don't know why, it wasn't being sent from HTTP to HTTP which was confusing me.

Related

How have safe HTTP Request Method

when use GET Method for receive JSON data , we can acsses the result directly from web browser , for example i send a mydata value from ajax to a main.php file and it process and get answer show a result some thing like below :
<?php
if (isset($_GET["mydata"])) {
if ($_GET["mydata"]=="hello"){
echo "hello world";
}
}
?>
but when a user call it in browser directly like http:mysite.com/mydata.php?mydata=hello recive answer . i want dont allow users to get answer of http request directly , and just can show it from ajax result of main page is it possible ?
You're asking how to prevent an ajax-only request from being accessed directly by copy-pasting the URL into the web browser; that is, only allowing the URL to be accessible via ajax on the main web page.
Well, there are a few things you can try:
Check the Referrer for the URL of the main page with $_SERVER['HTTP_REFERER']
Set a header in Javascript using xhr.setRequestHeader() and then ensure it's value by checking for $_SERVER['HTTP_X_....'] in PHP
Like Jay Bhatt recommended, check for the X_REQUESTED_WITH header, but be aware this might not always be set (see: X-Requested-With header not set in jquery ajaxForm plugin)
However, in any of these situations you should be aware that anyone who knows what they are doing can easily set any HTTP header, variable, or even modify the referrer which is sent to the server. As such, there is no 100% guarantee that your resouce can be accessed only via AJAX on the main web page. There is no control built in the internet to verify where a request is coming from, so anyone can easily spoof or fake it.

(A|B) testing Google Analytics, remove utm_expid from URL

Im new to this and im trying to rewrite URL so that utm_expid is hidden so if my url is:
http://www.myweb.com/?utm_expid=67183125-2
how would i make it so when user visits
myweb.com
it does not show utm_expid in url
Is this possible using PHP/JS?
NOTE: i cant use RUBY or any other languages except PHP/JS/HTML
There is a way. Just redirect the page to base url once the utm_expid=67183125-2 is got. ie,
if($_GET['utm_expid']) { //header to redirect to myweb.com }
Its a tricky way. Hope you are permitted to use it.
Just start a session and store value in session variable. you can regain it even page is re directed.
ie
<?php
session_start();
if($_GET['utm_expid']) {
$_SESSION['variable_name']=$_GET['utm_expid']
//header to redirect to myweb.com
}
?>
Let me add this Javascript trick that is server agnostic.
if (location.search.indexOf('utm_expid') > -1) {
history.replaceState('page', 'Title', '/')
}
I recommend you to place it at the end of the body.
If you wanted a clean URL (as you do for branding and manual sharing purposes), I'd script it so that you load a full page iFrame which loads the gA test queried URL. That way the user see s the clean URL in the address bar and still see the experiment.
You could use PHP to set up your index page (or any server side, or even client side script).

Detect if an image is loaded in a page outside my domain

I would like to create a single URL that returns one image when loaded in a page within my domain, and another slightly modified image when loaded in a page outside my domain.
I am thinking along the lines of something like:
<?php
header('Content-type: image/jpg');
if (/**image is loaded within my domain**/)
{
readfile("image1.jpg");
}
else
{
readfile("image2.jpg");
}
?>
Is there something I can put in the if-statement to make it work? Possibly that works in all browsers?
Is there a way to do this without php?
You could use the referrer URL in the request and check to see if it is your domain. This is done using $_SERVER['HTTP_REFERER'].
However, the HTTP_REFERER URL can be easily modified by clients and can even sometimes not be set, so you need to be careful when using it.
I don't know, how you're going to get request for image not in your domain, but you may look at $_SERVER['HTTP_HOST']. Maybe, HTTP_REFERER is what you need. Anyway look here.

301 Permanent Redirect

a website has used a "301 permanent redirect" to my site is there a way i can set code that detects this and displays a page when my website is accessed through this?
Does anyone have any idea about this?
You can get only a referer. I think you will not be able to get the http status code on server which the client gets during last request.
So my answer is NO, you cannot get the 301 status code on your server.
But you can do a little of needed magic with referer variable.
e.g. in PHP you can read this:
$_SERVER['HTTP_REFERER'];
Not much you can do. If you were doing the 301, you could set the referrer to the querystring. But since you're not, you can only grab what the request has given you.
You can try using PHP's $_SERVER['HTTP_REFERER'] to track the source URL from where your visitor comes from. I think it's a bit dodgy though and might not yield the same result in all browsers. Even PHP's documentation says 'it cannot really be trusted'.
Why do you have to use .htaccess for the redirect? You could do something like this:
Site A's index.php:
header("Location: http://siteb.com/?ref=".urlencode('http://sitea.com');
Site B's index.php:
if(isset($_GET['ref']))
{
if($_GET['ref']=='http://sitea.com')
{
// Do something
}
}
Edit:
If you can't edit Site A's code or server settings, try using:
if($_SERVER['HTTP_REFERER']=='http://sitea.com')
{
// Do something
}

Do not allow hot-linking of images unless logged in

I just ran into something today that I am not sure how it is being done.
I know a few things:
The site is done in php
There is an image gallery, a url would be something like
http://www.example.com/girls/Cyn/sets/getImage/1170753147/7.jpg
I can see that url, as long as I am logged into the site. It does not appear to be referrer based, as I took the url, made a new window in a browser, and was able to load it while still logged in. In doing so, I had no referrer.
The second I log out, I am redirected to a please register/login page.
This is a heavy hit site.
How is this done? I can tell they are running apache on Cent. When I login, I am given a cookie, that has a hash of something, which I am sure they are using to lookup an id to make sure I am allowed to be logged in.
However, the above is a direct request for a resource that is just a jpg. There has to be some communication then with Apache, and their database to see the state of that request. How would merely loading a url, send off a cookie value to apache that could then pass it off to a database?
I am about to embark on a paid membership site, and will need to protect images in the same way. This was not http auth, this was form based login, and I am at a loss as to how this was done. Any ideas?
All requests go through the web server. If a site sets a cookie, then all your requests to that site will include the cookie contents until that cookie expires or is removed. It doesn't matter what you're requesting it only matters where you are requesting it from.
If you have firebug open up the 'Net' tab when you're on this site and check all the requests you have made. You'll see in the request headers a 'Cookie' line. This will be on every resource requested: the images, the stylesheets, everything.
If Apache is the web server then it could use mod_rewrite to direct your request or it could pass it to PHP or Perl or something else that can check the cookie and output the image if valid or redirect if not.
Here is a php example (image output taken from php.net):
if(valid_auth($_COOKIE['auth'])) {
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
exit;
} else {
header('Location: /login');
exit;
}
It's probably a web application that uses a session cookie for authentication and redirects if the session has not been authenticated.
Pretty much any web framework has plugins for this sort of thing. There might even be apache modules to do it, but I haven't seen one.
You must create a "getter" for the images. The images must be stored in a folder outside of the public accessible directories.
/public_html
/js
jquery.js
index.php
getimage.php
/private_images/
myimage.jpg
Note that private_images directory is not accessible when you: http://www.mysite.com/private_images
Now, to create the "getter" script.
/* This is getimage.php */
if(!isset($_SESSION['is_logged_in'])) {
header('Location: /login');
exit;
}
/*
Get the image_name from the URL
You will be using something like: http://mysite.com?image_name=flowers.jpg
This is the way to get the image.
*/
$path = "/var/www/html/private_images"
$name = $path.'/'.$_GET['image_name'];
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/jpg");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
exit;
If you missed the comment above, you can do this to retrieve the image:
http://mysite.com?image_name=flowers.jpg
However, the above is a direct request for a resource that is just a jpg. There has to be some communication then with Apache, and their database to see the state of that request. How would merely loading a url, send off a cookie value to apache that could then pass it off to a database?
Every single http request is sent to a web server. The web server will then decide how to handle the request, based on a set of rules. By default, Apache has a simple handler that just sends the requested file back to the user. There is however no reason why you couldn't configure Apache to handle all requests with a php-script. On a high traffic site, you would probably solve this differently, since it's a bit expensive to fire up php for each and every image to show, but in theory you could just make a mod_rewrite rule that pipes all requests matching a particular pattern (Such as ^girls/Cyn/sets/getImage/.*) to a php-script. This script would then read the actual file from somewhere outside the web root and print it out to the user.

Categories