Skip to content

Malware scanning

The File Service scans every uploaded version for known malware, as a step of processing, before or while it serves the file, as the application chooses. An infected file is quarantined: it is never served again. This page explains the policies, what quarantine does and what your code sees. It is for developers, administrators and evaluators.

Each version is scanned once, after the type and policy checks and the checksum. Its outcome is processing.scan:

processing.scan Meaning
pending Not scanned yet
clean Scanned; nothing known was found
infected Malware was found: the version is quarantined
skipped Not scanned: the application switched scanning off, or the file is larger than 1 GiB
failed The scan could not finish after 5 attempts

A copy or a restored version is a new version and is scanned again.

Three settings of the application decide when a file may be served. An administrator sets them on the console’s Settings page, or a backend with files:config.manage.

Setting Values
scan_policy block_until_clean (default): nothing is served before the scan is clean. async: the file is served at once and quarantined if the scan finds malware. off: no scan
scan_failed_policy block (default): a version whose scan failed is never served. allow: it is served as if it were clean
scan_oversize_policy allow (default): a file too large to scan is served unscanned. block: it is never served

The platform may require scanning; then scan_policy: off is refused with 400 invalid_request.

What a download, a preview, a batch URL, a share link download or the public copy answers:

The version block_until_clean async off
Not scanned yet 409 scan_pending Served Served
clean Served Served Served
Too large to scan scan_oversize_policy scan_oversize_policy Served
failed scan_failed_policy scan_failed_policy Served
infected 409 file_quarantined 409 file_quarantined (not scanned)

scan_pending (409) always means “not now”; its message says why:

Message Why What to do
“The file is not scanned yet; retry after file.ready” block_until_clean and the scan has not answered Show the file as processing; try again on file.ready
“The file is too large to be scanned and the application does not serve unscanned files (scan_oversize_policy: block)” Above 1 GiB under block It will not be served; an administrator can change the policy
“The file could not be scanned and the application does not serve unscanned files (scan_failed_policy: block)” The scan failed under block It will not be served; the owner received file.failed with step: "scan"

In a batch (POST P/files/urls) the entry carries error: "scan_pending" and the other entries are served. ccs-files-client’s waitUntilReady waits while the scan is pending and rejects with processing_failed (step: "scan") when a failed scan stops processing.

When the scan finds malware, the service:

  • moves the bytes out of reach and marks the version quarantined, and the file too when it is the current version (state: "quarantined");
  • deletes the version’s renditions and its public copy, and revokes every share link of the file (they answer 410 share_gone);
  • forgets the version’s extracted text, so content search no longer finds it;
  • publishes file.quarantined to the owner and to the users who manage access to the file, with a push when they are offline;
  • writes the audit row file.quarantined, with the name of what was found.

A quarantined file is never served: its URLs answer 409 file_quarantined and its preview is kind: "none". Nothing releases it. List quarantined files with GET P/search and state=quarantined, and remove one for good with POST P/files/:file_id/purge.

Where What
Live events file.quarantined with file_id, name and signature; file.failed with step: "scan" when a failed scan blocks the file
The file state: "quarantined", processing.scan: "infected"
The Files console A banner on the file’s page saying it was quarantined; the file cannot be opened or downloaded
Your backend The same events through your webhook