Denying Access To A Page Based On Referrel - php

Here's where I'm at:
I have a Wordpress plugin that allows for subscriptions to be in place, and uses the Paypal IPN. This plugin denies access to certain pages based on whether a user has an active subscription.
I have another plugin that allows for one time payments for a different service. This takes the user to Paypal, and redirects them to a page where they can upload videos. These videos can only be uploaded after payment, but anyone can access the page by direct URL...
How can I limit access the this upload page?

So I'm not sure if you want to do this with JavaScript or PHP... PHP would be more reliable (people can turn off JavaScript,) but ultimately, the referrer can be altered by a user if they are really keen to bypass any measures you put in place, so bear that in mind when implementing this.
The best way would just be to have an if statement checking the referrer, and if it isn't an acceptable referrer, just redirect them.
<SCRIPT LANGUAGE=JAVASCRIPT TYPE="TEXT/JAVASCRIPT">
<!-- Hide script from old browsers
if (document.referrer != '[Only Allowed Referrer URL]')
{
window.location = "http://not.allowed.to.view.site";
}
//-- Stop hiding script -->
</SCRIPT>
or
<?php
if ($_SERVER["HTTP_REFERER"] != "[Only Allowed Referrer URL"])
{
header( 'Location: http://not.allowed.to.view.site' ) ;
}
?>
I haven't fully tested the above code, but something like that is what you want. Basically, if it isn't from an "allowed" referrer, redirect to an error page.
Again, using the referrer URL to deny or grant access to a page isn't that reliable, but if you want to do it, something like that is what you need. Also be wary of things such as the URL may sometimes have "www." at the beginning, sometimes may not. There may be variations of the URL that you will want to consider in your if statement.

I assume that you are using something like this in your paypal form:
<input type="hidden" name="return" value="http://mydomain.com/verify.php">
If so, in this page: http://mydomain.com/verify.php you must verify if the transactions was right. Instant Payment Notification - Code Samples stuff, correct? Well, if this verification is invalid you deny all further processing (uploading video).
Otherwise you redirect to let's say http://mydomain.com/upload.php:
header('Location: http://mydomain.com/upload.php') ;
Now, in the uploading page you put at top:
if ($_SERVER['HTTP_REFERER'] != 'http://mydomain.com/verify.php')
{
die('get out of here!');
}

Related

match previous url to give alternate 'cancel' button

I have a site with a normal admin and a super admin, both share some functions. A new function I am introducing is a admin serial activation. This is already implemented in normal admin and now I am trying to add same code to super-admin. If you are in normal admin or super admin you would click the serial to activate and move on to activate2.php to activate. All works well and good unless you change your mind about activating serial, in which case you would click 'back' or a 'cancel' button to return to previous screen. I currently check what the previous page was using php:
$ref = $_SERVER['HTTP_REFERER'];
The idea is to show a different return url on 'back' link and the 'cancel' button depending on if the previous page was 'super-admin-serials.php' or just 'admin-serials.php'. I tried to match 'super-admin-serials.php' in $_SERVER['HTTP_REFERER'] to deduce what the previous page was and allow the user to go back to his previous page. But the code I have put together does not work, so if anyone out there can help with this simple function it would be much appreciated. Here is the code I have so far on the independent 'activate2.php' page to cancel and return to previous:
$superpage=array('super-admin-serials.php');
$ref = $_SERVER['HTTP_REFERER'];
if (in_array($ref, $superpage)) {
echo "back (super admin)";
} else {
echo "back (normal admin)" ;
}
The HTTP referer may not just contain the name of the script it comes to, it usually includes a fully qualified URL such as http://example.com/foo/your-script.php.
Instead of observing the HTTP referer (which will be lost if they refresh the page), I suggest that you pass an argument from the first page to the second to determine where they came from, and send them back where you need.
Transparently the user will be accessing either of:
activate2.php?super=1
activate2.php
Then the following code will do what you want:
$isSuper = !empty($_GET['super']);
if ($isSuper) {
echo "back (super admin)";
} else {
echo "back (normal admin)" ;
}
I understand you have some kind of sign in feature and you cannot be logged in simultaneously with two different users (if that's not the case, just make sure you aren't running an insecure site that can be easily hacked). In that case you should already have that information on the server so it's both unnecessary and unreliable to gather it from client-side. So code would look like this:
if ($_SESSION['is_super']) {
echo 'back (super admin)';
} else {
echo 'back (normal admin)';
}
(Please note I've also removed double quotes, which served no other purpose than making code harder to write and read.)
In any case, you must be aware that HTTP_REFERER:
Will get lost if you add extra steps (e.g. show form errors to get them corrected)
May not be there at all (some proxies and security programs strip it)
Will often include extra stuff that make a simple string comparison fail, like GET parameters (and it's of course a full URL)
If you opt for it anyway you may want to have a look at parse_url() as starting point.

Detect SSL when proxy *always* claims a secure connection

I want to detect whether or not a user is viewing a secure page and redirect if not (for logging in).
However, my site travels through a proxy before I see the server variables and the proxy (right now) is telling me that $_SERVER['HTTPS'] is 'on' when the URI clearly indicates otherwise. It also shows 'on' when the user is navigating 'securely'.
Navigating through http:// and https:// both output that $_SERVER['SERVER_PORT'] = 443.
I don't have the ability to make any changes to the proxy so I want to know:
Does PHP have any other options for me to detect the truth or...
Am I stuck to resort to JavaScript's mechanisms for detection and redirection.
I mined this question for ideas but they mostly revolve around the $_SERVER['HTTPS'] variable being trustworthy. Bah!
It appears that this question is experiencing at least something similar, but s/he was able to resolve it by adapting an apache solution.
Are there any other PHP SERVER variables or tricks available to detect what the user's URI begins with? The only difference between the $_SERVER variables when my site is viewed http versus https are the following:
_FCGI_X_PIPE_ (appears random)
HTTP_COOKIE (sto-id-47873 is included in the non-secure version but I did not put it there)
REMOTE_ADDR (This and the next two keep changing inexplicably!)
REMOTE_HOST
REMOTE_PORT ('proxy people', why are you continually changing this?)
Are any of these items strong enough to put one's weight upon without it splintering and causing pain later? Perhaps I shouldn't trust anything as filtered through the proxy since it could change at any given time.
Here is my plan to use JavaScript for this purpose; is it the best I have?
function confirmSSL() {
if(location.protocol != "https:") {
var locale = location.href;
locale = locale.replace(/http:\/\//,"https://");
location.replace(locale);
}
}
<body onLoad="confirmSSL()">...
I think if the user has JavaScript disabled in my community, then they hopefully know what they are doing. They should be able to manually get themselves into a secure zone. What sort of <noscript> suggestions would be commonplace / good practice? Something like this, perhaps?:
<noscript>Navigate using https://blah.more.egg/fake to protect your information.</noscript>
PHP solutions that work (with good explanation) will be given preference for the correct answer. Feel free to submit a better JavaScript implementation or link to one.
Many thanks!
Although already partially discussed in the question's comments, I'll summarize some suggestions concerning the redirection logic in JavaScript:
Generally using window.location instead of location is advisable, an explanation can be found here.
Regex seems like a bit of an overkill for a simple replacement of the protocol.
The redirection logic should be executed as soon as possible, because in the event of redirection, every additional document processing is unnecessary.
Browsers with JavaScript disabled should at least show a notification prompting the user to switch to https.
I suggest using the following code (adopted from here), which is short and efficient:
<head>
<script type="text/javascript">
if (window.location.protocol != "https:") {
window.location.href = "https:" + window.location.href.substring(window.location.protocol.length);
}
</script>
...
</head>
<body>
...
<noscript>Please click here to use a secure connection!</noscript>
...
Just use the client-side approach. If your proxy is non-configurable, then that option is out. Detecting and redirecting via js is fine.
There is also a way to achieve the redirection without client side javascript. This method can be especially helpful, if JavaScript is disabled in the client's browser.
The steps are pure PHP and pretty simple:
Start a session
If it's a fresh session, redirect to the https location
If the session isn't new, it can be assumed, that the user has been redirected
Example code:
<?php
session_start();
if( !isset($_SESSION['runningOnHttps']) ) {
$_SESSION['runningOnHttps'] = true;
header('Location: https://my-cool-secure-site.com');
}
?>
Naturally, you could restrain this functionality to those browsers with JavaScript disabled in order to create a kind of 'hybrid mode': Whenever there is a new session with a non-JS browser, make a request to some kind of callback script that notifies the server to send a location header:
some_landingpage.php sends an initial <noscript> containing a hidden iframe, which will load redirect.php:
if( !isset($_SESSION['checkWasMade']) ) {
$_SESSION['checkWasMade'] = true;
echo '<noscript>
<iframe src="redirect.php" style="visibility: hidden; position: absolute; left: -9000px;"></iframe>
</noscript>';
}
A request to redirect.php will let you know, that JavaScript is disabled and give you the chance to force redirection by sending a Location header (see above) with the next actual request.
As a matter of course, this method will only work reliably, if the protocol won't change (magically?) during one session.
UPDATE:
All of the above-mentioned method for handling non-JavaScript user agents could be rendered moot by an even neater approach:
I just learned, that <noscript> can also be included inside the <head>, which allows one to just redirect via <meta> tags.
Hence, some_landingpage.php could send an initial meta-refresh inside <noscript>:
// The following echo must appear inside the html head
if( !isset($_SESSION['checkWasMade']) ) {
$_SESSION['checkWasMade'] = true;
echo '<noscript>
<meta HTTP-EQUIV="REFRESH" content="0; url=https://my-cool-secure-site.com">
</noscript>';
}

How to hide HTML Page Source in php by detecting the URL

I do not care about people viewing my source code, however, I want Bots to avoid coming on to my site and getting through my security. I was hoping to disable page source viewing. To do this, I am using this code:
$url= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$needle = "view-source:";
if (strpos($url,$needle)) { echo "You can not see me";}
else {
//The rest of my index page
}
The objective here is that if someone tries to view my page source or if a bot tries to, that rather than being able to see it, the code will detect that the page URL is view-source:www.yoururl.com and will display a "Nice try" message in the source instead of the page source. The code above in theory should have worked, but didn't. Any other idea's to try and make this work?
This cannot be done, the HTML source code is passed to whoever requests it. You should probably redesign your captcha, as it is not secure from how you described it. Use session variables to store the data and to check against the submitted value on the form processor script.
you could use mod_rewrite and a permanent 301 redirect in your .htaccess to hide the ?captcha=xxxx part of your url, if it is your sole concern.

Redirect a user to an external site while linking to an internal page?

How can I redirect a user to an external site while linking to an internal page ?
I have seen examples like:
example.com/go/ksdjfksjdhfls
example.com/?go=http://www.new-example.com
... And many more...
How this is achieved in php ?
Does this have any pros/cons with regards to SEO ?
I don't see any benefit in this approach, but there are a few ways to achieve it. To do it with the GET query, you would simply need the following code:
HTML:
Google!
PHP:
if (filter_var($_GET['site'], FILTER_VALIDATE_URL)) {
header('Location: ' . $_GET['site']);
}
With the above example, it will actually take the user to that location, not to:
http://example.com/link.php?site=http://www.google.com
To achieve the url being "local" while pulling up a remote site, you'd either have to:
Mess with URL rewriting, which can get messy and I'm not sure will let you do the above
Retrieve the remote page via curl and display it, which may screw up links on the "remote" page
Use iframes and set the iframe to be the size of the page. Note that this last method, while least offensive, is recognized as a potential security breach known as 'clickjacking' since it's used to trick users into clicking on a link for one page which his hiding a malicious link to another site. Many servers and browsers are taking steps to avoid this (for instance, google does not allow iframing of its home page), so this may also reach dead ends.
So of the three server-side methods I can think up, one may or may not be possible, and is a pain. One will be crippled and put a heavy load on the server. The last is a known bad guy and is likely not to work for many cases.
So I'd just go with a redirect, and really, if you don't need the address bar to show the local URL, then I'd just have a direct link.
All of the raises the question: What are you hoping to accomplish?
put this is beginning before any output to browser
<?
header('location:example.com\index.php');
?>
Set up an index php file which sets the header location to the url in the get parameter.
example.com/?go=http://www.new-example.com :
// example.com/index.php
<?php
if (isset($_GET['go'])) {
$go = $_GET['go'];
header('Location: $go');
} // else if other commands
// else (no command) load regular page
?>
example.com/go/ksdjfksjdhfls :
// example.com/go/ksdjfksjdhfls/index.php
<?php
header('Location: http://someurl.com');
?>
I use .htaccess rules for this. No PHP needed.
i.e.
Redirect 307 /go/somewhere-else http://www.my-affiliate-link.com/
So visiting http://www.mywebsite.com/go/somewhere-else will redirect to http://www.my-affiliate-link.com/.
On my site, I use "nofollow" to tell the search engines not to follow the link. The 307 status code means "temporary redirect".
Click here!
example.com/?go=http://www.new-example.com
you can use iframe and set the src attribute to http://www.new-example.com
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<iframe src="http://www.new-example.com" width="100%" height="100%"></iframe>
</body>
</html>

How can I deny users access to parts of my Backbone App if they have not logged in?

So I've got a Backbone application + web homepage. Right now, if you login to my website, I create a global object with your user details from the database. However, you can still just hit one of the routes in the application directly.
How should I handle users who are not "logged in" and redirect them to a "you must login page"?
Is this a standard operation? Basically, I have a REST url setup that returns just
{ sessionId: [php-session-id-here] }
If they are logged in, it would return something more like this:
{
sessionId: [php-sess-id],
userId: [user-id-from-db],
firstName: [f-name],
lastName: [l-name]
}
Ideas? Thanks!
What I've done in the past is to include on every page along with jQuery (actually, added to the jQuery file) an extension on the AJAX method to check for a custom code that I send when a user isn't logged in. When that value was seen it redirected the user to the login page regardless of what was going down.
This was because that site had a time out on login, so a user could get logged out while sitting on a page and then the AJAX request would just fail. If you don't have a timeout on the login the odds of ever seeing this issue are slim. Just ignore requests that come from users that aren't logged in.
If you need help coding this, start here: Extending Ajax: Prefilters, Converters, and Transports.
Really shouldn't require anything as complex as pseudo-code:
JS needs to do some AJAX, so JS talks to server
PHP checks for login if needed
If not logged in, send back the abort message (I used a converter to catch a "notLoggedIn" dataType. However this could also be done with a transport, they are just more complex.)
JS sees the abort message and does a window.location redirect rather than return AJAX message.
If you want, you could load a lightbox with a login form and send that via AJAX to PHP where a re-login can take place, if you remember the AJAX attempt that failed you can send it again after login. Then the user doesn't even need to leave the page to log back in.
If you're using jQuery, you can set a global ajaxSetting that allows you to do certain things upon certain http codes. Some pages I read recommend adding to your JSON a url field to point to where to login, but I figure that's just up to you. So the only modifications you'd need to implement what I've mentioned is 1. change the http code to something reasonable like 401 (unauthorized) and implement the http code handler. But I wouldn't call this standard, I'd just say that's what several people have done (including myself).
<?php
function IsLoggedIn()
{
if(isset($_SESSION['id'])) // Change that to what you want
{
return 1;
}
else
{
return 0;
}
}
?>
Then in your code, you could use something like:
if(isLogged()){ header('Location: http://google.com'); }

Categories