Link to home
Start Free TrialLog in
Avatar of sciwriter
sciwriter

asked on

Stop PHP errors revealing path

Now I'm back to using PHP, I realize one of this greatest annoyances that stopped me using it years ago.

Whenever it generates an error, it reveals to the user the ENTIRE PATH to gain access to your account.

This has got to be one of the STUPIDEST, DUMBEST oversigns of the century.

I need a GLOBAL FIX, which will ELIMINATE SHOWING THE PATH ON THE SERVER.

If I cannot get this, I cannot use PHP -- that was my conclusion years ago.

Anyone know how to STOP the PATH portion of the typical PHP error message --

"PHP error in **'my_root/my_account_name/here_hackers/come_hack_my_server/steal_my_account'**"

Talk about DUMB, DUMB, DUMB -- stupider than dumb !!!
Avatar of gruntar
gruntar

You cannot hide only path. When you publish your page add line below to a file that is included at the beggining of all other files.

error_reporting(0);

that will block all kinds of errors except the ones you call with die()...

cheers
Avatar of sciwriter

ASKER

I was hoping to block the PATH ONLY, not the error itself, since they help debug.  Are you sure there is no way to substitute something for the path, or eliminate it?  So to stop the path showing, I have to issue no die() statments, and I cannot even use something like a 404 redirect???  What an incredible oversight !!!
No, I just said that for production server you hide errors for obvious reasons. I didn't say that because there are some errors that cannot be predicted so you cannot know where to put or die()

For advanced error reporting see "Error Handling and Logging Functions" that way you have ability to do whatever you want with errors... http://www.php.net/manual/en/ref.errorfunc.php 

Why would you debug on production server? You should test/debug your application on local server.

cheers
>>This has got to be one of the STUPIDEST, DUMBEST oversigns of the century.

Don't think so; this is somewhat important information for debugging purposes.
What if your application uses 50 other files?
If there's an error, I want to know exactly where it is. I wish errors gave even more detail. :)
To echo what gruntar said, common practice is to turn error reporting off on live environments and just log the errors.
Do you think php is the only web language that does this?

However if you really want to stop this, you can look at set_error_handler()-->http://us2.php.net/set_error_handler
There's a nice example on the page. Basically you create your own function that will handle errors that are encountered, but some errors can not be handled by it(i.e. parse errors); but many can.
Also, one of the parameters sent to your error handler is of course 'filename'. So instead of echoing the whole filename, you could use:

basename($errfile)

which will only show the file, and none of the path.
>> If there's an error, I want to know exactly where it is. I wish errors gave even more detail. :)

IMO hiding directories are important, security reasons.
Thought it would be obvious here I was talking about final production running -- NOT the initial debuging stages.  Two different worlds.  Sint4x, so glad you see this too.

Evidently I wasnt' clear enough.  I KNOW where my files are, I KNOW exactly what the path is -- I don't need this echoed back to me or advertised to the rest of the world -- THAT is what is dumb.  I don't see anything in the two links to just turn off the path.  

Perhaps someone would like to just provide a simple statement that turns off the path on ALL errors on a server.  That is what I need.  The PATH, not the errors.  
>>  I KNOW where my files are, I KNOW exactly what the path is -- I don't need this

Yes, you do an don't know. Here is example...

test.php

<?php
include('file1.php');
include('file2.php');
include('file3.php');

//some more code here
?>

if you run "test.php" you also run all included files. Now, let say that for some reasons some error occur in included file "file2.php".

Now, if PHP wouldn't reveal the file where error occur You would not have a clue in which file you have a bug. This is the reason why you get all that info PHP gives you. I hope it's a bit clearer now.

cheers
here is your error reporting that don't reveal server path..

test.php
<?php

//error_reporting(E_ALL);
error_reporting(0);


function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{

   $errortype = array (
               E_ERROR          => "Error",
               E_WARNING        => "Warning",
               E_PARSE          => "Parsing Error",
               E_NOTICE          => "Notice",
               E_CORE_ERROR      => "Core Error",
               E_CORE_WARNING    => "Core Warning",
               E_COMPILE_ERROR  => "Compile Error",
               E_COMPILE_WARNING => "Compile Warning",
               E_USER_ERROR      => "User Error",
               E_USER_WARNING    => "User Warning",
               E_USER_NOTICE    => "User Notice",
               E_STRICT          => "Runtime Notice"
               );
   // set of errors for which a var trace will be saved
   $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
   
   $err = '<br />';
   $err .= ' <b>' . $errortype[$errno] . '</b>';
   $err .= ' ' . $errmsg;
   $err .= ' <b>' . basename($filename) . '</b>';
   $err .= ' ' . $linenum;

   
   // echo error without paths..
    echo $err;

}

set_error_handler('userErrorHandler');



echo $dsf

?>

few lines above I have "forgot" to add traling ; so error should like ...

Notice Undefined variable: dsf test.php 45

cheers
Thank you gruntar for all the explanations you have put in -- I DO understand why some PHP coders think you need to display the file path -- but I don't want that information to show at all -- once in production.

Perhaps someone would like to just provide a simple GLOBAL statement that turns off the path on ALL PHP errors on a server.  That is what I need.  The PATH turned off, not the errors.

If that is impossible, then I would settle for -- ALL errors supressed -- everything.
I cannot live with intermittent PHP and MySQL errors revealing the path to the account on the server.  
Repeat, I cannot live with it -- once in production.  

Thanks for a brief, working solution  -- hopefully juat a 1-2-line statement.
Sorry gruntar -- I posted before I saw your code  -- Thank you for that code....

Does this code go in each page, or can I put it somewhere more "globally"?

An include, or can I specify it in something like the htaccess?  
>>IMO hiding directories are important, security reasons.
I'm not disagreeing. I'm just saying turn them off and log them on live servers.
Yes, I suppose, it would be nice it there was an error flag that would prevent the path from being displayed.
I guess they think we have enough options.
You can put it in a file that gets included in every file. this code should be first one to execute.

cheers
OK, I  put all your code in a file called errors.php  uploaded it to the server,
Changed the file giving errors to add, at top --     <?php include("errors.php"); ?>
All the errors still show, and I am also getting this additional error --

" Notice Undefined variable: dsf errors.php 50 " 

I put the ; after dsf, but notice, it is not defined above.
Also, since this is a function, do I have to call it in every single php action
if ... else die(errors.php)  -- or something like that?

That would be too much hassle.  I assumed it can replace the standard error handling.
Also, all the warnings on the page are showing the path as well....
gruntar you saved my life!

I always was looking for a way to debug my production server errors!! Now I have complete control over them :)

THank you.
Then please fill me in on getting this working -- as it is not working for errors for me, or for warnings.  Please see my post above...
you must put this code into that file


<?php

error_reporting(0);


function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
{

   $errortype = array (
               E_ERROR          => "Error",
               E_WARNING        => "Warning",
               E_PARSE          => "Parsing Error",
               E_NOTICE          => "Notice",
               E_CORE_ERROR      => "Core Error",
               E_CORE_WARNING    => "Core Warning",
               E_COMPILE_ERROR  => "Compile Error",
               E_COMPILE_WARNING => "Compile Warning",
               E_USER_ERROR      => "User Error",
               E_USER_WARNING    => "User Warning",
               E_USER_NOTICE    => "User Notice",
               E_STRICT          => "Runtime Notice"
               );
   // set of errors for which a var trace will be saved
   $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
   
   $err = '<br />';
   $err .= ' <b>' . $errortype[$errno] . '</b>';
   $err .= ' ' . $errmsg;
   $err .= ' <b>' . basename($filename) . '</b>';
   $err .= ' ' . $linenum;

   
   // echo error without paths..
    echo $err;

}

set_error_handler('userErrorHandler');

?>

No problem sint4x, glad I could help :)
gruntar --

I have put your new code into a file called -- errors.php -- in the <BODY> section.

In the top of filename.php  I have put --
<?php
include("errors.php");
.......
?>

I am still getting tons of warnings and errors, like --

Warning session_start(): Cannot send session cookie - headers already sent by (output started at /home/path/public_html/filename.php:7) filename.php 44
Warning session_start(): Cannot send session cache limiter - headers already sent (output started at /home/path/public_html/filename.php:7) filename.php 44
Warning Cannot modify header information - headers already sent by (output started at /home/path/public_html/filename:7) filename.php 45
Warning end(): Passed variable is not an array or object filename.php 55

Don't worry about the meanings of the errors -- I just want to eliminate them....
Obviously I am not doing something right
What BODY?!

Put only PHP code that I have posted in last post NOTHING else!!!

cheers
I did that, it made no difference.

As I said, your file declares a function -- where do I call this function?
I am not calling any function -- only:    include "errors.php"   -- in the other file.

Seems to me a function has to be called, unless this replaces PHP's global error reporting.

I am increasing points for all the effort you have put in, but it is still not working.
Something simple, no doubt.
Well, yes you DON'T call that function, PHP does.

set_error_handler('userErrorHandler');
this line tells PHP to use your function to show errors.

Have you copyed whole code?
yes gruntar, exactly as you have it.  Since I am not a PHP expert, it is probably something real simple.  I don't doubt the correctness of your code, I would suspect I am missing something that might be "obvious" to you...

In the other file, I tried --

include("errors.php");

with and without the brackets, made no difference.  I even copied your latest code again, and re-upoaded that errors.php to the public_html directory.  There is nothing in it but your code.

server stats --

Apache version  1.3.33 (Unix)        
MySQL version      4.0.22-standard      
PHP version      4.3.10

Sorry for the problem, but I really need to get these errors out of the way, so I can see what I am doing ....
Based on info you have posted seems OK. I can tell you more only if you paste the code...

errors.php is EXACTLY your code -- checked it 3 times

otherfile.php is as follows (simplified, to not clutter this question) --

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE></TITLE>
</HEAD>
<BODY>
....some HTML tables here

<?php

include ("errors.php") ;

session_start();
header("Cache-control: private");                                     // IE 6 Fix.
if (!session_is_registered('divs')) { session_register('divs'); }

// there is a whole bunch more code relating to displaying session information, none relevant to the errors
//because the errors relate to the above code, but they are typical PHP errors (see above). Example code --
  echo "<DIV id='" . $key . "'>Description: ". $_SESSION['divs'][$key]['title'] . "</DIV>";

?>

.... more HTML tables here

</BODY>
</HTML>
SOLUTION
Avatar of gruntar
gruntar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Marcus Bointon
Marcus Bointon
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you squinky, that simple statement is what I was looking for all along !!!

I was using error reporting(0) to stop them, so I could move ahead with debugging, and I will change that to your suggestion.

Since yours is the right answer -- but gruntar put in so much effort with his code (that I still could not get to work) -- If it is OK with you both, I will split points evenly.

Thanks again squinky -- check my other posts, could use your help.