我遇到了一个关于在 SailsJS 应用程序中上传图像的有趣问题。我想将图像从前端上传到后端(NodeJs,SailsJS),验证图像(图像),以确保图像不包含恶意数据(如图像内容中的隐藏脚本),然后发送此图像到 AWS 存储(S3 存储桶))。
在前端,一切都按照 SailsJS 的要求完成(文本字段在表单顶部,文件在底部)。
上传工具:
对于图片上传,我使用了 SailsJS 中的内置模块skipper (skipper-better-S3) 。Skipper 扩展了 Sails 和 Express 中使用的 HTTP 正文解析器。
为了实现这一点,我使用下面提到的代码:
Vault.read((err, result) => {
if (err) {
console.log('Vault S3 Error', err);
} else {
request.file('logo').upload({
adapter: require('skipper-better-s3'),
key: result.access_key,
secret: result.secret_key,
bucket: sails.config.s3.bucket,
maxBytes: sails.config.globals.multipleMaxLogoSize,
dirname: `some-directory/${client.id}/logo`,
s3config: {
signatureVersion: 'v4',
sslEnabled: true,
sessionToken: result.security_token
},
s3params: {
ACL: 'private',
SSEKMSKeyId: process.env.AWS_S3_KMS_KEY_ARN,
ServerSideEncryption: 'aws:kms',
}
}, (error, uploadedFiles) => {
if (uploadedFiles.length === 0 ? true : Utility.isValidImage(uploadedFiles[0].filename)) {
if (error) {
sails.log.error(error);
return response.serverError();
}
if (uploadedFiles.length > 0) {
uploadedFiles.forEach(uploadedFile => { client.logo = `/logo/${client.id}/${uploadedFile[0].fd.split('/').pop()}`;
client.displayName = request.body.displayName ? request.body.displayName : client.displayName;
client.save().then(() => {
return response.ok({});
}, (error) => {
sails.log.error(error);
return response.serverError(error);
}
)})
} else if (conditionForBadRequest) {
return response.badRequest();
}
} else {
sails.log.error('Invalid Image Type');
return response.badRequest('Invalid Image Type');
}
});
}
})
此代码片段可以检查图像是否具有正确的扩展名(结尾),但它不允许我们检查图像是否包含恶意脚本(跨站脚本、持久性 XSS)。
基于上述,我有两个问题:
如何检查上传的图像(它的内容)是否包含恶意脚本,因为我们知道图像内容可以在某些工具(Burp Suite)的帮助下被截获?
验证图像的最佳位置是什么?也许最好在 request.file('logo').upload() 函数的 saveAs 属性上做?
任何帮助表示赞赏。