Split long condition over multiple lines in sanitizeStacktrace()
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / core.functions.php
index b414761add3a7cc8e699a18d7f8176314dc23e2d..3cecacd3ba2789d1fbdb2a15aad868f5ef9a2730 100644 (file)
@@ -116,6 +116,11 @@ namespace wcf {
        function getMinorVersion(): string {
                return preg_replace('/^(\d+\.\d+)\..*$/', '\\1', WCF_VERSION);
        }
+
+       #[Attribute(\Attribute::TARGET_PARAMETER)]
+       class SensitiveArgument
+       {
+       }
 }
 
 namespace wcf\functions\exception {
@@ -710,13 +715,48 @@ EXPLANATION;
                        if (!isset($item['class'])) $item['class'] = '';
                        if (!isset($item['type'])) $item['type'] = '';
                        if (!isset($item['args'])) $item['args'] = [];
-                       
-                       // strip database credentials
-                       if (preg_match('~\\\\?wcf\\\\system\\\\database\\\\[a-zA-Z]*Database~', $item['class']) || $item['class'] === 'PDO') {
-                               if ($item['function'] === '__construct') {
-                                       $item['args'] = array_map(function () {
-                                               return '[redacted]';
-                                       }, $item['args']);
+
+                       if (!empty($item['args'])) {
+                               if ($item['class']) {
+                                       $function = new \ReflectionMethod($item['class'], $item['function']);
+                               }
+                               else {
+                                       $function = new \ReflectionFunction($item['function']);
+                               }
+
+                               $parameters = $function->getParameters();
+                               $i = 0;
+                               foreach ($parameters as $parameter) {
+                                       $isSensitive = false;
+                                       if (
+                                               \method_exists($parameter, 'getAttributes')
+                                               && !empty($parameter->getAttributes(\wcf\SensitiveArgument::class))
+                                       ) {
+                                               $isSensitive = true;
+                                       }
+                                       if (\preg_match(
+                                               '/(?:^(?:password|passphrase|secret)|(?:Password|Passphrase|Secret))/',
+                                               $parameter->getName()
+                                       )) {
+                                               $isSensitive = true;
+                                       }
+
+                                       if ($isSensitive && isset($item['args'][$i])) {
+                                               $item['args'][$i] = '[redacted]';
+                                       }
+                                       $i++;
+                               }
+                               
+                               // strip database credentials
+                               if (
+                                       preg_match('~\\\\?wcf\\\\system\\\\database\\\\[a-zA-Z]*Database~', $item['class'])
+                                       || $item['class'] === 'PDO'
+                               ) {
+                                       if ($item['function'] === '__construct') {
+                                               $item['args'] = array_map(function () {
+                                                       return '[redacted]';
+                                               }, $item['args']);
+                                       }
                                }
                        }