Testing for Anti-Virus on File Upload

One of the issues on a standard web app checklist is to test whether or not an application that supports file upload is scanning those files for malware. This article reviews the methodology and highlights the danger of corrupting an EICAR test file so that it no longer acts as a valid test. It is based on an internal presentation I gave, the slides for which are here.


It’s really quite simple – upload a file, download it and compare the hashes. If you upload successfully but don’t download then that’s not sufficient proof – perhaps the file has been silently quarantined. Showing that the hashes of the uploaded and downloaded files are the same proves that the file has not been cleaned up. (If no download feature is available, you can only speculate on the lack of an error message on upload.)

It’s obviously unfair to report a system lacking AV if the file you upload gets only 1 out of 57 hits on VirusTotal, for example. So running the file through VirusTotal and including a screenshot in the report shows the client that the file should have been detected. The output of VirusTotal includes a SHA-256 hash so that nicely ties in with hashing the uploaded and downloaded files, mentioned above.


Which file?

Of course, you don’t want to be uploading real malware. This is where the EICAR test comes in – a widely adopted benign signature that triggers an alert so that you can be sure your anti-virus product is running correctly. So, during a web application assessment, you put together a test file thus:


You upload and download it with no problem – so the files aren’t being checked for malware, right? Wrong. Take a look at the VirusTotal result for this file:


It would be unfair to report a lack of anti-virus scanning using this file as a test case – and not, as we’ll soon see, because most of the AVs have missed it.

Okay, what about this Word document?


Hopefully that was a no-brainer. This file got no hits on VirusTotal because the document text isn’t stored exactly as it’s seen and thus the EICAR signature was not in the raw file at all.

The EICAR test

If you haven’t already guessed, the EICAR test specification is stricter than the appearance of that well-known string. According to the EICAR site “any anti-virus product that supports the EICAR test file should detect it in any file providing that the file starts with the following 68 characters…X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*“. Don’t be fooled by the printable ASCII, though – the file is in fact executable, shown below on a Windows XP SP3 machine:


Let’s take that Word doc and, using a hex editor, stick the EICAR signature at the front:


Now VirusTotal reports 26 out of 56 (46%). In contrast when we put the signature elsewhere in the file (middle or end) we get 1 out of 57 hits.

Technically the anti-virus products that haven’t reported the file are quite right not to do so because there’s another condition that the file “is exactly 68 bytes long”. The spec goes on to say, though, that “it may be optionally appended by any combination of whitespace characters with the total file length not exceeding 128 characters. The only whitespace characters allowed are the space character, tab, LF, CR, CTRL-Z”.

So let’s truncate the Word doc to 112 bytes – and this time VirusTotal reports 34 out of 56 hits (61%), compared to the original 26 (46%). As you can imagine, as we edit the file to get closer and closer to the original EICAR file, the hit rate goes up and up.

In summary

When testing file uploads for the presence of anti-virus scanning, the test file should be picked up by a significant number of AVs otherwise it’s not a fair test. To this end, it’s safest to use the EICAR file – but if you mess with the original too much (even if the signature is still intact), you might inadvertently create a file that isn’t an EICAR test at all. The specification for the EICAR test file is actually quite strict, although AVs tend to be overzealous in reporting it.

The best approach is simply to rename the EICAR test file to a file format the application allows you to upload, e.g. change eicar.com to eicar.pdf. One potential niggle is that the file is no longer in a valid format for the file type it’s purporting to be, e.g. PDFs don’t start with X50!P%@AP so if there’s any file content analysis being done, then the file may be rejected. Depending on the error, this could be taken as evidence that AV is running when in fact it’s not, so other tests are required to confirm this. If text files are allowed, always use the original EICAR test file as a .txt.

Finally, remember that the aim of this check is not to qualitatively assess the anti-virus, you’re really only aiming to prove whether or not AV is running. Once you have proof that it is, stop. It’s really all you can expect to check – and all that should be expected from you within the bounds of a standard application pentest.

3 thoughts on “Testing for Anti-Virus on File Upload

  1. momses

    thanks for you article.

    I have a question:

    I’m using a CPanel to manage my website. the website is created with wordpress. CPanel is delivered with antivirus clamAV. but it’s not a realtime antivirus. cause I can upload on my wordpress library a file with eicar virus signature.this file is a .jpeg. So, is it a simple way to prevent from this? what kinf of antivirus do you recommanded me?

    Thanks in advance for your answer!


    1. Jerome Post author

      Hi. As this article explains, be careful with the file you’re using for testing. If it’s a regular JPEG file with the EICAR signature embedded as, say, metadata, that doesn’t meet the true EICAR standard and so AV engines are within their rights to ignore it. Some AVs ignore it anyway. Try submitting your test file to Virus Total to get an idea of how good a test it is (and look out for the Clam AV response in particular of course).


Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>