When do I need to check the file size / mimetype in node.js upload script?

I created a load script in node.js using express / majorable. This basically works, but I wonder where and when to check the downloaded e file. d. for the maximum file size or if the actual file type is indeed 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 to check the mimetype / file size is an event completewhere I can reliably use the file system functions to get the size of the downloaded file in /tmp/, but this seems like a not-so-good idea, because:

  • possibly a malicious / too large file is already uploaded to my server
  • - , , .

? node.js, , , , .

+5
2

node IRC node, :

formable . progress, :

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

mimetype . progress, , , file --mime-type . :

// 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);
    }
});
+3

All Articles