Skip to content

Malware scan of uploads as a separate service

Context and Problem Statement

People, agents and imports upload files. Other people open them, agents process them. A file should be served only after a malware scan has checked it. How does the server scan without tying its own stability, license and memory planning to a virus scanner?

Decision Drivers

  • No unchecked byte reaches receivers or agents (fail closed).
  • A crash or out-of-memory condition of the scanner must not affect the server.
  • The license of the server stays Apache-2.0.
  • Runs self-hosted without data flowing out to third parties.
  • Replaceable by other engines.

Considered Options

  • ClamAV daemon (clamd) as a separate service, addressed over the INSTREAM protocol, with a small custom client behind a port Scanner
  • libclamav via cgo in the server process
  • External scan service in the cloud
  • ICAP interface to any virus scanner
  • No scan

Decision Outcome

Chosen option: "ClamAV daemon as a separate service over INSTREAM", because it separates process, memory and license from the server and no data leaves the premises. Default file.scan.mode = required: if clamd is not ready, files stay pending and are not served. Hitting the size and depth limits (AlertExceedsMax yes) counts as error, not as clean. Details: 12-files.md section 5.

Consequences

  • Good, because a crash or a reload of the signatures in clamd does not stop the server.
  • Good, because the protocol is small (length-framed chunks, end with length 0) [Q1, verified] and a custom client needs no unmaintained library.
  • Good, because the port Scanner can later take ICAP or other engines.
  • Bad, because ClamAV needs a lot of memory (according to the project at least 3 GiB, better 4 GiB) and takes a long time to load at startup [Q2, verified]; small installations feel this.
  • Bad, because clamd on TCP neither authenticates nor encrypts [Q1, verified]; the service must be reachable only in the internal network or over a Unix socket.
  • Bad, because encrypted archives are not checked for their content by default (AlertEncrypted no); this is a documented residual risk.

Confirmation

  • Integration test with a real clamd container: EICAR becomes infected and is never served.
  • Test with a stopped clamd: the file stays pending, a fetch returns 409 file_not_ready.
  • Test with an archive beyond MaxRecursion: result error.
  • Startup check: the server does not start if file.max_upload_bytes is larger than file.scan.clamd_stream_max_bytes and the scan is required.
  • Architecture rule: no cgo import of a scanner library in the server.

Pros and Cons of the Options

ClamAV daemon as a separate service over INSTREAM

  • Good, because of process and memory separation.
  • Good, because separate programs communicating over sockets normally do not form a combined work according to the GPL FAQ [Q3, verified]; ClamAV itself is under GPL-2.0 [Q4, verified]. The legal assessment stays with the instance operator (no legal advice).
  • Neutral, because an official image for amd64 and arm64 exists (clamav/clamav-debian) [Q5, verified].
  • Bad, because another container with a high memory need runs.

libclamav via cgo in the server process

  • Good, because there is no network path and no serialization.
  • Bad, because the memory of the signatures lies in the server process and an error stops the server.
  • Bad, because linking against GPL code affects the license of the server.
  • Bad, because cgo makes the static binary and multi-arch builds harder.

External scan service in the cloud

  • Good, because there are no on-site operations.
  • Bad, because files go to third parties (data protection, processing by a processor) and the service is not necessarily reachable in private networks.

ICAP interface

  • Good, because commercial virus scanners in companies often speak ICAP.
  • Neutral, because the port Scanner can take this adapter later.
  • Bad as the default, because ICAP with ClamAV needs another intermediary service.

No scan

  • Good, because there is nothing to operate.
  • Bad, because malware reaches people and agents unchecked. It remains only as an explicit mode off for development and very small installations, visibly marked.

More Information

  • Sources (retrieved 2026-10-10): Q1 https://docs.clamav.net/manual/Usage/ClamdProtocol.html [verified]; Q2 https://docs.clamav.net/manual/Installing/Docker.html [verified]; Q3 https://www.gnu.org/licenses/gpl-faq.html [verified]; Q4 https://raw.githubusercontent.com/Cisco-Talos/clamav/main/COPYING.txt [verified]; Q5 https://hub.docker.com/v2/repositories/clamav/clamav-debian/tags/stable [verified]; clamd options https://raw.githubusercontent.com/Cisco-Talos/clamav/main/etc/clamd.conf.sample [verified].
  • Required settings for clamd and result mapping: 12-files.md sections 5.2 and 5.4. Compose stack: 16-operations.md.