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.
The scan step
Section titled “The scan step”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.
The policies
Section titled “The policies”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) |
Why a URL answers scan pending
Section titled “Why a URL answers scan pending”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.
Quarantine
Section titled “Quarantine”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.quarantinedto 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.
What the owner sees
Section titled “What the owner sees”| 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 |