Restrict access to page based on referrer page - php

I need to restrict access to a page only if visitor came from specific wordpress page(s).
I have been Reading here since morning and most answers I see discourage the use of "just" referrer because it can be spoof.
I do not know much about php security and vulnerabilities. My only aim is to "discourage" users bookmarking the page and access to it directly. I need to validate visitors on our wordpress website and point them to the page only when they are authenticated.
Currently what I came up so far is this.
<?php
$ref = $_SERVER['HTTP_REFERER'];
$theOrigins = array(
'http://mysite.tld/?page_id=x1',
'http://mysite.tld/?page_id=x2');
$validRef = false;
if (in_array($ref, $theOrigins)) {
$validRef = true;
}
if (isset($_GET['passkey']) && ($_GET['passkey'] == 'thePasskey') && $validRef ) {
?>
<show html page>
<?php
} else {
//echo 'You are not supposed to access this page directly';
header('HTTP/1.0 403 Forbidden');
exit('Forbidden');
}
?>
This is mostly based on the answer in this post
What is the best way to password protect folder/page using php without a db or username
I am planning to add the solution in this page
http://thisinterestsme.com/restricting-access-referrer/
But according to this post,
Passing PHP Session Value
wp does not use sessions
Is this instruction on how to use wp session no longer applicable in current wp versions?
https://silvermapleweb.com/using-the-php-session-in-wordpress/
What are my options?
Thanks

Moin,
if you know that what you are trying to do is insecure (possibility to manipulate the HTTP header HTTP_REFERER), you could try to be less specific about the allowed URLs. Maybe just check for the right host:
if(strpos($ref, 'mysite.tld') !== false && $_GET['passkey'] == 'thePasskey')
{ ... }

Related

Preventing direct access to a page, but allowing iframe embedding

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.

how to redirect to secure section of website with Login script created in redbeanphp

$email = trim($_POST['email']);
$pass = md5(trim($_POST['password']));
$user = R::findOne("user"," email = ? AND password = ? ", array($email,$pass));
if($user != NULL) {
// good login
header('Location: http://www.google.com/');
} else {
// bad login
}
Now the framework we are provided already in redbean to create the login script is in this file which runs when we submit any form on website -
require_once('xyz.class.php');
if (isset($_REQUEST['apiName']) && $_REQUEST['apiName'] != null) {
$apiName = $_REQUEST['apiName'];
switch ($apiName) {
case 'requestSignUp':
echo UberHealth::requestSignUp($_REQUEST['email']);
break;
case 'contact':
echo UberHealth::contact($_REQUEST['email'], $_REQUEST['msg'], $_REQUEST['name'], $_REQUEST['subject']);
break;
...
}
}
and xyz.class.php has redbean functions for logging in / sign up etc.
Now when i login through this script this gives me an error on console like -
XMLHttpRequest cannot load http://www.google.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
I have tried
return header('Location: http://www.google.com/');
return json_encode(header('Location: http://www.google.com/'));
instead of just header('Location: ...'));
But gave the same error.
I think you're missing the Access-Control-Allow-Origin header, as the message said :)
Here is the same question on SO.
Edit: To address your header alternative question
As far as I understood you're searching for an alternative approach for header redirects. Well typically PHP Frameworks I know use some Bootstrapping mechanisms to build the user output. Take a look at my rude graphic below:
Essentially the request from the client will always be handled via a main entry point (index.php) where you depending on the url style either use hashes, or parts of the querystring to determine where to navigate to. Thats the job of the bootstrapper to find out: "Ok the user want's to visit Page XYZ".
The next layer could be the Authorization amongst others. Here you would check whether the user has the permission or not if so continue to your BL and render the result which then is returned to the client.
So this whole sequence takes place during the initial request from the client thus no redirecting would be needed. For detailed examples take a look how well-known Frameworks do the Job.

How to prevent direct access to php pages through URL

I have index.php that include pages like
<?php
define('MyConst', TRUE);
include_once('template/header.php');
if (!empty($_GET['action'])) {
$action = $_GET['action'];
$action = basename($action);
include("template/$action.php");
} else {
include("template/main.php");
}
include_once('template/footer.php');
?>
With in a template directory I have main.php which has link to other pages like page1.php, page2.php.
Goto page 1
Goto page 2
How could I prevent users form accessing pages directly typing "http://mydomain.com/?action=page1" on the URL? And redirect them to main.php if they have done it?
You can not. What you want is simply not possible.
For the server side there is no way to know whether an URL is typed or clicked.
If I understand correctly, the thing you want is to prevent the user to access http://example.org/?action=page1 unless they came from http://example.org/?action=main. To do that, you must be able to detect whether they came from http://example.org/?action=main. The safest way to do that is to generate some random value that you associate to the users when they access http://example.org/?action=main and to check whether there is a correct value associated to the users when they want to access http://example.org/?action=page1. If not, they tried to access that page directly.
Check for HTTP_REFERER and if it is not pointing to right values (like your meny page) then redirect user.
Maybe you can try this, On your index.php :
session_start();
if(! isset($_GET['action']))
{
$_SESSION['pageAccess'] = true; # Set the key whatever you want
}
then under that script (we need that session_start() used twice) :
if(isset($_GET['action']))
{
if(! isset($_SESSION['pageAccess']) || ! $_SESSION['pageAccess'])
exit('There is no direct access allowed.');
}
Hope this help, have a nice day.
As per your Question:
There are two approaches that you can follow:
Use HTTP_REFFRER and check on desired page if User is coming from the page u wanted. IF he is accessing the direct URL then show him error page.
Use $_SESSION but this approach can be harmful as SESSION will always be there untill browser / instance closed.
So better to go for 1st approach.
And also as per Pehaa, you can not check id URL is typed

Check if traffic is coming from specific URL?

I want to make a count of visits to my website from referal websites. I know there are many programs such as Google analytics but there will show you that my taffic is coming from www.facebook.com for example. I want to check if the traffic is coming from some specific urls that I specify such as www.facebook.com/myfanpage.
Befor I think about php I tried several methods with javascript that they did not seem to function the way I wanted to. For my search for php I only found this function. Any Ideas ?
$_SERVER['HTTP_REFERER']
$_SERVER['HTTP_REFERER'] Will do exactly what you need.
if (strstr($_SERVER['HTTP_REFERER'], 'facebook.com') !== false) {
// Facebook brought me to this page.
}
elseif (strstr($_SERVER['HTTP_REFERER'], 'google.com') !== false ) {
// Google brought me to this page.
}
Sorry, I know this is 6 months late but surely if the url was http://mydomain.com/?p=facebook.com then this would also be true? a better way would be to explode the referrers url based on / then extract the 4th section i.e.
$refererUrl = $_SERVER['HTTP_REFERER'];
$Exploded_URL = explode("/",$refererUrl);
$urlToCheck = $Exploded_URL[3].'.'.$Exploded_URL[4];
if($urlToCheck == 'facebook.com'){
/* From Facebook */
} elseif ($urlToCheck == 'google.com'){
/* From Google */
}
$_SERVER['HTTP_REFERER'] should contain the URL that the user is coming from to get to your page. It's not a function. It's simply a value. So you can use it for this purpose.
Do note, however, that the value is easily spoofed. (It's taken from the HTTP request header, and the user can send whatever they want.) It should be acceptably reliable if you're just collecting stats for your own interest or whatever. But if you're trying to use it to secure the page (e.g., only show certain content if the visitor came from a certain URL), forget it.
You will be able to check only if the HTTP Request has referer which is actually accessible in PHP using HTTP_REFERER. So its solely responsible from the referring website.
Get original URL referer with PHP?
The above post also will help you.

how can I restrict user access on specific pages? (Drupal, php, FileMaker Pro 10)

I am working on a website which already has user access set up so that only members who are logged in can see certain pages. Now i need to go in and make the access for logged in users more specific. So, anyone who logs in can see the site, but there are 2 pages (called PDQ and Comm Plus) that should only be accessed by users that have PDQ or Comm Plus access. I use a filemaker 10 database to keep track of user information. If the user has PDQ access, then PDQ=1 in the database. the website is coded in Drupal,php, and html.
So right now I have a good idea of what to do but there are some pieces missing and im not very familiar with drupal or filemaker. I need for the page to get the user information and see what the value of PDQ is in the database. If 1 then grant access to the page, and if 0 go to the access denied page.
Here is what I have so far
<?php require_once('DatabaseName');
global $user;
//looks at the current user
$use = $user->uid;
//Not sure what goes here. I need code that looks at the filemaker database to see
//what the value of PDQ is and then stores it in a variable.
if (!session_id()) session_start();
if (!isset($variableGoesHere) || $variableGoesHere == '0'){
drupal_goto("access-denied");
exit();
}
?>
Any help would be greatly appreciated. Also, let me know if im on the right track or if I need to be looking somewhere else. Thanks!
First of all, using Drupal and not using the Drupal system to store info is a bad idea. If you use Drupal, you can use an external source to do the login, but your users should have a drupal user.
When your users are Drupal users things get a lot easier. You can use the Drupal access control system to check access etc.
If Drupal is serving the page, you should never write code like you have shown, hook_menu which is how you register paths has a access callback option, where you can handle your access, or you can just check if the user has a permission. This stuff only applies if you are doing the stuff in a custom module, which is what it seems like you are doing.
In any regard you should use the drupal_access_denied function if you want to return access denied yourself.
I figured this out a long time ago, but I never got around to answering the question. So heres what I did
$WebAuth_find = $FILMAKER->newFindCommand('WebAccess');
$Search_findCriterions = array('Access::cntdPhoneNumberDisplayCalc'=>"==".$find,'Access::phoneType'=>"E-mail",'Access::phoneMain'=>"==1",'LoginAccess'=>'1');
foreach($Search_findCriterions as $key=>$value) {
$WebAuth_find->AddFindCriterion($key,$value);
}
$WebAuth_Result = $WebAuth_find->execute();
if (FileMaker::isError($WebAuth_Result) && $WebAuth_Result->code == 401) {
echo "FM ERROR CODE: ".$WebAuth_Result->code."<br>"."ERROR: ".$WebAuth_Result->getMessage();
This identifies the current user in the Filemaker database under the WebAccess layout. It throws an error message if there is a problem. Now that I am looking at the current user I have it look to see what is in the Comm Plus and PDQ fields in the database, and create a session to hold the information.
else{
$FinalResult = current($WebAuth_Result->getRecords());
$_SESSION['district']= $district;
$PDQ = $FinalResult->getField('PDQ_subscription');
$_SESSION['PDQ'] = $PDQ;
$CommPlus = $FinalResult->getField('CommPlus_subscription');
$_SESSION['CommPlus'] = $CommPlus;
Then I just add the following code to the top of whatever page I want to restrict access to. It looks at the session to see if the current user has credentials if not they are directed to the access denied page.
$PDQ_check = $_SESSION['PDQ'];
if (!isset($PDQ_check) || $PDQ_check == '' || $PDQ_check == '0'){
drupal_goto("access-denied");
exit();
}

Categories