5

Visiting all of the following sends you to the login screen:

http://mysite.com/admin/configuration.php
http://mysite.com/admin/login.php

However if you visit (note the last two portions of the url string are both .php):

http://mysite.com/admin/configuration.php/login.php

You can see the configuration screen and all of its data!

Further, if you append some GET variables you can even get editable fields:

http://mysite.com/admin/configuration.php/login.php?cID=1&action=edit

What is going on here?

I should note that this is on site using an absolutely horrible shopping cart called oscommerce. The code is a nightmare to deal with but I am stuck with it for now.


EDIT

A fix based on vstm's excellent and accurate comment below:

This would go just before the check to see if $current_page != FILENAME_LOGIN (around lines 141-143 in /admin/includes/application_top.php). Mind you this is just an emergency patch as the real solution is to never use oscommerce as it is about as secure as a hooker's belt.

//$current_page = basename($PHP_SELF); //this is the default
$current_page = basename($_SERVER['SCRIPT_NAME']); //change that default to this

if ( ($current_page == FILENAME_LOGIN) && !tep_session_is_registered('redirect_origin') ) {
      $current_page = FILENAME_DEFAULT;
      $HTTP_GET_VARS = array();
    }

If anyone tries this don't forget that the redirect_origin session var might already be set so this will appear to not work. Just unset it and try again.

3 Answers 3

16

In the includes/application_top which gets included by all the scripts in /admin you'll find this little gem (I have thrown some uninteresting parts out):

// redirect to login page if administrator is not yet logged in
if (!tep_session_is_registered('admin')) {
    $redirect = false;

    $current_page = basename($PHP_SELF);

    if ($current_page != FILENAME_LOGIN) {
        // session stuf blabla
        $redirect = true;
    }

    if ($redirect == true) {
        tep_redirect(tep_href_link(FILENAME_LOGIN));
    }

    unset($redirect);
}

This code gets only executed when you are not logged in. What it basically does is check if the basename of $PHP_SELF is login.php. If it is login.php then it proceeds rendering the page, otherwise you will be redirected.

If you make this request:

http://mysite.com/admin/configuration.php/login.php

Then the PHP_SELF will be

/admin/configuration.php/login.php

And basename($PHP_SELF) will of course be login.php thus the rendering continues and no redirect is executed. But it is of course not login.php which gets rendered but configuration.php. The rest of the URL "/login.php" is "ignored" and just supplied to PHP in $_SERVER['PATH_INFO'].

Edit: I like to add that this "bug" affects only oscommerce or any other software that uses a solution like that to "secure" the administration login (I think there aren't that many which suffer from this). It is not a bug which affects all PHP-software.

3
  • Nice example, +1. Aug 11, 2011 at 18:02
  • Yep. I just found this myself. My fix is up as an edit to my original comment. Aug 11, 2011 at 18:09
  • Thanks for the response. I think you could also replace $PHP_SELF with $_SERVER['SCRIPT_FILENAME'] this should also do the trick, since it contains the path of the real php file which is actually executed (in your example it would be /filesystem/path/to/your/admin/configuration.php).
    – vstm
    Aug 11, 2011 at 18:32
3

This is simply a vulnerability in the configuration.php file - the 'fake directory' thing with a php file as part of the path is an intentional feature and something that you'll see often - how the stuff after the slash is handled is up to the php file in the path. (mediawiki comes to mind as a good example)

1

I have tried this on a windows box, to use a double url as indicated - it says page not found. But the server is set not to allow directory transversals and OSCommerce is set to check user agent and prevent spider sessions as well as use a sessions directory - possibly this is why it is secure and does not allow appending a url. Additionally, the server treats the /login.php as part of the first filename, does not allow driectory transversals and does not allow dot in a filename - hence it refuses the url entirely. Therfore secure because the server is secure regardless of what the catalog software tries to do.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .