Skip to content

Commit

Permalink
Merge pull request #7736 from kenjis/update-BaseExceptionHandler-mask…
Browse files Browse the repository at this point in the history
…SensitiveData

fix: [4.4] merge Exception::maskSensitiveData() fix into BaseExceptionHandler
  • Loading branch information
kenjis authored Jul 27, 2023
2 parents 69cfe7b + ec6835d commit 56dba66
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 17 deletions.
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']);
}
}

0 comments on commit 56dba66

Please sign in to comment.