diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index 91227241..0d96ed09 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -151,9 +151,20 @@ class NormalizerFormatter implements FormatterInterface if (isset($frame['file'])) { $data['trace'][] = $frame['file'].':'.$frame['line']; } elseif (isset($frame['function']) && $frame['function'] === '{closure}') { - // We should again normalize the frames, because it might contain invalid items + // Simplify closures handling $data['trace'][] = $frame['function']; } else { + if (isset($frame['args'])) { + // Make sure that objects present as arguments are not serialized nicely but rather only + // as a class name to avoid any unexpected leak of sensitive information + $frame['args'] = array_map(function ($arg) { + if (is_object($arg) && !($arg instanceof \DateTime || $arg instanceof \DateTimeInterface)) { + return sprintf("[object] (%s)", get_class($arg)); + } + + return $arg; + }, $frame['args']); + } // We should again normalize the frames, because it might contain invalid items $data['trace'][] = $this->toJson($this->normalize($frame), true); } diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index b4f82897..bafd1c74 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -407,6 +407,29 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase $result['context']['exception']['trace'][0] ); } + + public function testExceptionTraceDoesNotLeakCallUserFuncArgs() + { + try { + $arg = new TestInfoLeak; + call_user_func(array($this, 'throwHelper'), $arg, $dt = new \DateTime()); + } catch (\Exception $e) { + } + + $formatter = new NormalizerFormatter(); + $record = array('context' => array('exception' => $e)); + $result = $formatter->format($record); + + $this->assertSame( + '{"function":"throwHelper","class":"Monolog\\\\Formatter\\\\NormalizerFormatterTest","type":"->","args":["[object] (Monolog\\\\Formatter\\\\TestInfoLeak)","'.$dt->format('Y-m-d H:i:s').'"]}', + $result['context']['exception']['trace'][0] + ); + } + + private function throwHelper($arg) + { + throw new \RuntimeException('Thrown'); + } } class TestFooNorm @@ -448,3 +471,11 @@ class TestToStringError throw new \RuntimeException('Could not convert to string'); } } + +class TestInfoLeak +{ + public function __toString() + { + return 'Sensitive information'; + } +}