我正在尝试学习NodeJS / Express的安全性最佳实践。如何保护此文件上传?当前,它只是将文件放在文件夹中。我担心用户会上传恶意文件/代码。
这是一个简单的文件上传,来自我的响应前端上的表单。目的是允许人们上传头像的头像。我正在使用Formidable,因此我可以检查图像的类型,但是我想知道这是否足够安全?
server.js
const express = require('express');
const server = express();
server.listen(8000, () => {
console.log('Server started!');
});
server.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept',
);
});
const upload = require('./upload');
server.post('/upload', upload);
upload.js
const IncomingForm = require('formidable').IncomingForm;
module.exports = function upload(req, res) {
var form = new IncomingForm();
form.parse(req);
form.on('file', (field, file) => {
console.log(file);
});
form.on('fileBegin', function(name, file) {
file.path = __dirname + '/uploads/' + file.name;
});
form.on('end', () => {
res.json();
});
};
答案 0 :(得分:1)
您还可以通过请求检查MIME内容类型:
if (contype.indexOf('image/png') !== 0)
还要检查文件扩展名:
file.extname('cool_picture.png')
最后但并非最不重要的一点是,检查十六进制格式的文件头。所有文件类型均以十六进制数字开头。是什么意思?
PNG始终以以下序列开头:5089 474e 0a0d 0a1a
JPG始终以以下序列开头:d8ff e0ff 1000 464a
依此类推,因此您可以使用图像的初始文件头(例如PNG_HEADER = '5089 474e 0a0d 0a1a';
)创建基本字符串或数组,读取上载的文件头,并比较文件内容类型和扩展名是否匹配。< / p>
上传就可以了。
答案 1 :(得分:1)
以下两个步骤是基本步骤。
在前端,只允许特定的文件扩展名(如(.pdf,.png等))具有大小限制。 (不要忘记可以操纵前端代码)。 2.您还需要检查后端的文件扩展名和大小(如果您使用的是节点,则可以使用multer来实现)。
我们在后端还能做什么?
如果我们仅依靠检查扩展名就没有帮助。 (任何人都可以将sample.exe的名称修改为sample.jpg并上传)。 例如,如果您除了检查文件扩展名之外,还检查文件是否在后端上传了图片,您也可以按照以下方法进行操作。
PNG文件的前八个字节始终包含以下(十进制)值:137 80 78 71 13 10 26 10
如果您要检查上传的文件是否为png,则上述条件将起作用。不仅如此,如果您想检查是否正确上传了文件,还可以按照上述方法进行操作。 (对于.pdf,.doc,可能会有一些规则)。 您可以检查MIME签名数据,这是最佳做法。
不要将上传的文件保存在后端代码存储库中。将它们存储在其他工作区中。 (可选的) 跟随链接可能会有所帮助。
云存储
除了将文件存储在本地服务器中之外,您还可以将上传的文件保存在Amazon S3存储桶之类的云中。每次将任何文件上传到该s3存储桶后,您都可以使用lambdas(亚马逊上的自动文件扫描仪)触发扫描仪。
除了亚马逊以外,您还可以使用Google驱动器上传文件(不是最佳选择)。但是当有人下载上传的文件时,谷歌会自动扫描病毒。
amazon的s3存储桶文件的扫描链接::
amazon s3 bucket files scan SO
s3 files scanning using lambda & clamav
对于本地服务器::