How To Scan and Validate Image Uploads in Java
This article discusses the dangers of image file uploads and presents two solutions for virus scanning and validating image files respectively.
Join the DZone community and get the full member experience.
Join For FreeDirect image upload processes create a highly efficient path between client-side users and a website’s underlying file storage instances, significantly benefiting both ends of the client/web service relationship. Due largely to the ever-increasing availability (and affordability) of cloud storage resources for independent developer projects and small business ventures, we see the option to upload our own image files more and more frequently everywhere we look online, growing in tandem with steady demand for new forms of social engagement and commerce.
The trouble is, however, that file upload security is a very serious issue - and image files are rather easily exploited by client-side threat actors. Image files aren’t unique in this respect, of course (many common file formats including PDF, DOCX, etc., for example, can house a variety of hidden threats), but their monumental value on the internet – a mostly visual platform – sets them apart as one of the more expedient vessels for malicious content.
Attackers can easily inject malware and other malicious code directly into image files using honed steganographic techniques, reliably avoiding detection from poorly configured upload security policies. Malware can be hidden in several different ways within an image file – bluntly appended to the end of a file, subtly incorporated through minor code changes, or even concealed in the image’s metadata or EXIF data. Malicious code is generally designed to execute remotely or upon file opening, meaning dormant, undetected threats in storage can wait days, weeks, or even months before suddenly unleashing dangerous content. It isn’t just the website’s system they can exploit, too: if an unsuspecting client-side user downloads an infected file, their device can be quickly compromised, badly (perhaps permanently) damaging the website’s reputation.
Mitigating image file upload threats starts with implementing powerful virus and malware detection policies, and it also involves putting sensible file upload validation measures in place. Unusually large image files, for example, might indicate a hidden threat, so understanding (and possibly standardizing) the size of image uploads can help facilitate quicker threat detection. Moreover, limiting the number of different file extensions allowed for upload (for example, limiting to PNG or JPG) makes file extension validation easier and more efficient to carry out. File extensions and headers shouldn’t be trusted blindly, either – thorough content verification should always take the file structure and file encoding into consideration.
Demonstration
In the remainder of this article, I’ll demonstrate two simple, free-to-use solutions which can help virus scan and validate image file uploads prior to reaching cloud storage. Both can be taken advantage of efficiently using complementary, ready-to-run Java code examples to structure your API calls. These APIs perform the following functions respectively:
- Scan image files for viruses
- Validate image files
Used in conjunction with one another, both APIs can help ensure image uploads are valid and free of viruses and malware, significantly mitigating the risks associated with direct image file uploads.
Scan an Image File for Viruses
This API is equipped with more than 17 million virus and malware signatures, covering extremely common threats like trojans, ransomware, and spyware among others. It isn’t limited to image files either (you can also scan documents like PDF, DOCX, XLSX, etc.), so it offers some versatility if your file upload process accepts multiple file types. All scanned files will ultimately receive a "CleanResult: True" or "CleanResult: False" Boolean response; if false, the name of the detected virus will be provided in the API response.
To install the client SDK, first, add a reference to the repository in your Maven POM File. Jitpack is used to dynamically compile the library:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
After that, add a reference to the dependency:
<dependencies>
<dependency>
<groupId>com.github.Cloudmersive</groupId>
<artifactId>Cloudmersive.APIClient.Java</artifactId>
<version>v4.25</version>
</dependency>
</dependencies>
With installation out of the way, you can structure your API call using the following complementary code examples:
// 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();
}
When testing this solution, I’d recommend thoroughly researching options for inert files that can safely trigger a "CleanResult: False" response (Eicar files, for example, are often a popular choice in this regard).
Validate an Image File
This API is designed to rigorously validate dozens of common input image types, including JPG, PNG, WEBP, GIF, and many more. It’ll identify whether the content contained within an image upload matches its extension, whether the file is password protected, and if there are any errors and warnings present within the file. If any errors are detected, the API response will provide a description of the error, a path to the error, and a URI for reference.
You can install this client SDK the same way as before. Add this reference to your Maven POM file repository:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Then add a reference to the dependency:
<dependencies>
<dependency>
<groupId>com.github.Cloudmersive</groupId>
<artifactId>Cloudmersive.APIClient.Java</artifactId>
<version>v4.25</version>
</dependency>
</dependencies>
Finally, you can structure your API call using the ready-to-run code examples below:
// 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();
}
Opinions expressed by DZone contributors are their own.
Comments