How to access my domain only via a certain referer/website - javascript

How do i make my website accessible via a certain website or referer from that website only?
Say for example i only want my website to be accessible through adf.ly, how would i do such thing? Thanks for your help.
Note- adf.ly was just an example, i mean the general code.

You can use this in your /root/.htaccess :
RewriteEngine on
RewriteCond %{HTTP_REFERER} !adf\.ly
RewriteRule ^ - [F]
This returns a forbidden 403 status to clients if their referer doesnt match the pattern or it's not adf.ly

The simplest option is to check PHP's $_SERVER['HTTP_REFERER'] variable and deny any that does not come from your desired websites. But this is not a reliable method, as anyone can tamper with the HTTP request headers, setting the $_SERVER['HTTP_REFERER'] variable to false values.
If your request is not through a public client like a browser (for eg. you want to access via a server to server request), then you can rely on some sort of authentication to identify where the requests are coming from.

Related

How to use .htaccess to redirect a page but also use it as a W3 include

I am building an html site using the include method shown here from w3schools
https://www.w3schools.com/howto/howto_html_include.asp
the site basically looks like the following
<div w3-include-html="navigation.html"></div>
<body>
</body>
<div w3-include-html="footer.html"></div>
It works great when you're on the right pages of the website but if I navigate directly to navigation.html it displays a terrible looking and useless page.
I tried to redirect it using the .htaccess file with something like the following so a user could gracefully land on a page that says sorry this doesn't exist, click here blah blah...
Redirect /navigation.html /page-not-found.html
however that ends up causing the navigation bar on all my real pages to display the html within the page-does-not-exist.html page.
Is there an easy way to use .htaccess to redirect a user who is directly typing in www.example.com/navigation.html to www.example.com/page-not-found.html while still allowing my other pages to 'include' it normally?
Thank you for any help you can offer.
This method uses JavaScript (XMLHttpRequest object, ie. "AJAX") to make an HTTP request for the document on the server. Ordinarily, this is no different (from a server perspective) to a direct request that the client might make by typing the URL for the file directly.
You need to make the JavaScript request different so it can be detected by the server.
You can add a custom HTTP request header (or override the User-Agent string) to the JavaScript request and check for this header using mod_rewrite in .htaccess on the server to send an alternative response if this header is not set as expected (ie. if the file is requested directly).
For example, based on the code from w3schools, add a second line after creating the XMLHttpRequest object:
xhttp = new XMLHttpRequest();
xhttp.setRequestHeader('User-Agent','XMLHTTP');
This sets the User-Agent header in the JS request to XMLHTTP. We can then check for this using mod_rewrite and serve a 404 if not set.
However, you should not "redirect" to the page-not-found.html script. Set this as a custom 404 error document instead and allow Apache to serve this.
For example:
ErrorDocument 404 /page-not-found.html
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} !=XMLHTTP
RewriteRule ^navigation\.html$ - [R=404]
Any request for /navigation.html where the User-Agent string is not XMLHTTP is served the custom 404 error document, ie. /page-not-found.html. So, only requests from your script are permitted.
NB: This is not a security feature, it simply prevents anyone who casually types the URL into the browser from seeing the content (including search engines).
Aside:
<div w3-include-html="navigation.html"></div>
<body>
</body>
<div w3-include-html="footer.html"></div>
It looks from this that you are including HTML elements outside of the HTML body? This isn't valid HTML.

Apache Server Web directories access restrictions

I have set up an apache server, hosting a website.
For example In my website you can play with an online javascript atari roms. Whenever you load a rom in the website, the javascript temporarily downloads it to your browsers cache.
If you for example write website.com/roms/atari.zip you can download this rom. I do not want this.
Is there a way to forbid direct access to this file but also whitelisting access from within the javascript requests?
Many thank you in advance.
Requiring Authorization header is one way to do this.
Creating an authentication user:
/path/to/htpasswd -c /etc/htpasswd/.htpasswd downloaduser
And you'd supply the password. Note that the command above will create a new file, overwriting a previous one.
You would configure it in httpd.config like:
<Directory "/var/www/html/roms">
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/htpasswd/.htpasswd"
Require valid-user
</Directory>
Then, with XHR request in javascript,
req.setRequestHeader('Authorization','Basic ' + Base64StringOfUserColonPassword);
base64StringOFUserColonPassword is what the name implies, you can get it like window.btoa(username + ":" + password)), or with base64 command line command.
Further reading:
https://wiki.apache.org/httpd/PasswordBasicAuth
How to assign basic authentication header to XMLHTTPREQUEST?
Edit: there are xampp specific instructions for example here: http://chandanpatra.blogspot.com/2013/08/basic-authentication-with-htpasswd-in.html. The process is as I outlined for xampp as well.

"Access-Control-Allow-Origin" issue while calling https url of the same site from a http page via javascript

Getting "Access-Control-Allow-Origin" error while calling https url of the same site via javascript from page of the same site with http.
The site root url is set at the .cshtml file to use absolute path. When the page is cached and opened again, the site url shows as http while the root url remains https since it's cached and causes this "Access-Control-Allow-Origin" error.
I am able to fix the issue by setting "Access-Control-Allow-Origin" to "*" on the action method.
But this means it will allow for all domains, i want to allow it for my application or domain only.
How can i set it programmatically, so it will work across all environments?
Is there any other better way to set the site root url which will use absolute path?
what you are looking for is called CORS (cross-origin resource sharing, http://enable-cors.org/, https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
You do not have to use a wildcard on that header, you can set only a specific domain and even limit HTTP methods if you want to.
Access-Control-Allow-Origin: http://domain1.com
# if you want to, you can limit the methods too
Access-Control-Allow-Methods: GET, POST
As a general rule of thumb open your system only as much as you need to and try to keep the configuration as "tight" as possible.
You can cache a condition which test the protocol and then change the URL dynamically.
for example:
if (location.protocol == "https:") {
url = "https://....";
} else {
url = "http://....";
}
// your AJAX call goes here
More info about location protocol here.

Why ajax is not setting HTTP_X_REQUESTED_WITH [duplicate]

All over the Internet, included even here at Stack Overflow, people state that a good way to check if a request is AJAX or not is to do the following:
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' ) {...}
However, I don't see $_SERVER['HTTP_X_REQUESTED_WITH'] in the official PHP documentation
And when I try to do the following:
echo $_SERVER['HTTP_X_REQUESTED_WITH'];
Nothing is outputted.
Am I doing something wrong? Because I'd really like to be able to use $_SERVER['HTTP_X_REQUESTED_WITH'] if it's available.
The variables in $_SERVER are not really part of PHP, which is why you won't find them in the PHP documentation. They are prepared by the Web server which passes them on to the scripting language.
As far as I know, the X-Requested-With is sent by the Ajax functions of most major Frameworks but not all (Dojo, for example, added it only two years ago: #5801). As such, and taking into considerations #bobince' comments, it's safe to say it's not generally a 100% reliable method to determine whether a request is an AJAX request or not.
The only 100% secure way is to send a pre-defined flag (e.g. a GET variable) along with the request and for the receiving page to check for the presence of that flag.
don't forget that you can easily spoof any header with cURL like so
curl_setopt($ch,CURLOPT_HTTPHEADER,array("X-Requested-With : XMLHttpRequest"));
$_SERVER keys that start with HTTP_ are generated from HTTP request headers. In this case, the X-Requested-With header.
This header is a standardization-in-progress from all of the AJAX libraries out there.
It won't be documented in the php documentation per-se, but rather in the different AJAX libraries that set this header. Common libraries do sent this header: jQuery, Mojo, Prototype, ...
Usually these library will set the header using
xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
Here's a quick function with example usage:
function isXmlHttpRequest()
{
$header = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? $_SERVER['HTTP_X_REQUESTED_WITH'] : null;
return ($header === 'XMLHttpRequest');
}
// example - checking our active call
if(!isXmlHttpRequest())
{
echo 'Not an ajax request';
}
else
{
echo 'is an ajax request';
}
echo $_SERVER['HTTP_X_REQUESTED_WITH'];
What'd you expect from such a code? Assume you're running it directly from the browser, not using AJAX request. So, how come this header could be set?
Well the Answer to the Ultimate Question of Life, the Universe, and Everything - an HTTP sniffer! Get yourself one and forget of printing $_SERVER variable.
Firebug has one, or you may want to use Fiddler HTTP proxy or LiveHTTPHeaders Mozilla plugin. I'm bored to make links but it easily googled.
So, with HTTP sniffer you can be sure of any HTTP header ever.
Note that you can't prevent any "direct access" by using XHR, as every HTTP request to your server is already "direct".
You have to set it specifically in your ajax request object (that is if you are not using a framework like jQuery), but core Javascript; like so:
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
Where xhr is your request object.
Then, PHP will now receive and set it in the global variable $_SERVER like so:
$_SERVER['HTTP_X_REQUESTED_WITH']
Otherwise $_SERVER['HTTP_X_REQUESTED_WITH'] will always be null.
Note: In your javascript, Please make sure you set headers after the request is open. I mean after xhr.open() method.
You can also blame some browser bugs - see this question and its solution for Firefox
Firefox does not preserve custom headers during Ajax request redirect: an ASP.NET MVC solution
IE also having caching issue which is more serious then detection of request method.
You anyway needs to add cache busters to avoid caching, so why not use another flag to specify the ajax call - or more better you can use different URL like http://ajax.mysite.com/endpoint/sevice?params
I agree Pekka. There is no reliable native method between front side and back side that can auto-detect if a client is really calling an endpoint using AJAX.
For my own use, I have few main ways to check if a client is requesting one of my endpoint:
I can use HTTP_X_REQUESTED_WITH when I'm not in cross domain context.
instead of checking "X-requested-with", I'm checking $_SERVER['HTTP_ORIGIN'] (that is sent from AJAX request) intending to handle cross domain permissions. Most of time, the main reason why I'm checking if a request is an AJAX request, is especially because of cross domain permissions, using this PHP code: header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); // If this "HTTP_ORIGIN" is in my white list
my APIs expect from the client to explicit, in few cases, the datatype (JSON, HTML etc.) into a GET or a POST var. For example, I check if $_REQUEST['ajax'] is not empty or equal to an expected value.
The best solution to make sure if an HTTP request is truly sent via AJAX is using SESSION checking , you send session_id in a get parameter and you check this session if it's allowed or not !
$headers = apache_request_headers();
$is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');

Reading request headers in Javascript

I need to be able to read the request headers coming from a redirect from a naked domain:
http://mydomain.com
to
http://www.mydomain.com/index.html
I need index.html to be able to parse any original request path and queries, how can I do that?
E.g
From naked domain: http://mydomain.com/abc to http://www.mydomain.com/index.html and then index.html will get the abc path request.
The question is how to be able to achieve this?
A similar question: Using DNS to redirect to another URL with a path
use document properties to check and reditect
for others questions use navigator roperties
Get referrer use = document.referrer or document.URL
Look : http://www.w3schools.com/jsref/dom_obj_document.asp
In apache the best solution is control that with .httaccess

Categories