Seldaek / php-console

PHP Debug Console
Other
529 stars 93 forks source link

Allow site to load if HTTP authentication is successful #8

Closed enderandpeter closed 10 years ago

enderandpeter commented 11 years ago

I noticed how the user is redirected to an error message if the site is not launched from localhost. Perhaps we should provide a way to allow this site to be used on a remote server provided that it is in a directory requiring HTTP authentication?

According to PHP's page on HTTP authentication, $_SERVER['REMOTE_USER'] should be set if external authentication (from a .htaccess file or what have you) was needed to reach the page and $_SERVER['PHP_AUTH_USER'] should be set if PHP's HTTP authentication methods were used.

Let me know what you think...

Seldaek commented 11 years ago

As far as I understand $_SERVER['PHP_AUTH_USER'] just means a user was provided, it doesn't seem to guarantee the password was valid or anything. $_SERVER['REMOTE_USER'] seems a bit safer, but please use !empty() instead of isset() because if it just happens to be set to an empty string for any messed up reason granting access could have quite bad effects.

staabm commented 11 years ago

you could also trigger a BASIC AUTH using plain php if the no authentication took place before: http://www.php.net/manual/en/features.http-auth.php

enderandpeter commented 11 years ago

I do agree that checking for an empty string is a good plan. Here's what I've found out so far:

On the one hand, I'm thinking it would be good to rely on $_SERVER['REMOTE_USER'] being set and not empty. According to this StackOverflow thread this value should be provided by the server handling the authentication/authorization. Although the discussion does not specifically talk about $_SERVER['REMOTE_USER'], it seems to suggest that 'REMOTE_' values were "verified by a TCP/IP handshake". This should not be set if there was no HTTP auth. I'm aware that there is also $_SERVER['AUTH_TYPE'], but it appears this should be set if $_SERVER['REMOTE_USER'] is, and the StackOverflow discussion seems to suggest that $_SERVER['AUTH_TYPE'] may be slightly more spoofable.

Now, if you initiate authentication by way of something like header('WWW-Authenticate: Basic realm="My Realm"'), authentication could either be handled entirely by PHP, or the web server could still get involved by imposing rules on the realm in a certain directory, and so forth. If the result is authentication/authorization, then $_SERVER['PHP_AUTH_USER'] will be set, but $_SERVER['AUTH_TYPE'] and $_SERVER['REMOTE_USER'] will not be set.

Another option would be to see if the array returned by apache_request_headers() contains a key called 'Authorization', which should be the case if either the web server provided the auth or if you use header(). However, this function may not be available, or give meaningful data if you're using something other than Apache. It is definitely not available if PHP runs on CGI.

But maybe both could be used in something like this:

/* 
php-console will only load if it is either launched from localhost or if the request
was HTTP authorized.
*/
if(isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])){
    // The remote user is authorized
    $httpAuth = true;
} else if(function_exists('apache_request_headers') &&
            array_key_exists('Authorization', apache_request_headers())){
    // The Apache Web Server acknowledges authorization
    $httpAuth = true;
} else {
    // The request does not appear to be authorized
    $httpAuth = false;
}

if (!in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'), true) && !$httpAuth) {
    header('HTTP/1.1 401 Access unauthorized');
    die('ERR/401 Go Away');
}

This test, however, would not allow a user whose authentication was initiated with a call to header() where the web server is not Apache, but they should be good if the authorization method includes setting $_SERVER['REMOTE_USER'].

What say you? Thanks a lot for the response!

staabm commented 11 years ago

would be best you commit the changes, this would ease adding comments to the code...

simplify

if(isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER']))

to

if(!empty($_SERVER['REMOTE_USER']))

to ease readability I would set $httpAuth = false; at first before the if.

enderandpeter commented 11 years ago

It looks like after updating ACE, syntax highlighting no longer works. I'm racking my brain trying to figure out why. For me, importing the ace.js file from the Internet like in their example doesn't even load the js file. But I'm just using the files in the ace folder right now, and no call to editor.getSession().setMode() is actually setting the mode... I might start another branch to help...

Seldaek commented 11 years ago

Indeed, not sure what happened with the highlighting. If you figure it out feel free to send a pull request.

enderandpeter commented 10 years ago

Hi, everybody—to quote Dr. Nick. I've been away for a bit, but I thought I'd come back to this awesome project.

So, I think I made a mistake in how I made this pull request. I should have simply created another branch to be merged into the master, so that it would be clear what changes I was proposing. I'm going to close this request and make a new, cleaner one.