I created a PHP page that is allowed only for one person, That's OK but when the non allowed user write in address bar view-source:tstwebsite.com/test/page.php it shows the user the source of the page can I block the source code from the user? this is my code that allow this page only for one user.
$aiwab = mysql_query("SELECT * FROM `table`");
while($aiwa = mysql_fetch_array($aiwab)){
$alo = $aiwa['allowed'];
if ($alo == 2 ){
}else{
echo "<script>javascript:history.go(-1)</script>";
}
}
So how Can I block the user from viewing the source code?
Using javascript to "block" a user is, frankly, stupid. javascript can be disabled/ignored/bypassed, exactly as you've seen with your view-source "hack". "Security" can never be established if you're relying on the CLIENT to cooperate.
Use proper server-side authentication, e.g. even HTTP basic authentication, to protect the script.
If you just want to quickly change this from client-side authentication to server-side, then you could make the following change:
if ($alo == 2) {
}
else {
// Redirect them by sending a HTTP Location header
header("Location: www.yourdomain.com/path/to/another/page");
}
Note that the above solution will only work if header() is called before any output is sent to the browser (HTTP headers have to be sent before the body of the message begins).
This functions very similarly to your current solution, with the difference that the redirect is caused by code on the server rather than in the browser. view-source lets someone get around your authentication as it allows them to load the page in their browser, without running the client side code.
This is just a quick fix that should help illustrate the difference between client side and server side authentication. If this is for anything beyond just messing about and learning a little code, then you should really be learning more about security. Also note that the mysql functions you're using are currently deprecated and you should instead be using mysqli, or pdo
You will also want to read up on the uses of client-side versus server-side code, just to get a grasp of what to use for what tasks and why.
Related
i'm new to php, and i'm having a hard time establishing proper session mgmt. controls to prevent unauthorized access to a specific section of my site. I'll give an example...
myimaginarysite.com/application/index.php has a form to auth the user and it will redirect you to 'portal.php' after successful auth. 'portal.php' will check for a valid session as part of an include and then based on that it will either send u back to authenticate via header("location....) or just load up the HTML content. Now, if an unauthorized user hits 'portal.php' directly.. because they won't have a valid session.. they will get redirected back to the index, however, if you proxy the traffic you will see that the whole HTML content for 'portal.php' will actually be sent to the client (although not displayed on the browser) before redirecting back to the login page. So my question is... am I missing something, is there a way to make sure the HTML content is suppressed and is not sent to the client??
below is a snippet of my code for 'portal.php'
<?php
include "includes/checksession.php";
?>
<html>
<body>
Who Am I ??
<br></br>
Log Off
.....bunch of authenticated content.....
</body>
</html>
You need to stop script execution after sending the redirect headers with die() or exit(). Header redirection only sets the http headers, otherwise the page content is the same unless you instruct it otherwise.
Stopping script execution, like Juhana suggested, is probably the easiest solution for now, but there are other possibilities of course. You can just make the output conditional:
<?php
if (checkSession())
{
// redirect to login page
}
else
{
// output HTML.
}
If your site grows larger, it will probably (hopefully) also be more structured. If so, it might be easier to include other page fragments. So your code could look like this at first:
if (!checkSession())
{
include 'loginpage.php';
}
else
{
include 'portalpage.php';
}
And eventually maybe:
if (!checkSession())
{
ApplicationContext.setController(new LoginPageController());
}
Whatever the case, exit works fine and may be useful, especially for a case like this, but it terminates your script quite abrubtly, so it might get in the way of other processes that you may want to include, like debug-output or logging, profiling, and stuff like that.
using JS : (in <head> tag)
<script>window.location="https://stackoverflow.com";</script>
using PHP : (in <head> tag)
header('Location: https://stackoverflow.com');
end();
Which one I should use ? or another ?
and what about using <meta>?
<meta http-equiv="refresh" content="0;url=https://stackoverflow.com"/>
Many good answers , I don't know which answer I will accept, Thanks so much
The result is same for all options. Redirect.
<meta> in HTML:
Show content of your site, and next redirect user after a few (or 0) seconds.
Don't need JavaScript enabled.
Don't need PHP.
window.location in JS:
Javascript enabled needed.
Don't need PHP.
Show content of your site, and next redirect user after a few (or 0) seconds.
Redirect can be dependent on any conditions if (1 === 1) { window.location.href = 'http://example.com'; }.
header('Location:') in PHP:
Don't need JavaScript enabled.
PHP needed.
Redirect will be executed first, user never see what is after. header() must be the first command in php script, before output any other. If you try output some before header, will receive an Warning: Cannot modify header information - headers already sent
A better way to set the location in JS is via:
window.location.href = 'https://stackoverflow.com';
Whether to use PHP or JS to manage the redirection depends on what your code is doing and how. But if you're in a position to use PHP; that is, if you're going to be using PHP to send some JS code back to the browser that simply tells the browser to go somewhere else, then logic suggests that you should cut out the middle man and tell the browser directly via PHP.
It depends on how and when you want to redirect the user to another page.
If you want to instantly redirect a user to another page without him seeing anything of a site in between, you should use the PHP header redirect method.
If you have a Javascript and some action of the user has to result in him entering another page, that is when you should use window.location.
The meta tag refresh is often used on download sites whenever you see these "Your download should start automatically" messages. You can let the user load a page, wait for a certain amount of time, then redirect him (e.g. to a to-be-downloaded file) without Javascript.
PHP redirects are better if you can as with the JavaScript one you're causing the client to load the page before the redirect, whereas with the PHP one it sends the proper header.
However the PHP shouldn't go in the <head>, it should go before any output is sent to the client, as to do otherwise will cause errors.
Using <meta> tags have the same issue as Javascript in causing the initial page to load before doing the redirect. Server-side redirects are almost always better, if you can use them.
The first case will fail when JS is off. It's also a little bit slower since JS must be parsed first (DOM must be loaded). However JS is safer since the destination doesn't know the referer and your redirect might be tracked (referers aren't reliable in general yet this is something).
You can also use meta refresh tag. It also requires DOM to be loaded.
window.location.href = 'url';
is beter than
header('location:url');
because the header command is mustly return an error "Warning: Cannot modify header information - headers already sent"
using js window.location.href = 'url';
this is beter
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>';
}
I have a situation like this.
<php>
<redirect the page >
<exit>
<javascript>
<redirect the page again>
I want to have javascript that basicall disables the PHP redirect. So if Javascript is enabled on the browser, the javascript redirect will work, if it disable, the PHP redirect will work. Should I just enclose the PHP code in span and make it invisible? Any ideas?
Addition ok this is not a simple redirect. the form authentication is rather odd. Register.php -> register_submit.php -> Was there an error -> yes go back to register.php (everything is javascript at this point). What I have added is PHP authentication as well so if I see javascript is not enabled, I take the user to register.php *after it does the regular checking of fields *.
PHP is a server-side technology. By the time Javascript even sees what's happened, it's too late.
Short answer, JS can't intercept/block PHP (as long as PHP is being called first).
Order of events:
Client requests page
PHP executes and generates output of page
Browser receives output
Browser begins parsing what was sent by what PHP already spit out.
Remove your PHP redirection and add this in your <head>:
<noscript>
<meta http-equiv="refresh" content="0; http://www.example.com/1" />
</noscript>
<script>
window.location = 'http://www.example.com/2';
</script>
This will redirect to http://www.example.com/1 when javascript is disabled, and to http://www.example.com/2 when it's enabled.
PHP code is executed on the server-side, while JS is client-side. So with that structure the PHP will kick in before the JS is executed. If you want JS to control PHP you need to make use of AJAX to control it.
Also enclosing PHP code in a "span" won't have any effect.
Javascript and PHP do not directly interact (exceptions apply, don't worry about them now :D). The best way to implement this type of interaction between these two disparate languages is to use the query string or cookies.
I think there may be some confusion here about when and how PHP is executed as opposed to when and how javascript is executed. Think of PHP as the factory - the goods are physically produced there. Think of your server as the loading dock, the internet as the shipping company. Your browser is the store, HTML is the shelves; Javascript is the window decorations on the store that sells the merchandise. The window decorations have no affect on the production, the factory can make some window decorations, but it doesn't use them, it just ships them right along with the merchandise for the store to use. PHP is the factory, javascript is the decoration. There are some problems with taking this analogy too literally, but there it is in a nutshell.
You can make the PHP redirect conditional on the presence or absence of a specific query string variable:
<?php
// redirect if $_GET['no_redirect'] is NOT set. Reverse the true/false to invert this rule
$do_redirect = (isset($_GET['no_redirect']) === false ? true : false);
// perform the redirect, if required
if ($do_redirect === false)
header('Location:http://mydomain.com');
?>
Javascript:
window.location = 'http://mydomain.com/?no_redirect=1';
EDIT If you're trying to detect if javascript is enabled, then the best way is for javascript to set a cookie if it is enabled. PHP can then check for this cookie, and if it isn't found then you'll know that javascript didn't get a chance to set it, so it must be disabled (or the user edited their cookies).
Take a look at some code snippets for dealing with cookies in javascript, and check out the documentation for dealing with cookies in PHP.
I'm developing a website, and due to user-input or by other reason, I need to show some error messages.
For this, I have a page named error.php, and I get the error number using $_GET. All error messages are stored in a array.
Example:
header( 'Location: error.php?n=11' );
But I don't want the users to the enter the error code in the URL and see all the other error messages.
For preventing that, I thought I could whitelist the referer page, and only show the error message if the referer is found in my whitelist.
It should be fair similar to this (haven't tested yet ;) )
$accept = false;
$allowedReferer = array (0=>'page1.php', 'page2.php');
if (in_array($_SERVER['HTTP_REFERER'], $allowedReferer )) {$accept = true;}
if ($accept) { $n=$_GET['n'];echo "Error: " . $errorList[$n];}
Is this method good enough to avoid the spy-users?
I'm doing this with PHP5
Thanks
No, it isn't remotely secure: the HTTP Referer header is trivial to spoof, and is not a required header either. I suggest you read this article for an example of exploiting code (written in PHP), or download this add-on for Firefox to do it yourself from the comfort of your own browser.
In addition, your $allowedReferer array should contain full URL's, not just the script name, otherwise the code will also be exploitable from remote referrals, e.g. from
http://www.example.org/page1.php
To summarise: you cannot restrict access to any public network resource without requiring authentication.
Rather than redirect, you could simply display the error "in place" - e.g. something as simple as adapting your present code with something like
if ($error_condition)
{
$_GET['n']=11;
include "/path/to/error.php";
exit;
}
In practice it might be a little more sophisticated, but the idea is the same - the user is presented with an error message without redirecting. Make sure you output some kind of error header, e.g. header("HTTP/1.0 401 Bad Request") to tell the browser that it's not really seeing the requested page.
If you do want to redirect, then you could create a "tamperproof" URL by including a hash of the error number with a salt known only to your code, e.g.
$n=11;
$secret="foobar";
$hash=md5($n.$secret);
$url="http://{$_SERVER['HTTP_HOST']}/error.php?n={$n}&hash={$hash}";
Now your error.php can check whether the supplied hash was correctly created. If it was, then in all likelihood it was created by your code, and not the user.
You shouldn't use an external redirect to get to an error page. How I structure my PHP is like this:
I have a common file that's included in every page, with common functions: handle login/logout, set up constants and the like. Have an error() function there you can pass error information to that will show an error page and exit. An alternative is to use the index.php?include=pagename.php idiom to achieve common functionality but I find this far more flaky and error prone.
If you externally redirect the client (which you obviously need to do sometimes) never rely on the information passed via that mechanism. Like all user input it's inherently untrustworthy and should be sanitized and treated with extreme caution. Don't use cookies either (same problem). Use sessions if you need to persist information between requests.
HTTP_REFERER can be spoofed trivially by those with enough incentives (telnet is the tool of choice there), and shouldn't be trusted.
Error messages should never reveal anything critical anyhow, so I'd suggest you to design your error messages in such a way that they can be showed to anyone.
That, or use random hashes to identify errors (instead of 11, use 98d1ud109j2, etc), that would be stored in a central place in an associative array somewhere:
$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"
Why don’t you just include the error message script? And to get rid of previous output data, use the output control to buffer it and clear it on error:
if ($error) {
ob_clear();
$errorCode = 11;
include 'error.php';
exit;
}
Instead of redirecting to an error page why not include an error page. You can restrict access to a directory containing the php files that contain the error content with .htaccess:
RedirectMatch 404 ^error-pages/*$
and inside the error-pages you can have include-able pages which display errors.
With this method you can be sure that no one can directly access the pages in the error-pages directory yet you can still include them within scripts that are publicly accessible.
If you handle errors before sending headers, you can easily create a function that outputs a basic html page with content, and exit right after it. That way there is no specific need for any other page (apart from the functions page, I guess).
It's as simple as checking if there's a problem, and if there is a problem, just call the function.
I use a function like this that even writes data away when it is called, so I have my own error logs...