Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [4.4] merge Exception::maskSensitiveData() fix into BaseExceptionHandler #7736

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions system/Debug/BaseExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ protected function collectVars(Throwable $exception, int $statusCode): array
$trace = $exception->getTrace();

if ($this->config->sensitiveDataInTrace !== []) {
$this->maskSensitiveData($trace, $this->config->sensitiveDataInTrace);
$trace = $this->maskSensitiveData($trace, $this->config->sensitiveDataInTrace);
}

return [
Expand All @@ -86,33 +86,50 @@ protected function collectVars(Throwable $exception, int $statusCode): array

/**
* Mask sensitive data in the trace.
*/
protected function maskSensitiveData(array $trace, array $keysToMask, string $path = ''): array
{
foreach ($trace as $i => $line) {
$trace[$i]['args'] = $this->maskData($line['args'], $keysToMask);
}

return $trace;
}

/**
* @param array|object $args
*
* @param array|object $trace
* @return array|object
*/
protected function maskSensitiveData(&$trace, array $keysToMask, string $path = ''): void
private function maskData($args, array $keysToMask, string $path = '')
{
foreach ($keysToMask as $keyToMask) {
$explode = explode('/', $keyToMask);
$index = end($explode);

if (strpos(strrev($path . '/' . $index), strrev($keyToMask)) === 0) {
if (is_array($trace) && array_key_exists($index, $trace)) {
$trace[$index] = '******************';
} elseif (is_object($trace) && property_exists($trace, $index) && isset($trace->{$index})) {
$trace->{$index} = '******************';
if (is_array($args) && array_key_exists($index, $args)) {
$args[$index] = '******************';
} elseif (
is_object($args) && property_exists($args, $index)
&& isset($args->{$index}) && is_scalar($args->{$index})
) {
$args->{$index} = '******************';
}
}
}

if (is_object($trace)) {
$trace = get_object_vars($trace);
}

if (is_array($trace)) {
foreach ($trace as $pathKey => $subarray) {
$this->maskSensitiveData($subarray, $keysToMask, $path . '/' . $pathKey);
if (is_array($args)) {
foreach ($args as $pathKey => $subarray) {
$args[$pathKey] = $this->maskData($subarray, $keysToMask, $path . '/' . $pathKey);
}
} elseif (is_object($args)) {
foreach ($args as $pathKey => $subarray) {
$args->{$pathKey} = $this->maskData($subarray, $keysToMask, $path . '/' . $pathKey);
}
}

return $args;
}

/**
Expand Down
8 changes: 5 additions & 3 deletions system/Debug/Exceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,11 @@ protected function collectVars(Throwable $exception, int $statusCode): array
/**
* Mask sensitive data in the trace.
*
* @param array|object $trace
* @param array $trace
*
* @return array|object
* @return array
*
* @deprecated No longer used. Moved to BaseExceptionHandler.
* @deprecated 4.4.0 No longer used. Moved to BaseExceptionHandler.
*/
protected function maskSensitiveData($trace, array $keysToMask, string $path = '')
{
Expand All @@ -353,6 +353,8 @@ protected function maskSensitiveData($trace, array $keysToMask, string $path = '
* @param array|object $args
*
* @return array|object
*
* @deprecated 4.4.0 No longer used. Moved to BaseExceptionHandler.
*/
private function maskData($args, array $keysToMask, string $path = '')
{
Expand Down
82 changes: 82 additions & 0 deletions tests/system/Debug/ExceptionHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Debug;

use App\Controllers\Home;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\StreamFilterTrait;
Expand Down Expand Up @@ -140,4 +141,85 @@ public function testHandleCLIPageNotFoundException(): void

$this->resetStreamFilterBuffer();
}

public function testMaskSensitiveData(): void
{
$maskSensitiveData = $this->getPrivateMethodInvoker($this->handler, 'maskSensitiveData');

$trace = [
0 => [
'file' => '/var/www/CodeIgniter4/app/Controllers/Home.php',
'line' => 15,
'function' => 'f',
'class' => Home::class,
'type' => '->',
'args' => [
0 => (object) [
'password' => 'secret1',
],
1 => (object) [
'default' => [
'password' => 'secret2',
],
],
2 => [
'password' => 'secret3',
],
3 => [
'default' => ['password' => 'secret4'],
],
],
],
1 => [
'file' => '/var/www/CodeIgniter4/system/CodeIgniter.php',
'line' => 932,
'function' => 'index',
'class' => Home::class,
'type' => '->',
'args' => [
],
],
];
$keysToMask = ['password'];
$path = '';

$newTrace = $maskSensitiveData($trace, $keysToMask, $path);

$this->assertSame(['password' => '******************'], (array) $newTrace[0]['args'][0]);
$this->assertSame(['password' => '******************'], $newTrace[0]['args'][1]->default);
$this->assertSame(['password' => '******************'], $newTrace[0]['args'][2]);
$this->assertSame(['password' => '******************'], $newTrace[0]['args'][3]['default']);
}

public function testMaskSensitiveDataTraceDataKey(): void
{
$maskSensitiveData = $this->getPrivateMethodInvoker($this->handler, 'maskSensitiveData');

$trace = [
0 => [
'file' => '/var/www/CodeIgniter4/app/Controllers/Home.php',
'line' => 15,
'function' => 'f',
'class' => Home::class,
'type' => '->',
'args' => [
],
],
1 => [
'file' => '/var/www/CodeIgniter4/system/CodeIgniter.php',
'line' => 932,
'function' => 'index',
'class' => Home::class,
'type' => '->',
'args' => [
],
],
];
$keysToMask = ['file'];
$path = '';

$newTrace = $maskSensitiveData($trace, $keysToMask, $path);

$this->assertSame('/var/www/CodeIgniter4/app/Controllers/Home.php', $newTrace[0]['file']);
}
}
Loading