Can I prevent direct access to a file, but allow that page to be embedded in an other page as an iframe?
I am using Apache and php on the serverside, and the file to be included is on the same domain.
Perhaps not the best solution (as some browsers or routers remove it) but you could use the HTTP_REFERER server value?
Something like:
<?php
if($_SERVER['HTTP_REFERER'] !== 'http://my-domain.com/page-x') {
header('HTTP/1.1 403 Forbidden');
exit;
}
//rest of code here
Nope, you cannot. Either you make your page available to everyone, or to no-one.
You can protect the page via basic authentication in order to restrict he users who can access it, however who accesses it will need to know the credentials for the page. There is a SO question on a topic like this: Basic authentication for a url in an iframe.
Related
I have a flask app that redirects to a php site on an Apache server. I don't have much experience with php. The flask app is at mysite.xyz and the php site is at mysite.xyz/page1. I would like to deny access to anyone going to mysite.xyz/page1 unless they are coming from mysite.xyz. Something along the lines of:
if not coming from 'mysite.xyz':
redirect to 'mysite.xyz'
else:
pass
Except at the beginning of my php and in php.
Look at http://php.net/manual/en/reserved.variables.server.php and check the 'HTTP_REFERER' part.
Example Code:
<?php
if($_SERVER['HTTP_REFERER'] == "mysite.xyz"){
// ok, continue to load the page...
}else{
die("not allowed");
}
However, you can SPOOF the referrer to make it seem to be coming from mysite.xyz (but it is not the case) so it will never be secure.
Is there an option to provide an authentication system to your users to be able to handle this functionality without security flaws?
Is it possible to disallow direct access to a PHP file and allow the access only if it's redirected from other PHP file?
For example, access to loading.php should be only allowed if it's redirected from example.php page. How how can I do that?
I hope you understand what I mean. If not, please ask me, and I will try to explain better.
example.php
session_start();
$_SESSION['loading']='yes';
loading.php
session_start();
if($_SESSION['loading']=='yes'){
/all good
}else{
//bad, redirect back or whatever
}
$_SESSION['loading']=''; // clear session var
You can check referer, but it not secure:
loading.php
<?php
if($_SERVER['HTTP_REFERER']!=='http://yoursite/example.php')
die('Denied');
--
or you can set visited flag in session
example.php
<?php
$_SESSION['isVisitedExample'] = true;
loading.php
<?php
if(!isset($_SESSION['isVisitedExample']))
die('Denied');
--
or in cookie (not secure)
example.php
<?php
setcookie('isVisitedExample', 1);
loading.php
<?php
if(!isset($_COOKIE['isVisitedExample']))
die('Denied');
--
or mix this methods
Test for the variable $_SERVER['HTTP_REFERER']. (yes, the incorrect spelling is what must be used.) That variable contains the URL of the site that a user came from. The REFERER header is blank or '-' if the page is accessed directly.
The code for this would look something like the following:
if (empty($_SERVER['HTTP_REFERER']) or $_SERVER['HTTP_REFERER'] == '-') {
exit; // do nothing if hit directly.
}
// The real page logic goes here.
If you want to only allow the loading page from a specific URL, then you may test for that URL instead of testing for empty().
Please be aware that the REFERER header is sent by the browser and easily spoofed. That said, checking the referer header is useful for blocking other sites from directly loading images from your site.
Another option would be to use sessions and session variables to check that someone hit the appropriate page before the loader page.
I want to deny direct access to a file, but allow access to use it in <script> tags only at my website.
Can someone please help me using PHP or .htaccess?
You cannot. The src attribute of a <script> tag is just a regular URL that can be accessed like any other URL. Nothing more, nothing less.
However, if you want to:
Prevent unauthorised access
Move the JS file outside of the web server document root, so as to prevent direct access. Serve the JS file from a server-side script, only to authorised parties. Example in PHP:
file: publicScript.php
<?php
if(access_granted()) { // use your usual authentication routine here
header('Content-Type: application/javascript');
readfile('/path/outsideOf/documentRoot/hiddenScript.js');
} else {
echo 'alert("access denied");';
}
file: page.html
...
<head>
<script src="//publicScript.php"></script>
</head>
...
Prevent unauthorised use of the JS
If the JS is supposed to issue HTTP requests (Ajax), keep in mind that it will also send session information (e.g. cookies) along. In fact, queries issued from JS are impossible to distinguish from a regular request (eg. click on a link), as far as the server is concerned. Such requests can be authenticated by your server just like any other request.
Prevent reverse-engineering
Obfuscate your JS file. A quick search on your favourite search engine will return thousands of options.
If this still poses a security concern to you, then it is likely that your JS code is doing too much. Take critical features away from the JS and have your JS call a server-side API instead.
Supposed the page is example.com/blog/data.php. I am using file_get_contents to get the content in another script page. Now, i want to:
Forbid google search to crawl and index the data.php page.
Forbid the visitor to access it
Is there a way to achieve this?
You can redirect to another page if the request url is example.com/blog/data.php, but a far easier and more logical solution would be to move the file out of your web-root.
Edit: If you really want to keep the file inside the web-root, you can use something like this at the top of the script that you don't want to access directly:
if ($_SERVER['REQUEST_URI'] === $_SERVER['SCRIPT_NAME'])
{
header('Location: /'); // redirect to home page
}
However, this will probably not work in combination with file_get_contents (you need to remove these lines from the result), you could include the file instead.
Don't put data.php under the web root. Keep it in a parallel directory.
You can pass token via GET. Overall your way is slightly wrong. Why don't you incorporate the data.php logic in the script that is calling it.
Simply apply access restriction for authorized users only. You are able to do it in the most simple way by accessing your page using url parama as password:
example.com/blog/data.php?secret=someblah
and in the first of your file data.php do the following:
<?php
if (!isset($_GET['secret']) || $_GET['secret'] != 'someblah')) exit();
?>
However,It is recommended, don't use this from public computer becuase it is not secure but it is the primitive authentication principle.
I have several pages inside an AJAX directory. I don't want these pages accessible directly so you cannot just type in the URL of the page within the AJAX directory and access it. I "solved" this by using a PHP session on the page that calls it as follows:
Main page:
<?php
session_start();
$_SESSION['download']='ok';
?>
and on the ajax page I have this:
<?php
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;}
?>
The only problem is that if a user goes through the correct process once, the cookie is stored and they can now access the page directly. How do I kill the session once they leave the parent page?
thx
why use session ?
if i understood what you want:
<?php /// Is ajax request var ?
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=="xmlhttprequest") {
// do your ajax code
} else {
// redirect user to index.php since we do not allow direct script access, unless its ajax called
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit();
}
} ?>
A really simple solution is to open up each of the files you want to protect from direct URL entry & add the following to the top:
<?php if (isset($_GET['ajax']) != true) die();?>
Now get rid of your redirect script since it's useless now. You don't need to use sessions for this. Every time you request a page, use it's direct URL, just add ?ajax=1 to the end of it.
By adding the ?ajax=1, PHP will set a key of 'ajax' to the $_GET global variable with the value of 1. If ?ajax=1 is omitted from the URL then PHP will not set a key of 'ajax' in $_GET and thus when you check if it's set with isset() it will return false, thus the script will die and not output anything. Essentially the page will only output data if ?ajax=1 is at the end of the URL.
Someone could still "spoof" the URL and add '?ajax=1' themselves, but that is not the default behavior for people or web browsers. If you absolutely need to prevent this then it will be much more complicated, e.g. using templates outside of a publicly available folder. Most other "simple" solutions will have the same "spoofing" potential.
There's really no way to accomplish this with a 100% certainty - the problem is, both AJAX and regular web browser calls to your web site are using the same underlying protocol: HTTP. If the integrity and security of your site depends on keeping HTTP clients from requesting a specific URL then your design is wrong.
so how do you prevent people from directly accessing files inside certain directories while still letting the site use them??
Create a controller file. Send all AJAX requests to this controller.
ajax-control.php
<?php
$is_ajax = true;
include "ajaxincludes/test.php";
// ... use the ajax classes/functions ...
ajaxincludes/test.php
<?php
if (!isset($is_ajax) || !$is_ajax)) {
exit("Hey you're not AJAX!");
}
// ... continue with internal ajax logic ...
If clients try to access the file directly at http://mysite/ajaxincludes/test.php they'll get the error message. Accessing http://mysite/ajax-control.php will include the desired file.
I don't think there is a surefire way to do what you are asking, since HTTP request headers can be faked. However, you can use $_SERVER['HTTP_REFERER'] to see if the request appears to be coming from another page on your site.
If the rest of the security on your site is good, the failure of this method would not grant the user access to anything they were not already able to access.
I've never tried this but maybe you could do something with jQuery's .unload() and then call a PHP page to unset() the session.
Why not (on Ajax page):
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;
}
// do whatever you want with "access granted" user
// remove the download flag for this session
unset($_SESSION["download"]);