显示 PHP 异常消息是否存在安全风险


Would displaying PHP Exception Message be a security risk?

我想设置一条自定义消息,以便在Laravel 5.1中抛出错误时向用户显示。例如,在控制器中,我可能有:

if(!has_access()){
    abort('401', 'please contact support to gain access to this item.');
}

然后我的自定义错误页面将显示错误:

$exception->getMessage();

但是,如果出现 SQL 错误或其他事件怎么办?这不也会设置异常消息吗,我会在不知不觉中在我的错误页面上输出?

getMessage() 的 PHP 文档对此没有太多细节。

如何在不引入任何安全风险的情况下设置特定的异常消息?

但是,如果出现 SQL 错误或其他事件怎么办?这不也会设置异常消息吗,我会在不知不觉中在我的错误页面上输出?

潜在地,是的。PHP 不保证异常消息的内容可以"安全"地显示给用户,并且某些类很可能会抛出异常,其中包括消息中的敏感信息。

如果要使用异常向用户显示错误,请为这些异常使用特定的Exception子类,并且仅在异常是该子类的实例时才打印消息,例如

class UserVisibleException extends Exception {
    // You don't need any code in here, but you could add a custom constructor
    // if you wanted to.
}
// Then, in your abort() function...
throw new UserVisibleException($message);
// Then, in your exception handler...
if ($exc instanceof UserVisibleException) {
    print $exc->getMessage();
} else {
    print "An internal error occurred.";
}

如果您访问app.php文件:

  'debug' => env('APP_DEBUG', false),

在生产环境中,将其设置为 false。这将确保生产环境中不会显示任何调试错误。

设置后,您可以通过控制器响应正常异常。其他任何事情,laravel都不会显示错误页面。

是的,

$e->getMessage() 可能会揭示有关代码的更多信息,如果您以类似的方式使用它:

try {
    $executeSomethingHereForWhichYouExpectAnException();  
// Basic 'Exception that reports everything  
} catch ('Exception $e) {
    $error = $e->getMessage();
}

即使'debug' => falseapp.php.例如,如果您的代码有错误$error会显示它 - 基本上任何类型的错误(PHP,MYSQL 等);

但是,有一个修复 - 捕获您的 CustomException 消息并防止显示典型错误,如果您像这样使用它:

try {
    $executeSomethingHereForWhichYouExpectAnException();
// Our custom exception that throws only the messages we want
} catch ('CustomException $e) {
    // Would contain only 'my_custom_message_here'
    $error = $e->getMessage();
}

您可能会问的区别是什么 - 区别在于,我们使用 ''CustomException 类,而不是基本的错误报告''Exception,您从函数$executeSomethingHereForWhichYouExpectAnException()抛出该类:

executeSomethingHereForWhichYouExpectAnException(){
   if (something) {
     throw new CustomException("my_custom_message_here", 1);
   }
}

如果你有更多的例外,你可以像这样包含它们(从 PHP7.1 开始):

try {
   something();
} catch('CustomException | 'SecondCustomException $e) {
  // custom exceptions
} catch('Exception $e) {
  // basic exception containing everything
}