何时在node.js上传脚本中检查文件大小/ mimetype? [英] when to check for file size/mimetype in node.js upload script?

查看:176
本文介绍了何时在node.js上传脚本中检查文件大小/ mimetype?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用express / formidable在node.js中创建了一个上传脚本。它基本上工作,但我想知道在什么时候检查上传的文件e。 G。对于最大文件大小或文件的mimetype是否被允许。



我的程序看起来像这样:

  app.post(' /',function(req,res,next){
req.form.on('progress',function(bytesReceived,bytesExpected){
// ... do stuff
}) ;

req.form.complete(函数(err,fields,files){
console.log('\\\
uploaded%s到%s',files.image.filename,files .image.path);
// ...做东西
});
});

在我看来,检查mimetype /文件大小的唯一可行的地方是 complete 事件,我可以可靠地使用文件系统函数获取上载文件的大小 / tmp / - 但是这似乎是一个不太好的主意,因为:
$ b $ ul

  • 可能恶意/太大的文件已经上传到我的服务器上

  • 用户体验不好 - 你看上传进度只是被告知以后没有工作了



  • 最佳做法是什么为了实现这个?我在node.js中发现了很多文件上传的例子,但似乎没有做我需要的安全检查。

    解决方案

    在IRC节点和节点邮件列表的帮助下,

    我使用强大的处理文件上传。使用 progress 事件,我可以检查最大文件大小是这样的:

     如果(bytesReceived> MAX_UPLOAD_SIZE){
    console.log('###错误:FILE TOO LARGE'); $ b $ form.on('progress',function(bytesReceived,bytesExpected){
    b}
    });

    可靠地检查mimetype要困难得多。基本的想法是使用 progress 事件,然后如果足够的文件被上传,使用文件--mime-type

      //包含上传文件的路径,
    //被抓取fileBegin事件低于
    var tmpPath;
    $ b form.on('progress',function validateMimetype(bytesReceived,bytesExpected){
    var percent =(bytesReceived / bytesExpected * 100)| 0;

    / /漂亮的基本检查是否有足够的文件字节写入磁盘,
    //如果文件很小,可能太天真了!
    if(tmpPath&& percent> 25){
    var child = exec('file --mime-type'+ tmpPath,function(err,stdout,stderr){
    var mimetype = stdout.substring(stdout.lastIndexOf(':')+ 2,stdout .lastIndexOf('\\\
    '));

    console.log('### file CALL OUTPUT',err,stdout,stderr);

    if(err || stderr){
    console.log('###错误:MIMETYPE不能被检测到);
    } else if!!ALLOWED_MIME_TYPES [mimetype]){
    console.log '###错误:INVALID MIMETYPE',mimetype);
    } else {
    console.log('### MIMETYPE VALIDA TION COMPLETE');
    }
    });

    form.removeListener('progress',validateMimetype);
    }
    });
    $ b form.on('fileBegin',function grabTmpPath(_,fileInfo){
    if(fileInfo.path){
    tmpPath = fileInfo.path;
    form .removeListener('fileBegin',grabTmpPath);
    }
    });


    I created an upload script in node.js using express/formidable. It basically works, but I am wondering where and when to check the uploaded file e. g. for the maximum file size or if the file´s mimetype is actually allowed.

    My program looks like this:

    app.post('/', function(req, res, next) {
        req.form.on('progress', function(bytesReceived, bytesExpected) {
            // ... do stuff
        });
    
        req.form.complete(function(err, fields, files) {
            console.log('\nuploaded %s to %s',  files.image.filename, files.image.path);
            // ... do stuff    
        });
    });
    

    It seems to me that the only viable place for checking the mimetype/file size is the complete event where I can reliably use the filesystem functions to get the size of the uploaded file in /tmp/ – but that seems like a not so good idea because:

    • the possibly malicious/too large file is already uploaded on my server
    • the user experience is poor – you watch the upload progress just to be told that it didnt work afterwards

    Whats the best practice for implementing this? I found quite a few examples for file uploads in node.js but none seemed to do the security checks I would need.

    解决方案

    With help from some guys at the node IRC and the node mailing list, here is what I do:

    I am using formidable to handle the file upload. Using the progress event I can check the maximum filesize like this:

    form.on('progress', function(bytesReceived, bytesExpected) {
        if (bytesReceived > MAX_UPLOAD_SIZE) {
            console.log('### ERROR: FILE TOO LARGE');
        }
    });
    

    Reliably checking the mimetype is much more difficult. The basic Idea is to use the progress event, then if enough of the file is uploaded use a file --mime-type call and check the output of that external command. Simplified it looks like this:

    // contains the path of the uploaded file, 
    // is grabbed in the fileBegin event below
    var tmpPath; 
    
    form.on('progress', function validateMimetype(bytesReceived, bytesExpected) {
        var percent = (bytesReceived / bytesExpected * 100) | 0;
    
        // pretty basic check if enough bytes of the file are written to disk, 
        // might be too naive if the file is small!
        if (tmpPath && percent > 25) {
            var child = exec('file --mime-type ' + tmpPath, function (err, stdout, stderr) {
                var mimetype = stdout.substring(stdout.lastIndexOf(':') + 2, stdout.lastIndexOf('\n'));
    
                console.log('### file CALL OUTPUT', err, stdout, stderr);
    
                if (err || stderr) {
                    console.log('### ERROR: MIMETYPE COULD NOT BE DETECTED');
                } else if (!ALLOWED_MIME_TYPES[mimetype]) {
                    console.log('### ERROR: INVALID MIMETYPE', mimetype);
                } else {
                    console.log('### MIMETYPE VALIDATION COMPLETE');
                }
            });
    
            form.removeListener('progress', validateMimetype);
        }
    });
    
    form.on('fileBegin', function grabTmpPath(_, fileInfo) {
        if (fileInfo.path) {
            tmpPath = fileInfo.path;
            form.removeListener('fileBegin', grabTmpPath);
        }
    });
    

    这篇关于何时在node.js上传脚本中检查文件大小/ mimetype?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆