Page 1 of 1

in system validation design

Posted: Thu Jul 03, 2003 4:06 am
by Heavy
Say you have a php script:

Code: Select all

<?php
define('IN_MY_SYSTEM',1);
include "someclass.php";
$obj = new someClass;
$obj->printHello();
?>
and the someclass.php:

Code: Select all

<?php

//in system validation:

if (!defined('IN_MY_SYSTEM')) die('Bye!');

class someClass{
    var $Tjopp;
    function someClass(){
        $this->Tjopp = 'Hello!';
    }
    function printHello(){
        echo $this->Tjopp;
    }
}
?>
I saw it works well to do the validation like this instead:

Code: Select all

<?php
defined('IN_MY_SYSTEM') or die('Bye!');
?>
Since it is so short, I like it. But since there is an expression whose result is not saved, I wonder if you great guys think I'm getting myself into trouble...

Any suggestions on better ways of doing it?
Any traps that you might fall into by coding it the latter way?

Posted: Thu Jul 03, 2003 8:52 am
by BDKR
It doesn't seem a very elegant way of dealing with an issue. Does the user just see 'Bye!'?

What exactly is this to be used for?

Cheers,
BDKR

Posted: Thu Jul 03, 2003 9:05 am
by Heavy
Clarification:
The "bye!" is just a string. It is never meant to be seen. Could be just anything more apropriate and polite.

"Bye!" only shows if someone tries to browse "someclass.php".
EDIT: And they should not browse it, since it is supposed to be included by other PHP files. /EDIT

What I was posting about was that I do an expression:

$bool1 or functioncall();

without storing the result:

$result = $bool1 or functioncall();

And the second question was:
How do YOU validate that the script is running included correctly to protect whatever sensitive code from beeing executed?

Posted: Thu Jul 03, 2003 9:29 am
by nielsene
Well, I stick all my "sensative" files outside the web tree, so the webserver can not serve them.

Ie
I'll have class files and configuration files in /usr/local/projectname/include/ under a classes/conf subdirectory. I'll have the viewable webpages in /usr/local/projectname/www which is aliased into the webtree in the httpd.conf file. So why php has read rights to the include files, apache can not navigate to them directly.

Posted: Thu Jul 03, 2003 11:13 am
by BDKR
Heavy wrote: What I was posting about was that I do an expression:

$bool1 or functioncall();

without storing the result:

$result = $bool1 or functioncall();

And the second question was:
How do YOU validate that the script is running included correctly to protect whatever sensitive code from beeing executed?
I'm sorry for being confused. That does clarify it a bit.

I'm not sure about the expression you're using. I've never used anything like it to be honest. Frankly, it reminds me a bit of a ternary operator. And the ternary operator is exactly what I would've used.

Code: Select all

$result=$bool1 ? '' : functioncall();
As for how do I (as I understand the question) check that all include or required files have been included or required, I don't. The reason I don't is because once a script is written and the includes start working, that part remains fixed. The good thing about checking for this kind of thing is that you can recover gracefully.

However, checking for this only works with include() as it will emit a warning in the event of failure and continue with the script. If require() fails, the script aborts immediately.

This worked for me...

Code: Select all

<?php
if(@include('args.php'))
	{ echo "good\n"; }
else
	{ echo "no joy\n"; }
?>
The ampersand (@) will suppress the warnings.

As for actually browsing the code, that shouldn't be possible. If a person figured out the path to a file that had nothing but function and class definitions, then all that would happen is the user would see a blank page. Back in the days of yore, those dark php3 times, people used to name their includes somthing.php.inc or something.inc. The problem there was that apache would treat these files like text and dump everything out to the screen.

Not good.

But people shouldn't know the names of your included lib files anyways right. And they better not have a way to view them. Make sure the web server doesn't allow directory listings. Also go one step further and create index files that redirect people back to the home page or something. That's what I do for image directories.

nielsene's method of putting things outside of the web is very good one too.

So...., I don't know if this is what you were looking for, but I hope it helps somewhat.

Cheers,
BDKR

Posted: Thu Jul 03, 2003 4:01 pm
by Heavy
Well I guess I could clarify things a bit further.

If you code bad, like I realise I have been doing, (I have spent almost every day and evening of the last two weeks reading about code design and such) you might happen to do things in an include script without triggering it with a call from the surrounding script (is there a term for that?). If these actions perform anything that has to do with POST or GET data, things (database) might get trashed up. Instead of spending time to set up rules about where POST & GET comes from, what things they contain and all that, I have been lazy and made an in system validation procedure at the top of each include.

Yeah, I know. If nothing is performed at include time, there would only be a blank page for the user. Correct and a better design.

And, Yeah, I know, sensitive stuff should go outside the web directory. But when making a distributable php application one might choose a more convenient (lazy) way to place certain include files. (I can feel it coming... don't hit me!).

This kind of checking from within the include file itself whether the include has been performed correctly is also done in phpbb. Check it out. There is where I saw that kind of validation the first time, and since it was so simple I liked it. If the constant is not defined, execution aborts before doing anything.

By replacing
if (!isdefined('IN_MY_SYSTEM')) exit;
with
isdefined('IN_MY_SYSTEM') or exit;
one can shorten it down a bit.
By reading BDKR's reply posts I see that this kind of coding is a little special. Maybe I am doing something so unusual that poeple think there is something wrong with that code when they read it. But I like the very short form of validation. I am asking you:
Can it get shorter?
Are there any technical reasons why I shouldn't do it? (hidden system errors that takes time or something. I guess you really have to know the Zend engine well to be able to answer this question.)


Every time you use a function that returns a value without using its result, you do what .... Let me show you with some examples:

Code: Select all

<?php
function echoAndReturnVal(){
    echo "funny feeling!";
    return rand(0,100);
}

// here, we call function that returns value. But we don't care about the result. 
// Thus, the returned value just "disappears".
echoAndReturnVal();

//and here, we do kind of the same thing, except for that a lonely variable is not executing anything
$aVariable;

//since boolean evaluation goes from left to right the following is true for the following expression:
$bool1 or functioncall();
// if $bool1 is false, the "or" causes the program to also evaluate functioncall(), wich can perform any action, including "exit;"
// but if $bool1 is true, the program does not look at what's to the right of "or".

//Thus!

isdefined('IN_MY_SYSTEM') or exit;
//...causes the include file to exit if that constant is not defined.
// So, the constant needs to be defined before the include script is included.

?>

Posted: Fri Jul 04, 2003 8:20 am
by BDKR
When you get right down to it, it's not needed.

If all you are worried about is someone viewing your files that are nothing but class and / or function definitions, just make sure there is a .php extension on the end of the file. Therefore, this...

Code: Select all

<?php 

//in system validation: 

if (!defined('IN_MY_SYSTEM')) die('Bye!'); 

class someClass{ 
    var $Tjopp; 
    function someClass(){ 
        $this->Tjopp = 'Hello!'; 
    } 
    function printHello(){ 
        echo $this->Tjopp; 
    } 
} 
?>
...can be changed too....

Code: Select all

<?php 
class someClass{ 
    var $Tjopp; 
    function someClass(){ 
        $this->Tjopp = 'Hello!'; 
    } 
    function printHello(){ 
        echo $this->Tjopp; 
    } 
} 
?>
When you run it through the server, all you'll see is a blank page.

However, if you want to make sure that something was included that is needed for proper functioning of the script, then I suggest the example I gave in the last post as it gives you an option of controlling what you do as opposed to just dropping dead on the spot.

This isn't saying your code is bad. It's just not allways expedient to add solutions where solutions aren't needed. :wink:

Cheers,
BDKR

Posted: Fri Jul 04, 2003 11:18 am
by Heavy
BDKR wrote:It's just not always expedient to add solutions where solutions aren't needed. :wink:
Agreed.