use*_*456 5 javascript node.js
我有以下代码尝试删除 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");
}
});
});
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
imageFullPathName = C:\IronKey\hes\cscie-71\project\medical-interchange\routes/../public/images/5658e5612103cb2c41000006
规范化路径名称 = C:\IronKey\hes\cscie-71\project\medical-interchange\public\images\5658e5612103cb2c41000006
新路径名 = C:\\IronKey\\hes\\cscie-71\\project\\medical-interchange\\public\\images\\5658e5612103cb2c41000006
调用 fs.unlink 时出错
当我使用 DOS shell 查找该文件时,该文件确实存在。我对新路径名做什么也没关系,我永远无法删除该文件。如果我通过注释掉对 的调用来保留带有单反斜杠的路径normalizedPathName.replace(),它仍然会失败。但是,如果我手动创建这样的字符串,它会起作用:
fs.unlink("c:\\IronKey\\hes\\cscie-71\\project\\medical-interchange\\public\\images\\5658e5612103cb2c41000006", function(err){ ...
我需要做什么才能删除这个文件?我完全被难住了。
我按照 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");
});
Run Code Online (Sandbox Code Playgroud)
错误消息如下: Error in call to fs.unlink { [Error: ENOENT: no such file or directory, unlink 'C:\\IronKey\\hes\\cscie-71\\project\\medical-interchange\\公共\\图像\\5658fd27fca1b3bc3d00000e']
这里有几个问题。
\n\n您盲目信任用户输入。攻击者只需要请求一个设置为itemId类似 的URL %2E%2E%2F%2E%2E%2F%2E%2E%2FWindows。Express 会将其转义req.params到../../../Windows,然后您的服务器就消失了。
一般来说,请记住在处理不受信任的输入时要格外小心(并且通过 HTTP 传入的任何内容都是不受信任的)。在这种情况下,请使用诸如sanitize-filename之类的内容来确保输入中没有任何顽皮的内容。
fs.exists是一种反模式。其他一些进程可能会在您调用和您下一步执行的操作之间添加或删除有问题的文件exists。相反,unlink无条件调用 - 如果出现错误err.code == \'ENOENT\',则该文件不存在;忽略该错误。
为什么normalizedPathName = normalizedPathName.replace(/\\\\/g,"\\\\\\\\");?您有一个有效的路径,但您将其设为无效(C:\\foo\\bar\xe2\x86\x92 C:\\\\foo\\\\bar),所以它当然不起作用。
组装路径时,请使用path.join,而不是字符串连接。它将处理斜杠(\\vs /),使您的代码可移植。
综上所述,
\n\nvar imageFullPathName = path.join(\n __dirname,\n "../public/images",\n sanitizeFilename(req.params.itemId)\n );\n\nfs.unlink(imageFullPathName, function(err){\n if (err) {\n if (err.code != \'ENOENT\') {\n // handle actual errors here\n console.error("Error in call to fs.unlink", err);\n }\n // else there was no file, handle that if you need to\n }\n // else delete success, handle that if you need to\n});\nRun Code Online (Sandbox Code Playgroud)\n\n由于您提到即使注释掉反斜杠行,您的代码也会失败replace:
你的代码应该这样工作。实际的错误是什么?我的第一个猜测是权限问题。
\n| 归档时间: |
|
| 查看次数: |
2334 次 |
| 最近记录: |