When an http header is sent by a browser because the url is included in another page is it any different than when it is called by browsing to that page. for example if I have myjavascript.php am I gonna be able to tell if its being viewed by someone browsing to it rather than it being included in a tag?
This comes up a lot when people want to know how they can detect image leeching.
The browser will usually send a "Referer" (sic) header for in-page requests which contain the URL of the page that containing the link.
This is accessible using the $_SERVER['HTTP_REFERER'] variable (note unusual spelling).
The idea is that you can check this variable and see if it refers to part of your site.
Note that this variable is not always accurate; a user may elect to protect their privacy by not sending a referer header (using some sort of dinky privacy tool) and they may even modify their browser to send whatever they want in this field. So it shouldn't be relied upon for authentication, unless you also take into account that even a legitimate user may have left it blank or put an arbitrary string in it.
Related
Lets say I have a URL, www.mysite.com/go that I want to redirect to www.anothersite.com/site.php?id=999
The trick is, I do not want anothersite.com to be able to see that the request came from mysite.com. It should look like the address www.anothersite.com/site.php?id=999 was typed into the addressbar manually by the user.
It is important to note, that this has nothing to do with Google Analytics, and there will never exist an anchor link to www.mysite.com/go anywhere. Instead, the user will manually input www.mysite.com/go in the address bar (which is easier to remembar than the long URL).
How is this achieved? The technology in question is PHP. I imagine that it can be achieved with the header() function, but google searches reveal that this only works with https, not http. Can I via PHP control what the client provides of referrel information when the redirect is performed? I guess that if I want it to look like the address was typed into the address bar, I would have to blank out the referrer information. Is it possible?
It's not possible by means of a HTTP Redirect. You don't have any control over the outgoing referrer header as the browser handles it entirely client-side.
Your only real option that you can directly control is to use HTTPS. Referrers with a value of a HTTPS page are not carried forward by browsers.
Example flow:
http://www.mysite.com/go (so any existing links don't have to change)
https://www.mysite.com/go
http://www.anothersite.com/site.php?id=999
There are 2 sites:
http://www.site1.com
http://www.site2.com
http://www.site1.com contains link to http://www.site2.com as
<a href="http://www.site2.com/">link<a/>
When user clicks on link from http://www.site1.com browser sends Referrer header to http://www.site2.com. Based on Referrer header http://www.site2.com makes some processes.
I wonder if I can fake/change (maybe with javascript, PHP, ...) Referrer header or not send it at all?
You normally should not be able change the Referer header yourself (maybe using only browser bugs, which, however, are likely to be fixed in a short time), however, you may wish to use or make a dereferrer site, which basically changes the referrer to it's URL. example: http://dereferer.org/start.asp.
I have an application which records users visits. None of these visits are directly accessed, 100% of these visits are referred from another site.
I am passing $_SERVER['HTTP_REFERER'] through to the database. Approximately 35% of the logged entrees pass a referer, the rest are blank.
Is there a reason for this?
There are a couple of number of reasons why HTTP_REFERER might be blank.
You have to understand it's an environment variable given by the browser. Meaning users can remove it or even change it, if they so intend to.
Users accessing the link from a bookmark, history or by typing the link manually do not have a referer.
IE has also been known to remove the referer in situations revolving around javascript. Such as window.open, window.location and even setting target="_blank" in anchors or meta refresh.
Clicking an embedded link in a chat application, PDF/Word/Excel document, will also not set a referer.
Using AJAX, file_get_contents, fopen and other similar functions in other languages will probably not set a referer request.
cURL, fsockopen, applications that have browser-like components might not set a referer.
There are probably more situations when this could happen, I'll update if I can think of anything that seems reasonable.
If a user visits your site directly, there is no referrer. It's also possible they have set it up so their browser never sends the referrer.
According to this answer, browsers do not necessarily send a referrer when doing a meta refresh.
Browsers sometimes will include the referer in the request. But it is not mandatory to do so (the referer is 100% voluntary). Indeed there are various privacy and security issues surrounding the referer (for example, if an HTTPS site refers you to an HTTP site, the browser should not include the referring site as the referer). So don't rely on it.
When linking from one document to another in Internet Explorer 4.0 and later, the Referer header will not be sent when the link is from an HTTPS page to a non-HTTPS page. The Referer header also will not be sent when the link is from a non-HTTP(S) protocol, such as file://, to another page. for more info go to this link
Direct access to your page (typing URL in address bar or from bookmarks, history, etc)
Browser settings (disabled referrer or empty)
if someone requests page content with file_get_contents() function...
It is common when you are stuck finding why it is missing:
- Sometime your referer is https and you are on http, it will be lost.
Otherwise:
- User accessing by inputing url directly.
- A user has bookmarked and come from bookmarks.
- Sometime user keep the url default for browser (similar like bookmark)
- Proxy surfying may remove referer.
- accessing website as bots (search engine)
It also depends on the Transport layer, I encountered an issue where my Consumer Application A was running on the HTTP layer while the Application from where I was sending the request was running on the HTTPS layer.
How can I hide $_SERVER['HTTP_REFERER'] when a user browses to another site via a link from my site?
You can't, you have no control over the headers that are sent to another site. Headers are sent from the browser, to the site being navigated. This means you cannot manipulate them in any way (short of a MITM attack).
You could redirect the user to the site via an intermediary proxy, but that proxy will become the new referrer. e.g.
Your Link -> Proxy -> End result
Not only should this generally not be done, but it is not possible, at least in the way you are describing. It is up to the client to decide what to send in the request headers to a different server, not you.
I should also point out that this has nothing to do with PHP. PHP makes this header variable accessible to you via $_SERVER['HTTP_REFERRER'], but the problem you are trying to solve is avoiding the client from sending the referrer URL to the next server.
A few options:
If your site utilizes HTTPS, then it won't be sent.
If you build a redirector script on your site and use the HTTP Refresh header, the browser will typically not send the referrer, and if it did, you would only be sending the URL of your redirector. For example:
http://www.yoursite.com/redir.php?url=http%3A%2F%2Fwww.google.com
<?php
if (isset($_GET['url'])) {
header("Refresh: 0; " . $_GET['url']);
}
?>
Now, you must be careful with this little script. Anyone could then use your site to make a redirect look like it was coming from you. Also, using this method, anyone can inject whatever headers they want to the client. This is just to give you an idea. Finally, using the refresh header for this goes against the grain of the standards and should not be done.
Finally, Google, Facebook, PayPal, etc. all have redirector scripts. They use some sort of encrypted hash on the URL to determine if they generated the redirect or not. If you don't specify that hash and just give the URL, then the user will be prompted before redirecting. Not friendly.
Look, the bottom line is, there isn't really a reason to do what you are doing. If you are trying to hide something in your URL, then you have bigger problems. Security through obscurity is bad, mmkay?
If you're working in a controlled (intranet say) environment you might benefit from fixing browser configs see eg. http://cafe.elharo.com/privacy/privacy-tip-3-block-referer-headers-in-firefox/ but this is far from ideal.
How can I detect the site the user came from before accessing mine in PHP?
You could check at the Referer HTTP Header :
echo $_SERVER['HTTP_REFERER'];
But note that the Referer is sent by the browser, which means :
It can be disabled (it's not mandatory, and is just an additionnal information that the browser can send)
It can be faked (i.e. anyone can send anything -- even some SQL injection, or XSS injection, for instance)
So, you can use the referer to provide an additional feature on your website, but you have to make sure that your website doesn't rely on it : your application must still work, even if the Referer is not present.
Try this:
$_SERVER['HTTP_REFERER']
For more information, please see HTTP referrer:
The referrer, or HTTP referrer—also
known by the common misspelling
referer that occurs as an HTTP header
field—identifies, from the point of
view of an internet webpage or
resource, the address of the webpage
(commonly the URL, the more generic
URI or the i18n updated IRI) of the
resource that links to it. By checking
the referrer, the new page can see
where the request came from.
echo $_SERVER['HTTP_REFERER'];
It's not entirely reliable and can be spoofed, but in general it will be populated with the URL that the user clicked to get to the script.
You need to look at the HTTP Referer Header:
$_SERVER['HTTP_REFERER']
See PHP Documentation for more HTTP Headers
As #Andrew Hare states in his answer, getting the value of the HTTP_REFERRER server value (which is a header that is sent as part of the HTTP request) will tell you the site that the browser was last on.
What should be noted, however, is that it is completely possible that this header/server variable will have no value, for a number of legitimate reasons, some being:
The user typed in the URL to the site in the same window
The user opened a bookmark in the same window
The user just opened the browser and did one of the things above
All of the above are really variations on the same thing, a case where the same browser window is used for going to another site, but wasn't prompted through clicking the on a link in a document which lead them there, a redirect, or some other action prompted by the page in the history before yours.
The above notes are correct, but keep in mind that the user can make his/her browser not send this information, or they can mess with this information and send false data.