From 1874e62fd15b8371c47404be4e954b56c8f443e7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 25 Oct 2023 07:00:00 +0900 Subject: [PATCH 1/8] fix: detailed error report is displayed in production environment php > ini_set('display_errors', '0'); php > var_dump(ini_get('display_errors')); string(1) "0" php > ini_set('display_errors', 0); php > var_dump(ini_get('display_errors')); string(1) "0" php > ini_set('display_errors', false); php > var_dump(ini_get('display_errors')); string(0) "" php > ini_set('display_errors', null); php > var_dump(ini_get('display_errors')); string(0) "" php > ini_set('display_errors', 'off'); php > var_dump(ini_get('display_errors')); string(3) "off" --- app/Config/Boot/development.php | 2 ++ app/Config/Boot/production.php | 2 ++ system/Debug/ExceptionHandler.php | 8 +++++++- system/Debug/Exceptions.php | 8 +++++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php index 05a861258fc9..aa8099a46501 100644 --- a/app/Config/Boot/development.php +++ b/app/Config/Boot/development.php @@ -7,6 +7,8 @@ | In development, we want to show as many errors as possible to help | make sure they don't make it to production. And save us hours of | painful debugging. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ error_reporting(-1); ini_set('display_errors', '1'); diff --git a/app/Config/Boot/production.php b/app/Config/Boot/production.php index 21d25805674a..73c7c60afbc7 100644 --- a/app/Config/Boot/production.php +++ b/app/Config/Boot/production.php @@ -6,6 +6,8 @@ |-------------------------------------------------------------------------- | Don't show ANY in production environments. Instead, let the system catch | it and display a generic error message. + | + | If you set 'display_errors' to '1', CI4's detailed error report will show. */ ini_set('display_errors', '0'); error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); diff --git a/system/Debug/ExceptionHandler.php b/system/Debug/ExceptionHandler.php index 9fe40f33728c..46b855e5eca7 100644 --- a/system/Debug/ExceptionHandler.php +++ b/system/Debug/ExceptionHandler.php @@ -129,7 +129,13 @@ protected function determineView(Throwable $exception, string $templatePath): st // Production environments should have a custom exception file. $view = 'production.php'; - if (str_ireplace(['off', 'none', 'no', 'false', 'null'], '', ini_get('display_errors')) !== '') { + if ( + str_ireplace( + ['off', 'none', 'no', 'false', 'null', '0'], + '', + ini_get('display_errors') + ) !== '' + ) { $view = 'error_exception.php'; } diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php index 885f98ae0b06..b127a58241b0 100644 --- a/system/Debug/Exceptions.php +++ b/system/Debug/Exceptions.php @@ -253,7 +253,13 @@ protected function determineView(Throwable $exception, string $templatePath): st $view = 'production.php'; $templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR; - if (str_ireplace(['off', 'none', 'no', 'false', 'null'], '', ini_get('display_errors')) !== '') { + if ( + str_ireplace( + ['off', 'none', 'no', 'false', 'null', '0'], + '', + ini_get('display_errors') + ) !== '' + ) { $view = 'error_exception.php'; } From 1be8686535592738056ea2ad884d0ca79a7fed8c Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 25 Oct 2023 15:44:12 +0900 Subject: [PATCH 2/8] docs: add comments --- app/Config/Boot/testing.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Config/Boot/testing.php b/app/Config/Boot/testing.php index e07a1d43f43e..e84670e972f6 100644 --- a/app/Config/Boot/testing.php +++ b/app/Config/Boot/testing.php @@ -1,5 +1,11 @@ Date: Wed, 25 Oct 2023 16:21:07 +0900 Subject: [PATCH 3/8] fix: SHOW_DEBUG_BACKTRACE does not work in web --- app/Views/errors/html/error_exception.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php index f311d910c0fa..1d1ac7bd87bb 100644 --- a/app/Views/errors/html/error_exception.php +++ b/app/Views/errors/html/error_exception.php @@ -44,6 +44,7 @@ +
    @@ -375,6 +376,7 @@
+ diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php index 1d1ac7bd87bb..1c094d728872 100644 --- a/app/Views/errors/html/error_exception.php +++ b/app/Views/errors/html/error_exception.php @@ -67,7 +67,7 @@
  • - + Date: Wed, 25 Oct 2023 20:46:11 +0900 Subject: [PATCH 5/8] test: add test for determineView() --- tests/system/Debug/ExceptionHandlerTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/system/Debug/ExceptionHandlerTest.php b/tests/system/Debug/ExceptionHandlerTest.php index cd87eff739cf..1321f67195f3 100644 --- a/tests/system/Debug/ExceptionHandlerTest.php +++ b/tests/system/Debug/ExceptionHandlerTest.php @@ -70,6 +70,21 @@ public function testDetermineViewsRuntimeExceptionCode404(): void $this->assertSame('error_404.php', $viewFile); } + public function testDetermineViewsDisplayErrorsOffRuntimeException(): void + { + ini_set('display_errors', '0'); + + $determineView = $this->getPrivateMethodInvoker($this->handler, 'determineView'); + + $exception = new RuntimeException('Exception'); + $templatePath = APPPATH . 'Views/errors/html'; + $viewFile = $determineView($exception, $templatePath); + + $this->assertSame('production.php', $viewFile); + + ini_set('display_errors', '1'); + } + public function testCollectVars(): void { $collectVars = $this->getPrivateMethodInvoker($this->handler, 'collectVars'); From 2a99bdf3fcfa1fe5bd681a570cc80dc052554ae1 Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 25 Oct 2023 20:55:12 +0900 Subject: [PATCH 6/8] docs: improve docs --- user_guide_src/source/general/environments.rst | 2 ++ user_guide_src/source/general/errors.rst | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/user_guide_src/source/general/environments.rst b/user_guide_src/source/general/environments.rst index 57e85c67c106..428894ad75b5 100644 --- a/user_guide_src/source/general/environments.rst +++ b/user_guide_src/source/general/environments.rst @@ -30,6 +30,8 @@ By default, CodeIgniter has three environments defined. If you want another environment, e.g., for staging, you can add custom environments. See `Adding Environments`_. +.. _setting-environment: + ******************* Setting Environment ******************* diff --git a/user_guide_src/source/general/errors.rst b/user_guide_src/source/general/errors.rst index 943793340466..9e49711e7954 100644 --- a/user_guide_src/source/general/errors.rst +++ b/user_guide_src/source/general/errors.rst @@ -49,8 +49,12 @@ Error Reporting --------------- By default, CodeIgniter will display a detailed error report with all errors in the ``development`` and ``testing`` environments, and will not -display any errors in the ``production`` environment. You can change this by setting the ``CI_ENVIRONMENT`` variable -in the :ref:`.env ` file. +display any errors in the ``production`` environment. + +.. image:: ../images/error.png + +You can change your environment by setting the ``CI_ENVIRONMENT`` variable. +See :ref:`setting-environment`. .. important:: Disabling error reporting DOES NOT stop logs from being written if there are errors. From f26b9dc85bdd4bcc785b1c98d86b8ecab62a96db Mon Sep 17 00:00:00 2001 From: kenjis Date: Wed, 25 Oct 2023 20:56:09 +0900 Subject: [PATCH 7/8] docs: add changelog and upgrade --- user_guide_src/source/changelogs/v4.4.3.rst | 7 +++++++ user_guide_src/source/installation/upgrade_443.rst | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.4.3.rst b/user_guide_src/source/changelogs/v4.4.3.rst index 9a70f3e17a9a..36e3dfb41e91 100644 --- a/user_guide_src/source/changelogs/v4.4.3.rst +++ b/user_guide_src/source/changelogs/v4.4.3.rst @@ -9,6 +9,13 @@ Release Date: Unreleased :local: :depth: 3 +SECURITY +******** + +- *Detailed Error Report is Displayed in Production Environment* was fixed. + See the `Security advisory GHSA-hwxf-qxj7-7rfj `_ + for more information. + BREAKING ******** diff --git a/user_guide_src/source/installation/upgrade_443.rst b/user_guide_src/source/installation/upgrade_443.rst index d33d162e9383..0af74926616c 100644 --- a/user_guide_src/source/installation/upgrade_443.rst +++ b/user_guide_src/source/installation/upgrade_443.rst @@ -15,6 +15,14 @@ Please refer to the upgrade instructions corresponding to your installation meth Mandatory File Changes ********************** +error_exception.php +=================== + +The following file received significant changes and +**you must merge the updated versions** with your application: + +- app/Views/errors/html/error_exception.php + Breaking Changes **************** @@ -48,3 +56,9 @@ This is a list of all files in the **project space** that received changes; many will be simple comments or formatting that have no effect on the runtime: - @TODO +- app/Config/Boot/development.php +- app/Config/Boot/production.php +- app/Config/Boot/testing.php +- app/Config/Filters.php +- app/Views/errors/html/error_404.php +- app/Views/errors/html/error_exception.php From f251a3c750468e126a996105c544636630a88341 Mon Sep 17 00:00:00 2001 From: kenjis Date: Thu, 26 Oct 2023 08:38:30 +0900 Subject: [PATCH 8/8] refactor: replace str_ireplace() with in_array() php > ini_set('display_errors', '1'); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', 1); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', true); php > var_dump(ini_get('display_errors')); string(1) "1" php > ini_set('display_errors', 'true'); php > var_dump(ini_get('display_errors')); string(4) "true" --- system/Debug/ExceptionHandler.php | 10 +++++----- system/Debug/Exceptions.php | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/system/Debug/ExceptionHandler.php b/system/Debug/ExceptionHandler.php index 46b855e5eca7..63449888ffb5 100644 --- a/system/Debug/ExceptionHandler.php +++ b/system/Debug/ExceptionHandler.php @@ -130,11 +130,11 @@ protected function determineView(Throwable $exception, string $templatePath): st $view = 'production.php'; if ( - str_ireplace( - ['off', 'none', 'no', 'false', 'null', '0'], - '', - ini_get('display_errors') - ) !== '' + in_array( + strtolower(ini_get('display_errors')), + ['1', 'true', 'on', 'yes'], + true + ) ) { $view = 'error_exception.php'; } diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php index b127a58241b0..bbcfcc8e8889 100644 --- a/system/Debug/Exceptions.php +++ b/system/Debug/Exceptions.php @@ -254,11 +254,11 @@ protected function determineView(Throwable $exception, string $templatePath): st $templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR; if ( - str_ireplace( - ['off', 'none', 'no', 'false', 'null', '0'], - '', - ini_get('display_errors') - ) !== '' + in_array( + strtolower(ini_get('display_errors')), + ['1', 'true', 'on', 'yes'], + true + ) ) { $view = 'error_exception.php'; }