无法使用node.js中的javascript在Windows中删除文件

pgpifvop  于 2023-02-21  发布在  Node.js
关注(0)|答案(2)|浏览(151)

我有下面的代码,试图删除Windows 7机器上的文件:

// check if this item has an uploaded image file
    var imageFullPathName = __dirname + "/../public/images/" + req.params.itemId;
    logger.log("imageFullPathName = " + imageFullPathName);
    var normalizedPathName = path.normalize(imageFullPathName);
    logger.log("normalizedPathName = " + normalizedPathName);

    // delete the image if it exists
    fs.exists(normalizedPathName, function(exists) {
        console.log("Found the file: " + normalizedPathName);
        normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\");
        console.log("New path name = " + normalizedPathName);
        fs.unlink(normalizedPathName, function(err){
            if (err){
                console.error("Error in call to fs.unlink");
            }
        });
    });

我得到了以下输出:
图像完整路径名称= C:\铁钥匙\hes\ccie-71\项目\医疗交换\路径/../公共/图像/5658e5612103cb2c41000006
标准化路径名称= C:\IronKey\hes\ccie-71\项目\医疗交换\公共\图像\5658e5612103cb2c41000006
新路径名= C:\IronKey\hes\ccie-71\项目\医疗交换\公共\图像\5658e5612103cb2c41000006
调用fs. unlink时出错
当我使用DOS shell查找时,这个文件确实存在。而且,不管我对新路径名做了什么,我都不能删除这个文件。如果我注解掉对normalizedPathName.replace()的调用,使路径带有一个反斜杠,仍然会失败。但是,如果我手动创建一个如下的字符串,它就可以工作了:
文件系统取消链接("c:\IronKey\hes\ccie-71\项目\医疗交换\公共\图像\5658e5612103cb2c41000006",函数(错误){...
我该怎么做才能删除这个文件?我完全被难住了。
我按照josh3736的建议修改了代码,但是得到了一个ENOENT错误。这个文件确实存在,因为我在编辑器中打开它时使用了错误消息中报告的完全路径名:

// check if this item has an uploaded image file
        var imageFullPathName = path.join(__dirname, "../public/images",
                                          sanitize(req.params.itemId));
        logger.log("imageFullPathName = " + imageFullPathName);

        fs.unlink(imageFullPathName, function(err){
            //if (err.code != 'ENOENT'){
            if (err){
                logger.log("Error in call to fs.unlink", err);
            }
            else{
                logger.log("No file found");
            }
            logger.log("Delete Success");
        });

错误消息如下所示:调用文件系统时出错。取消链接{[错误:错误:无此类文件或目录,请取消链接"C:\IronKey\hes\ccie-71\项目\医疗交换\公共\图像\5658fd27fca1b3bc3d00000e"]

nbysray5

nbysray51#

这里有几个问题。
1.您盲目地信任用户输入。攻击者只需要请求一个将itemId设置为类似%2E%2E%2F%2E%2E%2F%2E%2E%2FWindows的URL。Express会将req.params中的此值反转义为../../../Windows,然后您的服务器就消失了。
一般来说,在处理不可信的输入(通过HTTP进入的 * 任何东西 * 都是不可信的)时要非常小心,在这种情况下,使用sanitize-filename之类的命令来确保输入中没有任何不必要的内容。

  1. fs.exists是一个反模式,在调用exists和执行下一步操作之间,其他进程可能会添加或删除所讨论的文件,因此,应无条件地调用unlink--如果err.code == 'ENOENT'出错,则该文件不存在;忽略错误即可。
    1.为什么是normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\");呢?你有一个有效的路径,但是你却把它设置为无效(C:\foo\barC:\\foo\\bar),所以它当然不起作用。
    1.组装路径时,使用path.join,而不是字符串连接。它将处理斜线(\ vs /),使代码可移植。
    把所有这些放在一起,
var imageFullPathName = path.join(
                                    __dirname,
                                    "../public/images",
                                    sanitizeFilename(req.params.itemId)
                                );

fs.unlink(imageFullPathName, function(err){
    if (err) {
        if (err.code != 'ENOENT') {
            // handle actual errors here
            console.error("Error in call to fs.unlink", err);
        }
        // else there was no file, handle that if you need to
    }
    // else delete success, handle that if you need to
});

既然您提到了代码即使注解掉反斜杠replace行也会失败:
你的代码 * 应该 * 那样工作。实际的错误是什么?我的第一个猜测是权限问题。

irlmq6kh

irlmq6kh2#

您可以使用Windows命令行永久删除文件,而不是fs.unlink:

exec(`del ${imageFullPathName}`, (error, stdout, stderr) => {
        if (error) {
          console.error(`exec error: ${error}`);
          return;
        }
      });

相关问题