strlen($b) <=> strlen($a)); foreach ($paths as $path) { if ($path !== '' && $path !== '/') { $value = str_replace([$path, str_replace('/', '\\', $path)], '~', $value); } } $value = (string) preg_replace('#/home/[^/\s]+#', '/home/~', $value); $patterns = [ '/\b(Authorization|Cookie|Set-Cookie)\s*:\s*[^\r\n]+/i' => '$1: [redacted]', '/\bBearer\s+[A-Za-z0-9._~+\/=-]{8,}/i' => 'Bearer [redacted]', '/\b(?:llm|llat|llrt|llp|mcp)_[A-Za-z0-9]{16,}/' => '[redacted]', '/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/' => '[redacted-jwt]', '#(https?://)[^/\s:@]+:[^/\s@]+@#i' => '$1[redacted]@', '/([?&](?:key|token|secret|sig|signature|password|api_key|access_token|code)=)[^&\s"\']+/i' => '$1[redacted]', '/((?:password|passwd|pwd|secret|api[_-]?key|token|DB_[A-Z_]+|[A-Z_]+_KEY|[A-Z_]+_SALT)["\']?\s*(?:=>|=|:)\s*["\']?)[^"\'\s,;)]+/i' => '$1[redacted]', '/\$(?:P|H|wp\$2y|2y|2a|2b|argon2id?)\$[A-Za-z0-9.\/$=+,-]{8,}/' => '[redacted-hash]', '/([A-Za-z0-9._%+-])[A-Za-z0-9._%+-]*@([A-Za-z0-9.-]+\.[A-Za-z]{2,})/' => '$1***@$2', ]; foreach ($patterns as $pattern => $replacement) { $value = (string) preg_replace($pattern, $replacement, $value); } return $value; } /** @param array $data @return array */ public static function deep(array $data): array { $out = []; foreach ($data as $key => $value) { if (is_string($key) && self::isSensitiveKey($key)) { $out[$key] = '[redacted]'; } elseif (is_array($value)) { $out[$key] = self::deep($value); } elseif (is_string($value)) { $out[$key] = self::text($value); } else { $out[$key] = $value; } } return $out; } }