我有下面的代码,试图删除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"]
2条答案
按热度按时间nbysray51#
这里有几个问题。
1.您盲目地信任用户输入。攻击者只需要请求一个将
itemId
设置为类似%2E%2E%2F%2E%2E%2F%2E%2E%2FWindows
的URL。Express会将req.params
中的此值反转义为../../../Windows
,然后您的服务器就消失了。一般来说,在处理不可信的输入(通过HTTP进入的 * 任何东西 * 都是不可信的)时要非常小心,在这种情况下,使用sanitize-filename之类的命令来确保输入中没有任何不必要的内容。
fs.exists
是一个反模式,在调用exists
和执行下一步操作之间,其他进程可能会添加或删除所讨论的文件,因此,应无条件地调用unlink
--如果err.code == 'ENOENT'
出错,则该文件不存在;忽略错误即可。1.为什么是
normalizedPathName = normalizedPathName.replace(/\\/g,"\\\\");
呢?你有一个有效的路径,但是你却把它设置为无效(C:\foo\bar
→C:\\foo\\bar
),所以它当然不起作用。1.组装路径时,使用
path.join
,而不是字符串连接。它将处理斜线(\
vs/
),使代码可移植。把所有这些放在一起,
既然您提到了代码即使注解掉反斜杠
replace
行也会失败:你的代码 * 应该 * 那样工作。实际的错误是什么?我的第一个猜测是权限问题。
irlmq6kh2#
您可以使用Windows命令行永久删除文件,而不是fs.unlink: