ASVS V5.4.3 requires that files obtained from untrusted sources are scanned by antivirus software so you do not serve known malicious content. It is a Level 2 requirement.
The risk is not only to your server. If one user uploads a trojan and another user downloads it from your domain, your service just delivered malware with your name on it.
Why it matters
Upload features are a distribution channel. Scanning will not catch everything, but it removes the commodity threats cheaply, and it gives you a record that you tried.
Treat any file that came from outside your team as untrusted. That includes user uploads, files fetched from a URL, attachments pulled from inbound email and files synced from partner systems.
How to implement it
Use a quarantine flow. Store the upload in a private location, mark it pending, scan, and only then make it downloadable.
import socket
def clamav_scan(path):
with socket.create_connection(("clamav", 3310), timeout=30) as s:
s.sendall(f"SCAN {path}\n".encode())
reply = s.recv(4096).decode()
return reply.strip().endswith("OK")
def process_upload(rec):
if clamav_scan(rec.quarantine_path):
move_to_public_store(rec)
rec.status = "clean"
else:
delete_file(rec.quarantine_path)
rec.status = "rejected"
rec.save()
Keep signatures updated, set a size limit, and fail closed: if the scanner is down, the file stays pending.
Run the scanner in its own container with no access to your database or secrets. Limit the file size and the archive depth the scanner will open, so a decompression bomb cannot exhaust it. Store the scan result and signature version with the file record so you can rescan later when definitions improve.
How to test it
Upload the harmless EICAR test string saved as a file. It must end in the rejected state and never appear in a download listing. Then stop the scanner and upload a clean file. It must stay pending.
Common mistakes
-
Serving the file while the scan is still running.
-
Failing open when the scanner times out.
-
Scanning only the first layer of an archive.
-
Never updating signatures.
-
Treating a clean scan as proof of safety. Pair it with content type checks and serving files from a separate domain.
Quick check
What should happen if the scanner is unreachable?
The file stays in quarantine. Serving unscanned files defeats the control.