---
title: "Use ClamAV to scan uploaded files · Agent Wranglers"
url: https://agentwranglers.se/playbook/stack/databases-and-storage/clamav
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Use ClamAV to scan uploaded files

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Databases and storage](https://agentwranglers.se/playbook/stack/databases-and-storage.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: STK-94
- Level: Recommended
- Chapter: [Databases and storage](https://agentwranglers.se/playbook/stack/databases-and-storage)
- Rule: Scan every uploaded file with ClamAV on its long-term support line, and fetch new signatures at least once a day.
- Cost: Open source. GPL-2.0 licence, free to run on your own servers. Cloud storage providers sell malware scanning as a paid extra.
- How: ClamAV first came out in 2002, and Cisco Talos maintains it under GPL-2.0. Version 1.4 is the current long-term support line. Each such line gets fixes for three years from its first release, so 1.4 runs to August 2027. Version 1.4.6 shipped on 7 August 2026. The `clamav/clamav` image had about 78 million pulls on Docker Hub in October 2026. Run the `clamd` daemon with `freshclam`, which fetches new signatures. The app streams each file to `clamd` over its socket, so it needs no extra library. Set the size limits and the quarantine as [Scan files for malware before anyone opens them](https://agentwranglers.se/playbook/api-design/files-and-uploads/scan-uploads) says. Choose something else when files land in a cloud bucket whose provider sells scanning, such as GuardDuty Malware Protection for S3. Record that as a paid pick.
- Check: `clamd --version` reports 1.4 or a newer long-term support line, with a signature date less than 24 hours old. Scanning the EICAR test file reports `FOUND`.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Shell example

```sh
docker run -d --name clamav -p 3310:3310 clamav/clamav:1.4
clamdscan --stream --no-summary quarantine/invoice-7.pdf
```

### Python example

```python
import socket
import struct

CHUNK_BYTES = 64 * 1024

def is_clean(path: str, host: str = "clamav.internal.example.com", port: int = 3310) -> bool:
    with socket.create_connection((host, port)) as conn, open(path, "rb") as upload:
        conn.sendall(b"zINSTREAM\0")
        while chunk := upload.read(CHUNK_BYTES):
            conn.sendall(struct.pack("!L", len(chunk)) + chunk)
        conn.sendall(struct.pack("!L", 0))
        return conn.recv(4096).strip(b"\0").endswith(b"OK")
```

## Sources

- [OWASP File Upload Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html)

## Related rules

- [Scan files for malware before anyone opens them](https://agentwranglers.se/playbook/api-design/files-and-uploads/scan-uploads) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/stack/databases-and-storage/clamav">Agent Wranglers software choices playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Avoid the MinIO community edition](https://agentwranglers.se/playbook/stack/databases-and-storage/avoid-minio-community)
- [Databases and storage](https://agentwranglers.se/playbook/stack/databases-and-storage)
