本文讨论了图像文件上传面临的危险,并分别提出了在Java中扫描和验证图像文件的两种解决方案。
(资料图片仅供参考)
译者 | 李睿
审校 | 重楼
直接上传图像文件的过程在客户端用户和网站的底层文件存储实例之间创建了一条高效的路径,极大地有利于客户端/web服务关系的两端。在很大程度上,由于独立开发者项目和小型企业的云存储资源的可用性(以及可负担性)不断提高,人们越来越频繁地上传自己的图像文件,无论在哪里上网,这与对新形式的社会参与和商业的稳定需求同步增长。
然而,文件上传安全性如今成为一个非常严重的问题,而且图像文件很容易被客户端威胁行为者利用。当然,图像文件在这方面并不是唯一的(例如,包括PDF、DOCX等在内的许多常见文件格式,可以容纳各种隐藏的威胁),但它们在互联网上的巨大价值(一个主要的视觉平台)使它们成为恶意内容的更便利的载体之一。
网络攻击者可以将恶意软件和其他恶意代码直接注入图像文件,从而避免被配置不佳的上传安全策略检测到。恶意软件能够以几种不同的方式隐藏在图像文件中——直接附加到文件末尾,通过微小的代码更改巧妙地合并,甚至隐藏在图像的元数据或EXIF数据中。恶意代码通常被设计为远程执行或在文件打开时执行,这意味着存储文档中处于休眠状态、未被检测到的恶意代码可能会等待数天、数周甚至数月,然后突然释放危险内容。网络攻击者不仅可以利用网站的系统:如果一位毫无戒心的客户端用户下载了一个受感染的文件,他们的设备很快就会被入侵或破坏,严重(也许是永久)损害企业的声誉。
缓解图像文件上传威胁,首先要实施强大的病毒和恶意软件检测策略,还需要采取合理的文件上传验证措施。例如,异常大的图像文件可能表明存在隐藏的威胁,因此了解(并可能标准化)图像上传的大小有助于更快地检测威胁。此外,限制允许上传的不同文件扩展名的数量(例如,限制为PNG或JPG)使文件扩展名验证更容易、更有效。文件扩展名和标头也不应该盲目信任——彻底的内容验证应该始终考虑到文件结构和文件编码。
演示两个解决方案
在本文的其余部分中,将演示两个简单的、免费使用的解决方案,它们可以在图像文件上传到云存储之前帮助进行病毒扫描和验证。两者都可以有效地利用互补的、可运行的Java代码示例来构建API调用。这些API分别执行以下功能:
(1)扫描图像文件是否有病毒
(2)验证图像文件
这两个API相互结合使用,可以帮助确保图像上传是有效的,并且没有病毒和恶意软件,从而显著降低与图像文件直接上传相关的风险。
扫描图文件是否有病毒
这个API配备了1700万多个病毒和恶意软件签名,涵盖了特洛伊木马、勒索软件和间谍软件等极其常见的威胁。它也不局限于图像文件(当然还可以扫描PDF、DOCX、XLSX等文档),因此,如果用户的文件上传过程接受多种文件类型,它提供了一些多功能性。所有扫描的文件最终将收到一个“CleanResult:True”或“CleanResult:False”。布尔响应中如果为false,则检测到的病毒的名称将在API响应中提供。
要安装客户机SDK,首先,在Maven POM文件中添加对存储库的引用。Jitpack用于动态编译库:
XML jitpack.io https://jitpack.io
之后,添加对依赖项的引用:
XML com.github.Cloudmersive Cloudmersive.APIClient.Java v4.25
在安装完成后,可以使用以下补充代码示例构建API调用:
Java // Import classes: //import com.cloudmersive.client.invoker.ApiClient; //import com.cloudmersive.client.invoker.ApiException; //import com.cloudmersive.client.invoker.Configuration; //import com.cloudmersive.client.invoker.auth.*; //import com.cloudmersive.client.ScanApi; ApiClient defaultClient = Configuration.getDefaultApiClient(); // Configure API key authorization: Apikey ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey"); Apikey.setApiKey("YOUR API KEY"); // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) //Apikey.setApiKeyPrefix("Token"); ScanApi apiInstance = new ScanApi(); File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on. try { VirusScanResult result = apiInstance.scanFile(inputFile); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling ScanApi#scanFile"); e.printStackTrace(); }
在测试这一解决方案时,建议彻底研究可以安全地触发“CleanResult:False”响应的惰性文件的选项(例如,Eicar文件在这方面通常是一个流行的选择)。
验证图像文件
这个API旨在严格验证数十种常见的输入图像类型,包括JPG、PNG、WEBP、GIF等等。它将识别图像上传中包含的内容是否与其扩展名匹配,文件是否受密码保护,以及文件中是否存在任何错误和警告。如果检测到任何错误,API响应将提供错误的描述、错误的路径和一个供参考的URI。
可以像以前一样安装这个客户端SDK。将这一引用添加到MavenPOM文件存储库中:
XML jitpack.io https://jitpack.io
然后,添加对依赖项的引用:
XML com.github.Cloudmersive Cloudmersive.APIClient.Java v4.25
最后,可以使用下面的现成代码示例来构建API调用:
Java // Import classes: //import com.cloudmersive.client.invoker.ApiClient; //import com.cloudmersive.client.invoker.ApiException; //import com.cloudmersive.client.invoker.Configuration; //import com.cloudmersive.client.invoker.auth.*; //import com.cloudmersive.client.ValidateDocumentApi; ApiClient defaultClient = Configuration.getDefaultApiClient(); // Configure API key authorization: Apikey ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey"); Apikey.setApiKey("YOUR API KEY"); // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) //Apikey.setApiKeyPrefix("Token"); ValidateDocumentApi apiInstance = new ValidateDocumentApi(); File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on. try { DocumentValidationResult result = apiInstance.validateDocumentImageValidation(inputFile); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling ValidateDocumentApi#validateDocumentImageValidation"); e.printStackTrace(); }
原文标题:How To Scan and Validate Image Uploads in Java,作者:Brian O’Neill