tre1.jpg


在做node服务端开发的过程中,会经常遇到文件类型校验,具体哪些场景呢,最常用的就是文件上传了。DoraCMS中利用uploadify(前端)和formidable(服务端)来处理上传,但是上传中需要注意安全性的问题。如何保证上传文件安全性呢,有网友总结了一下几点:


一,不能仅仅依赖客户端js进行判断和校验,需要在服务器端进行校验;

二,通过白名单的方式控制允许上传文件的类型,注意不要用黑名单,很容易忽略或者遗漏;

三,校验上传文件的大小和上传的路径;

四,禁止上传.htacess文件,校验上传文件的内容,有时不能仅仅只判断magic num;

(上传.htacess文件在部分配置有问题的php中会覆盖之前的权限控制文件.htacess,导致脚本执行权限的口被撕开)

五,上传文件的目录,不能被服务配置成可以执行脚本的目录;(重点)


doraCMS前端校验比较简单,

//允许上传的文件后缀
'fileTypeExts': filtertype,

仅仅是通过filter来过滤掉不允许上传的文件。

后台也是必须的,因为可以通过修改文件拓展名的方式骗过过滤器上传可执行文件到服务器,这样就无形增加了服务器被攻击的可能性,我们可以这样做(读取二进制流)来校验文件的真实类型:

//获取文件真实类型
getFileMimeType : function(filePath){
    var buffer = new Buffer(8);
    var fd = fs.openSync(filePath, 'r');
    fs.readSync(fd, buffer, 0, 8, 0);
    var newBuf = buffer.slice(0, 4);
    var head_1 = newBuf[0].toString(16);
    var head_2 = newBuf[1].toString(16);
    var head_3 = newBuf[2].toString(16);
    var head_4 = newBuf[3].toString(16);
    var typeCode = head_1 + head_2 + head_3 + head_4;
    var filetype = '';
    var mimetype;
    switch (typeCode){
        case 'ffd8ffe1':
            filetype = 'jpg';
            mimetype = ['image/jpeg', 'image/pjpeg'];
            break;
        case '47494638':
            filetype = 'gif';
            mimetype = 'image/gif';
            break;
        case '89504e47':
            filetype = 'png';
            mimetype = ['image/png', 'image/x-png'];
            break;
        case '504b34':
            filetype = 'zip';
            mimetype = ['application/x-zip', 'application/zip', 'application/x-zip-compressed'];
            break;
        case '2f2aae5':
            filetype = 'js';
            mimetype = 'application/x-javascript';
            break;
        case '2f2ae585':
            filetype = 'css';
            mimetype = 'text/css';
            break;
        case '5b7bda':
            filetype = 'json';
            mimetype = ['application/json', 'text/json'];
            break;
        case '3c212d2d':
            filetype = 'ejs';
            mimetype = 'text/html';
            break;
        default:
            filetype = 'unknown';
            break;
    }
        fs.closeSync(fd);
    return {
        fileType : filetype,
        mimeType : mimetype
    }
}


上面列出来一些比较常用的文件类型16进制码,可以读出文件的真实类型,进一步校验提高文件上传的安全性。下面列出一些其它类型,供您参考:


文件格式文件头(十六进制)
JPEG (jpg)FFD8FFE1
PNG (png)89504E47
GIF (gif)47494638
TIFF (tif)49492A00
Windows Bitmap (bmp)424D
CAD (dwg)41433130
Adobe Photoshop (psd)38425053
Rich Text Format (rtf)7B5C727466
XML (xml)3C3F786D6C
HTML (html)68746D6C3E
Email [thorough only] (eml)44656C69766572792D646174653A
Outlook Express (dbx)CFAD12FEC5FD746F
Outlook (pst)2142444E
MS Word/Excel (xls.or.doc)D0CF11E0
MS Access (mdb)5374616E64617264204A
WordPerfect (wpd)FF575043
Postscript (eps.or.ps)252150532D41646F6265
Adobe Acrobat (pdf)255044462D312E
Quicken (qdf)AC9EBD8F
Windows Password (pwl)E3828596
ZIP Archive (zip)504B0304
RAR Archive (rar)52617221
Wave (wav)57415645
AVI (avi)41564920
Real Audio (ram)2E7261FD
Real Media (rm)2E524D46
MPEG (mpg)000001BA
MPEG (mpg)000001B3
Quicktime (mov)6D6F6F76
Windows Media (asf)3026B2758E66CF11
MIDI (mid)4D546864