We are trying to secure a large application (including some third party applications) and we want to disable anything that would allow programmers or potential hackers to hide errors (that is because we are using some monitoring scripts to check the logs in real time and identify any security breach).
We have disabled error_reporting, ini_set (along with some other functions); we have also installed php extension scream to disable suppression operator (no errors are displayed to the user but everything is logged)
We are now looking for a solution to set the default php error_handler server side (instead of using set_error_handler as we do now)? We want to use a custom error handler (for a better logging of the error environment) but we do not want to allow anyone to suppress errors using set_error_handler function.
So basically we can either disable this function (and make sure that all errors will be logged by the default handler) or maybe find a solution to set this server side (maybe an extension or some other trick) for better logging.
Any idea would really help!
UPDATE
We're using Apache with mod_php so we cannot use [PATH] to disable_functions for a certain script. Changing this is not exactly an option.
You can try to use a prepend script which runs before each request
php_value auto_prepend_file prepend.php
In this script you can set the error handler:
<?php
set_error_handler('yourHandler');
/* EOF */
And give only this script the right to use the set_error_handler() function.
Related
We want to monitor all php errors. We can check all errors with error_log file.
Error logs files become so heavy.
So it is very difficult to check errors in error_log file.
Could it possible to write php error_log file on date-wise example '19-05_2015_error.log'
or we can write error like "fetal.log" "notice.log"
You can absolutely do it in PHP. A popular logging library is Monolog.
You can change the PHP config at beginning of your application, create the log file dynamically.
<?php
function logByDate(){
$sPath = '/logs/application/PhpError_' . date('Y-m-d') . '.log';
ini_set('error_log', $sPath);
}
// To validate only, it is not necessary
echo 'Actual log ' . ini_get('error_log') . PHP_EOL;
logByDate(); //Call it at beginning
// To validate only, it is not necessary
echo 'Validate new log ' . ini_get('error_log') . PHP_EOL;
To get logs in daily format (19-05_2015_error.log) you can use logrotate if you're on a UNIX stack (but it' a bit more complicated if you're on a Windows stack).
There are some useful hints on controlling duplication and suppressing error messages.
As far as I know, the mod_log_config module does not accept variables for file names so that excludes the most straightforward possibility. Apache-based solutions you can actually use include basically:
Send logs to a script and let the script choose the file name.
Good old log rotation.
Said that, I think PHP has pretty good built-in logging. You can do exactly what you are asking for with the error_log() function (together with e.g. date('Y-m-d')). You can even define a different file for different error types. Sure, that will not capture errors that prevent PHP code from running (such as parse errors, request time-outs...) but you can set the error_log directive as fallback mechanism—these situations should be rare enough to keep the log file manageable.
One more thought: make sure your development box has full error reporting enabled (many devs use third-party bundles with default settings and happily write buggy code). It isn't normal to have so many logged errors in a production server.
CodeIgniter 2.x still uses the classic mysql. We all know it's bad practice to still use it, but my job still requires me to use CodeIgniter.
I always have my Console.app (OSX) open watching my Apache/MySQL/PHP/CodeIgniter-native error logs.
Now I mostly have all notices/errors/etc. fixed always instantly when I see them and constantly monitor my development with Webgrind on my MAMP.
Back to the start; I constantly have one big annoying thing each page-load PHP always gives the error about mysql_pconnect is going to get deprecated in the future.
In the CodeIgniter driver the command is suppressed by # to not print the warnings to the screen, but it still ends up in my logs.
Is there any viable way to except one such error specifically in either PHP code or the PHP settings?
Locally I could recompile the whole PHP core and just remove the warning, but I would like to have the logs on our production installations rid of those warnings too :P.
Thanks in advance!
Traditionally, you can use set error verbosity using error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED) (i.e., report everything—except notices and deprecation warnings) as mentioned in "disabling deprecated errors".
Your issue may be related to CodeIgniter taking ownership of all errors.
system/core/CodeIgniter.php calls the function set_error_handler. You can find and modify the function _exception_handler it invokes on error in system/core/Common.php. It doesn't appear to be a configurable, so you may simply want to edit the line that begins with $is_error.
How can you log to web server's log ( error_log() ) using log4php? I think what this ultimately means is to have a log appender that logs to error_log(). Seems like a no brainer, but I couldn't find anything in the log4php documentation and I couldn't find anything online about someone already doing this... Is this something that's easy to do and I'm just missing it?
I haven't found such an appender either. Seems like there is no such thing. You'd probably be best of if you are using the FileAppender and give it the name of the error_log ini setting if that is a filename.
If the error_log directive is set to syslog, there is a SyslogAppender.
Note however that the error_log() function itself has a target parameter that most of the time is identical to what dedicated appenders already provide. With the added uncertainty of where the error messages really end up depending on configuration, I feel it's a better idea to leave it up to the Log4PHP configuration. Sending mail, logging to a file, logging to syslog: All already supported. The only case missing: Logging to the SAPI logging handler.
Is it possible to configure php.ini to store errors in MySQL database rather than plain error-log?
The only option that I see is using php.ini to append file containing custom error handling function to every PHP script. Though, this doesn't sound efficient.
This is more of a server level question, if you don't like the answer that Frankie provided in his comment. Without using set_error_handler there is no way (in PHP) to output all errors to a log file instead of the log.
If you are using Apache, you can do the following:
CustomLog "|/path/to/custom_log_script.php [OPTIONS]"
(note the pipe)
That will allow you to use a custom error log handler to control what does and doesn't wind up in the log files.
You can set a cron job to execute a php script read the error log file for new errors and store them in the database. The error log table won't be real time though but I think it shouldn't be too big a problem.
I was wondering if anybody knew of a method to configure apache to fall back to returning a static HTML page, should it (Apache) be able to determine that PHP has died? This would provide the developer with a elegant solution to displaying an error page and not (worst case scenario) the source code of the PHP page that should have been executed.
Thanks.
The PHP source code is only displayed when apache is not configured correctly to handle php files. That is, when a proper handler has not been defined.
On errors, what is shown can be configured on php.ini, mainly the display_errors variable. That should be set to off and log_errors to on on a production environment.
If php actually dies, apache will return the appropriate HTTP status code (usually 500) with the page defined by the ErrorDocument directive. If it didn't die, but got stuck in a loop, there is not much you can do as far as I know.
You can specify a different page for different error codes.
I would assume that this typically results in a 500 error, and you can configure apaches 500 handler to show a static page:
ErrorDocument 500 /500error.html
You can also read about error handlers on apaches documentation site
The real problem is that PHP fatal errors don't cause Apache to return a 500 code. Errors except for E_FATAL and E_PARSE can be handled however you like using set_error_handler().
There are 2 ways to use PHP and Apache.
1. Install PHP as an Apache module: this way the PHP execution is a thread inside the apache process. So if PHP execution fails, then Apache process fails too. there is no fallback strategy.
2. Install PHP as a CGI script handler: this way Apache will start a new PHP process for each request. If the PHP execution fails, then Apache will know that, and there might be a way to handle the error.
regardless of the way you install PHP, when PHP execution fails you can handle errors in the php.ini file.