'url_param', 'key' => $matches[0], 'note' => 'Sensitive URL parameter value replaced.', ); return $matches[1] . '[REDACTED]'; }, $value ); return null !== $masked ? $masked : $value; } /** * Masks values of fields with inherently sensitive names. * * @since 1.0.0 * @param string $value Raw string to inspect. * @param string $field_key The parameter key name. * @param array $log Passed by reference — masked items appended here. * @return string Possibly masked value. */ private static function mask_sensitive_field( string $value, string $field_key, array &$log ): string { $sensitive_keys = array( 'api_key', 'apikey', 'token', 'secret', 'password', 'access_token', 'auth', 'private_key', 'client_secret', 'apiKey', 'accessToken', 'clientSecret', 'privateKey', ); if ( in_array( $field_key, $sensitive_keys, true ) && '' !== $value && '[REDACTED]' !== $value ) { $log[] = array( 'reason' => 'sensitive_field_name', 'key' => $field_key, 'note' => 'Field name indicates sensitive data.', ); return '[REDACTED]'; } return $value; } /** * Applies condition rightValue heuristic masking. * Used specifically for condition node parameter values. * * @since 1.0.0 * @param string $value Raw condition value. * @param array $log Passed by reference — masked items appended here. * @return string Possibly masked value. */ public static function apply_condition_heuristic( string $value, array &$log ): string { $len = strlen( $value ); // Must be 8–512 chars. if ( $len < 8 || $len > 512 ) { return $value; } // Safe-list check. if ( in_array( strtolower( $value ), self::SAFE_CONDITION_VALUES, true ) ) { return $value; } // n8n expression check. if ( str_starts_with( $value, '={{' ) && str_ends_with( $value, '}}' ) ) { return $value; } // ISO date check. if ( preg_match( '/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/', $value ) ) { return $value; } // Entropy check: UUID-shaped, or mixed case+digits, or long with no spaces. $is_uuid = (bool) preg_match( '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $value ); $is_complex = (bool) preg_match( '/[A-Z]/', $value ) && (bool) preg_match( '/[a-z]/', $value ) && (bool) preg_match( '/[0-9]/', $value ); $is_long_no_space = $len > 20 && ! str_contains( $value, ' ' ); if ( $is_uuid || $is_complex || $is_long_no_space ) { $log[] = array( 'reason' => 'condition_heuristic', 'key' => 'rightValue', 'note' => 'Value matches entropy heuristic for potential secret.', ); return '[REDACTED]'; } return $value; } }