In production environment should errors be disabled?

Asked

Viewed 650 times

11

I saw that errors generated in production environment result in major problems, especially when you have an application related to money and/or passwords, but also due to the privacy of information.

  • In production environment, everything already hosted, working with real people, the generated errors should be disabled? Through the command:
<?php
error_reporting(0);
ini_set(“display_errors”, 0 );
?>

Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?


As stated in the commentary, exactly

  • How could I not display the error message but create logs error, then redirect the user to the previous page, stating "Error occurred"?
  • 2

    In production it is best not to display any error messages or information about the system/technology/framework/platform etc to provide no detail to a possible attacker.

  • 2

    I don’t think you can show potentially dangerous information, but that doesn’t stop you from having well hidden and descriptive error logs :)

  • @Guilhermebirth you ask about: Is it necessary to use ini_set('display_errors', 0);? Is error_reporting(0) not enough? while I wonder if: Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?

  • You ask about functionality, while I ask about theory, it’s not the same duplicate question

  • You marked the question as duplicate, so I went to see what was duplicated from the other question, and there you ask about: Is it necessary to use ini_set('display_errors', 0);? error_reporting(0); is that not enough? while I wonder if: Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?

  • All right, thanks again

  • I was just saying that I think the question doesn’t seem duplicated once you ask about ini_set functionality and error Reporting, while I ask about theory: "Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?" and later I made an Edit incrementing: the question "exactly how could I not display the error message but create error logs, then redirect the user to the previous page by stating "Error occurred"?" it doesn’t seem the same double question

  • Maybe your other question might even look like a "related", but in my view, not as duplicate

  • 1

    @Sauldasilvarolim see edition http://answall.com/a/195941/3635 I also reopened the question.

  • 1

    When the programmer is creating the system in Local server, it is necessary that the errors are enabled, so that the same can fix it, on the other hand, when we have a system already ready and hosted, it is the best option to hide all error messages, because if a malicious user catches this error, he can use it against the system itself, thus causing a huge headache.

Show 6 more comments

4 answers

8


Never use error_reporting(0);, this affects more than display the errors, it affects the logs saved, which is not a good idea, just use the:

ini_set('display_errors', 0);

This will already prevent errors from being displayed to the user and the most it will get is the "500 Internal Error Server'

An ideal setting for the error_reporting would be:

error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);

This will cause all errors to be saved on log (if it is authorised to do so log), except notifications, type errors Strict, usage errors and errors of discontinued functions, classes or functionalities.

More details on this reply: Why use error_reporting with display_errors and display_startup_errors?

For development I recommend enabling everything, after all it is development:

ini_set('display_errors', 1);
error_reporting(E_ALL|E_STRICT);

Note that in modern versions of PHP only E_ALL is enough, the use of E_ALL|E_STRICT was more for retro-compatibility.

In production in php.ini you can configure the logs error setting so:

error_log = /home/user/php/logs.txt

There is no problem in doing this in homologation and development environments, since there are pages that can be ordered via Ajax and you may not be able to notice the error when developing.

Note also that on some shared servers there is usually no way to change the error_log =, but usually it is already enabled and using the echo ini_get('error_log'); (will not display to the user :)) you can pick up the location where you were saved and maybe by SSH or SFTP download the log generated diary.

Another example of how to capture logs as I quoted in /a/34818/3635, would be using set_error_handler combined with register_shutdown_function, you could use this to send an error to an email, or something like that.

Anyway I would say that the ideal is to correct as many errors as possible and test the system well before sending it to production and if there is any error it was not possible to detect the log should inform only you.


How to display errors in a friendly way

... how I could not display the error message and yes create logs error, then redirect the user to the previous page, stating "Error occurred"?

Overall between display or not is the least of the problems in my view, the issue is the system fails and cause a number of side effects cascaded, for example generating invalid/incomplete records in the database, as said ideal is to handle everything possible, for example using mysql with innodb (myisam can’t stand it) you have the rollback:

if (!mysqli_query($link, 'INSERT ... xyz...')) {
    die('Erro ao inserir xyz');
}

if (!mysqli_query($link, 'UPDATE... status...')) {
    die('Erro ao atualizar status');
}

if (!mysqli_query($link, 'UPDATE... chat...')) {
    die('Erro ao atualizar chat');
}

Assuming the last one query fail, but it’s important, you’d have updates on status and in Xyz that there shouldn’t be, because the system failed, now use:

/*Desativa o autocommit*/
mysqli_autocommit($link, false);

if (!mysqli_query($link, 'INSERT ... xyz...')) {
    die('Erro ao inserir xyz');
}

if (!mysqli_query($link, 'UPDATE... status...')) {
    mysqli_rollback($link); //Desfaz
    die('Erro ao atualizar status');
}

if (!mysqli_query($link, 'UPDATE... chat...')) {
    mysqli_rollback($link); //Desfaz
    die('Erro ao atualizar chat');
}

mysqli_commit($link);

He’ll just do the commit if you’ve been through all ifs, of course this is a very simple example, another situation is that people always take data from $_GET and $_POST without checking, simply doing this:

$nome = $_POST['nome'];
$email = $_POST['email'];

When they could do this (it’s just an example):

$nome = $_POST['nome'];
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

if (!validaNome($nome)) { //Função "teórica"
     die('Dados do formulário vazio');
}

if (!$email) {
     die('Dados do formulário vazio');
}

These would be some examples, the die is optional, in case I find it complicated to use it when it depends on the layout, you could group the errors and send them at the end, but this is a matter of experience and how your system was designed. Now about script errors that don’t have to do directly with "logic" or lost data, I mean FATAL and PARSE errors, as I said should be things that you should always check in the development, but of course I understand that this can happen back and forth, in case you could use the set_error_handler and the register_shutdown_function combined to display a fixed message at the top or to use ob_start could generate an error page with nothing else (note that ob_start can increase server consumption, which personally I don’t think is a good idea, I just cited it as an example, there are other ways to do this), for example:

  • create a global.php

    <?php
    ob_start(); //Inicia o buffer
    
    function handleErrors($errno, $errstr, $errfile, $errline, $details = null) {
        static $log; //Variavel static para detectar erros repetidos
    
        if (isset($loggers) === false) {
             $log = array();
        }
    
        $localizacao = $errfile . ':' . $errline;
    
        if (in_array($localizacao, $log)) {
             return true;
        }
    
        $localizacao[] = $localizacao; //Salva o erro para evitar ser eviado mais de de uma vez
    
        $msg = 'Erro ' . $errstr .
               ' no arquivo: ' . $errfile .
               ' na linha: ' . $errline;
    
        error_log($msg, 1, '[email protected]');
    
        ob_end_clean(); //Limpa o buffer
    
        require 'erroamigavel.php';
    
        return true; //Não executa o "handler interno" do PHP
    }
    
    set_error_handler('handleErrors', E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
    
    register_shutdown_function(function () {
         $error = error_get_last();
         $type = $error['type'];
    
         if (!in_array($type, array(E_NOTICE, E_STRICT, E_DEPRECATED))) {
             handleErrors($type, $error['message'], $error['file'], $error['line']);
             );
         }
    });
    
  • Include this global.php in all files at the beginning like this:

    <?php
    require_once 'global.php';
    

    Note that if the file you included has a PARSE error the global.php will probably not work

  • And then create a file called erroamigavel.php with the content you want to display to the user, for example:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Erro</title>
    </head>
    <body>
        <h1>Ouve um erro na página</h1>
        <p>Os administradores já foram notificados e estão trabalhando para corrigir</p>
    </body>
    </html>
    

    note that it is all example, it is not something that will be copy and paste, I myself am not "fan" of ob_start() for the reason I have already mentioned, only the use if necessary is even possible to do in other ways, but it depends a lot on how your system was created, in my framework personal for example I can do something like this without needing to ob_start().

  • @Sauldasilvarolim Great, I’m just in doubt what function is this called msglog, it would be a function of a framework?

  • It was not user who left no! I can not see this vote when I visualize the positive and negative.

  • 1

    @Guilhermenascimento you said you received a negative vote, but, it does not appear here in your score!

  • 1

    But for him to undo it his question has to be edited or I’m wrong @Guilhermenascimento ?

  • @Stormwind should be, on the panel listed: desfazer o voto o favor, was the trip of my crazy mind :P

  • That of the commits was great! Really good!

Show 1 more comment

3

It is recommended that it be disabled, not even an error should be exposed to the user, because failure in your system may end up being demonstrated, errors should be handled in the application and always shown user-friendly screens.

Note: this is just a recommendation and a good practice, leaving to your discretion what will actually be done on your production server.

Log is essential for you to capture all errors and can treat later.

-3

yes should be disabled, because a malicious person can take advantage of a failure and get access to databases and so take information from their customers and the errors that appear are not variables that are not being used, but vulnerabilities may also appear in the system that can result in a big financial loss and among other reasons should be disabled yes in the production environment after everything is working properly.

-3

Answering the question of EDIT, you should use Try/catch blocks and exceptions, I’m a little rusty in php but if I’m not mistaken it’s not so difficult and I’ve heard that php7 is easier still, so the correct is always "treat the error" and to treat the errorlo, so we have to the most correct is: predict which points can give error and create exceptions and Try/catch blocks to handle these errors, obviously not all errors will be identified right from the first, but the ideal is to try to achieve the largest number of scenarios. Ex: In a user’s registration the name field cannot be empty. You create an Exception for example Nameovazioexception and fire it if the name is empty: name == empty? trhow Nameanovazioexception and at set time or save time Oce makes a Try/catch

try
{
    //tenta salvar o usuario
}
catch(NomeNaoVazioException $e)
{
    //trata o erro enviando o ator para a tela anterior com mensagem de erro
}
  • 2

    I find that option horrible. Using try/catch specifically does not mean that you handled the errors. In cases of variables that do not have indexes, a simple if with isset would. But the problem goes beyond simply "reinforcing checks". Every application has a bug, so it is best to always leave the error view disabled.

  • 1

    Just so I’m clear, you’re discouraging the use of try/catch ? And instead is stimulating the use of if/else ? Obviously only Try/catch does not guarantee that errors have been eliminated but say that you find it horrible to use this gimmick and a little heavy if you do not use, as then treats exceptional flows in your applications?

  • 2

    I didn’t say I disapprove, but using it for everything is misusing the resource. There are several ways to handle the error (in PHP there are many different occasions to handle). I find it horrible to sell the idea that Try catch solves everything in PHP, because that’s not true.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.