Security problem with history button

fomalhaut

Member
Messages
107
Reaction score
0
Points
16
Hello.

The first page of my web site (php, html, javascript) is for public consultation, but there is a form which permits administrators to sign on (with user and password).

When an administrator is signed on, he has a bigger menu, and so he can manage users and others things. That works fine - thank you x10-forum -

When the administrator has finished his work, he returns to the first page and disconnect himself (signs out). Or if he omits that, there is a delay and his disconnection is forced. All that works fine too - and thank again to the people of this forum.

BUT... if I use the back button (history), I can re-display the complete administrator's menu, and do as if I was himself !

Is it possible to forbid the critical pages be written on history ?
Or are there other solutions ?
Or am I obliged to ask the administrator's 'password on each page he has to work ?

Thanks for your help.
 

Twinkie

Banned
Messages
1,389
Reaction score
12
Points
0
Assuming that the page is already secured and the 'attacker' cannot do anything with the page cache without forcing a page reload (in which the sign in page would be displayed), there is not much to worry about security wise. However, it does send the wrong message to allow a user to do this. There are no-cache meta tags that force a browser to reload every time.
Code:
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="-1">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
Add these to your page in the head tag. Descriptions of each one can be found here. This simply lists all of them, they may not all have to be used.

If you did not secure every page, then it helps to create a login script and use an include statement to include it on every protected page. It is very insecure to have a login page, and then leave the rest of the admin panel unprotected. Robots will quickly display those pages in search engines, and if you block the robots, malicious users can see the 'protected' pages listed withing the robots.txt file.
 
Last edited:

slacker3

New Member
Messages
146
Reaction score
6
Points
0
slightly off-topic:

robots.txt is a fine place to punish stupid script kiddies - i love this file :biggrin:

mine looks like this:
Code:
User-Agent: *
Disallow: /adminpanel.html
Disallow: /mypasswords.html
Allow: /

now, if some wannabe hacker opens http://josef-steppan.co.cc/adminpanel.html... :lol:
(attention, this may crash your computer)
 

fomalhaut

Member
Messages
107
Reaction score
0
Points
16
Hello guys.

Firstly, thank you for your answers.

Twinkie said:
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="-1">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
That's what I've added in the head section of my html page, when the user is connected. But, that doesn't work, the back button still displays the page I don't want. And if I do "show the source code" for that page, it has really the three lines above in its head section !

And I ask me other questions. Perhaps I havn't understood all because beeing french man, English isn't my natal language :
Twinkie said:
Assuming that the page is already secured...

How can I be sure my page is secured ? What do you mean exactly ? Is there something particular to do on the server ? I have not used .htaccess file, ignoring how it works exatly ; should I write something in it ?

Last point : what about robots.txt file ? I didn't know it ?

Thanks for your help. :nuts:
 

Livewire

Abuse Compliance Officer
Staff member
Messages
18,169
Reaction score
216
Points
63
How can I be sure my page is secured ? What do you mean exactly ? Is there something particular to do on the server ? I have not used .htaccess file, ignoring how it works exatly ; should I write something in it ?

I think what he means is something I'm having problems doing on my own projects mostly due to lazyness: if it's -truly- secured, it basically means every action anyone takes (especially mods/admins) is double-checked to make sure they're actually a mod/admin AND logged in; that'd basically just mean before doing any action, check all the data you can against that user and make sure it's really them.

Cause then if it's not, oh well. Somehow they found the link, but it won't do them any good when the system knows it's not them and keeps disallowing the action :)
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
How can I be sure my page is secured ?
Before outputting anything, check that the visitor is authorized to view the page. If not, redirect them to a login page, including the URL of the protected page as a query parameter so the login script can redirect back to the original page. If you do it right, redirection should also prevent your problem.

For example, at the start of every page that needs protection put:
PHP:
<?php
include_once('../init.php');
include('auth.php');
protect(...);
?>
where the argument to protect() can be nothing (to give everyone access), an array of groups, or an array of groups & an array of users.

In include/auth.php (among other functions):
PHP:
/* login(): Attempt to login the user (if necessary). 
returns: true on success, false if login fails (user doesn't have a login session 
& can't get a login session). If a login session already exists, login is successful. 
*/
function login() {
    if (! isset($_SESSION['user'])) {
        ...
    } else {
        if ($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
            /* Session hijack. Don't logout, because this will destroy the 
             * session for the real user.
             */
            destroy_login_cookie();
            return False;
        }
        return True;
    }
}
/* logout(): Destroys the session to logout */
function logout() {
    $_SESSION = array();
    if (ini_get("session.use_cookies")) {
        destroy_login_cookie();
    }
    session_destroy();
}
/* authed: return true if user is authorized to view page, which is determined
by checking if user is member of one of the specified groups. Alternative is
to store authorization information (page => authorized users & groups) somewhere 
and refer to that.

  Params--
$groups: array of group names that are allowed access
$users: array of user names that are allowed access
 */
function authed($groups=array('everyone'), $users=array()) {
    return login() 
        && (   $_SESSION['user']->isInGroup($groups) 
            || $_SESSION['user']->isIn($users));
}

function protect($groups=array('everyone'), $users=array()) {
    if (! authed($groups, $users)) {
        header("Location: $_SERVER[APP_ROOT]/login?redir=" . urlencode($_SERVER[REQUEST_URI]));
        exit();
    }
}

function destroy_login_cookie() {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', 1 /* expire at 1 second past epoch */,
              $params["path"], $params["domain"],
              $params["secure"], $params["httponly"]
    );
}
You can also place the above functions in a class to allow the authorization system to be easily changed.
PHP:
interface Authorizer {
    public function login();
    public function logout();
    public function authed($groups=array('everyone'), $users=array());
    public function protect($groups=array('everyone'), $users=array());
}

init.php sets up the include path and starts the session:
PHP:
<?php
if (!function_exists('addToIncludePath')) {
  function addToIncludePath($path) {
      $currIncPath = ini_get('include_path');
      if (!preg_match('#(^|:)'.preg_quote($path, '#').'(:|$)#', $currIncPath)) {
          set_include_path(get_include_path() . ':' . $path);
      }
  }
}

$_SERVER['APP_BASE'] = dirname(__FILE__);
addToIncludePath($_SERVER['APP_BASE'] . '/include');
/* add other directories to include path, if any */
...
/* include configuration settings */
include('conf.php');
$_SERVER['APP_ROOT'] = $conf['app_root']; // defined in include/conf.php

/* include any classes that might define objects be stored in $_SESSION before calling session_start() */
include_once('User.php');
...
start_session();
...
?>

Much needs to be filled in, such as the login() function, the User class and the login page. You can work in login/logout forms and actions as you see fit. The way you check for a user's membership in a group will need to be rewritten if users don't track that information.

I have not used .htaccess file, ignoring how it works exatly ; should I write something in it ?
There are two things you can configure in .htaccess that might apply: mod_auth (to use the web server for authentication, which won't be compatible with your user system) and mod_access (to protect files and folders from being accessed by anyone). The latter will be of particular use to prevent visitors from accessing page fragments & included scripts. In the "include" directory, as well as any directories containing views, actions &c., put an .htaccess with:
Code:
Deny from all
Order allow, deny
This will deny all direct access via HTTP requests, though scripts can still access the files locally.
 
Last edited:

fomalhaut

Member
Messages
107
Reaction score
0
Points
16
Hello

I've made a lot of modifications.

I moved all my include files in a directory "inc". I've created in this directory a .htaccess file that contains:

Code:
Deny from all
That seems to work.

When an admin user is connected and call a menu page such as "Gestion des utilisateurs" i.e. "user's management", I've had a page that asks him his password to confirm who he really is (that prevents from the back button) - as exposed by Livewire (thanks). If the user is really this admin, then I make an include of the real management page ! That's good... but...
This page has forms and redirects itself but not by "include". And that doesn't work ! With the .htaccess file, I can't load any script that is not an "include page" ! How can I do ?

Code:
Deny from all
Order allow, deny
misson said:
This will deny all direct access via HTTP requests, though scripts can still access the files locally.
I've had try this. Effectively, direct access is no more possible... but scripts can never catch the files in this directory, unless for include. I don't undestand why ?

I seem to be blocked by this problem I don't master !

Can you please help me again ?

In fact, that I would like to have is a directory containing includes and other scripts or html pages, and in this directory, noone can see nor execute nor load any file, but scripts that are in the root directory can include or execute...

Thank again for your help.;)
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
What, exactly, is the issue? As I understand it, here's where things stand: Scripts in the "inc" directory cannot be accessed directly by a browser (e.g. "http://fomalhaut.x10hosting.com/inc/auth.php" is forbidden) but can be included by other scripts, which is as it should be. Some of the scripts redirect to... where, exactly? Scripts in "inc"? By design, only certain scripts are entry points. The other scripts, such as the ones that define classes and functions, are protected from direct browser access. You should redirect only to entry points.
 

fomalhaut

Member
Messages
107
Reaction score
0
Points
16
OK Misson

I've found my errors : only includes can be in the protected directory ! And I have worked now in this direction. It's all ok now. It's works fine.

misson said:
You should redirect only to entry points.
That was my error : I had not redirect only to entry points ! That is now corrected.

Sorry for the time I make you lost !

And thank you again.
 
Top