The malicious uploads detection is a traffic detection that scans files and other content uploaded to your application for malware.
When you turn on this detection, the WAF inspects incoming uploads and checks them for malicious signatures. The scan results are available as fields you can use in custom rules and rate limiting rules to act on requests containing malicious content.
Once you turn on this detection, Cloudflare inspects all incoming traffic and identifies content objects automatically.
When Cloudflare detects one or more content objects in a request, it sends them to an antivirus (AV) scanner for analysis. The AV scanner is the same one used in Cloudflare Zero Trust.
Based on the scan results, the detection populates fields you can reference in rule expressions. For example, you can create a rule to block requests with malicious files, or a more specific rule that also matches on file size, file type, or URI path.
A content object is a file or binary payload in a request that Cloudflare identifies as scannable content. The malicious uploads detection uses heuristics to find content objects automatically, without relying on the request's Content-Type header (since this header can be manipulated).
The following content types are excluded from scanning: text/html, text/x-shellscript, application/json, text/csv, and text/xml. All other detected content is treated as a content object. Common examples include:
- Executable files (for example,
.exe,.bat,.dll, and.wasm) - Documents (for example,
.doc,.docx,.pdf,.ppt, and.xls) - Compressed files (for example,
.gz,.zip, and.rar) - Image files (for example,
.jpg,.png,.gif,.webp, and.tif) - Video and audio files
If Cloudflare detects a malicious object but cannot determine its exact content type, it reports the object as application/octet-stream.
Content scanning can check the following content objects for malicious content:
- Uploaded files in a request
- Portions of the request body for multipart requests encoded as
multipart/form-dataormultipart/mixed - Specific JSON properties in the request body (containing, for example, files encoded in Base64) according to the custom scan expressions you provide
The content scanner inspects up to the first 50 MB of a request body. When a request contains more than one content object, for example a submitted HTML form with several file inputs, all the content objects share this 50 MB.
Every content object within the first 50 MB of the request body is checked and reported individually.
Content beyond the first 50 MB is handled as follows:
- If the request body is not multipart (for example, a raw file upload or a single JSON property) and is larger than 50 MB, the scanner analyzes the first 50 MB of the object and provides scan results based on that portion.
- If the request body is multipart (
multipart/form-dataormultipart/mixed) and larger than 50 MB in total, content objects that fall entirely within the first 50 MB are scanned as usual. The content object that straddles the 50 MB boundary is not scanned, and neither is any content object that follows it. This applies even when the multipart request contains only one file, since a single-part multipart upload is still a multipart body.
Sometimes, you may want to specify where to find the content objects, such as when the content is a Base64-encoded string within a JSON payload. For example:
{ "file": "<BASE64_ENCODED_STRING>" }In these situations, configure a custom scan expression to tell the content scanner where to find the content objects. For more information, refer to Configure a custom scan expression.
For more information and additional examples of looking up fields in nested JSON payloads, refer to the lookup_json_string() function documentation.
When content scanning is enabled, you can use the following fields in WAF rules:
| Field | Description |
|---|---|
Has content object cf.waf.content_scan.has_obj Boolean |
Indicates whether the request contains at least one content object. |
Has malicious content object cf.waf.content_scan.has_malicious_obj Boolean |
Indicates whether the request contains at least one malicious content object. |
Number of malicious content objects cf.waf.content_scan.num_malicious_obj Integer |
The number of malicious content objects detected in the request (zero or greater). |
Content scan has failed cf.waf.content_scan.has_failed Boolean |
Indicates whether the file scanner was unable to scan any of the content objects detected in the request. |
Content scan truncated cf.waf.content_scan.truncated Boolean |
Indicates whether the request body exceeded the size limit for content scanning and was truncated before scanning, meaning the scan results may be incomplete. Refer to Size limit. |
Number of content objects cf.waf.content_scan.num_obj Integer |
The number of content objects detected in the request (zero or greater). |
Content object size cf.waf.content_scan.obj_sizes Array<Integer> |
An array of file sizes in bytes, in the order the content objects were detected in the request. |
Content object type cf.waf.content_scan.obj_types Array<String> |
An array of file types in the order the content objects were detected in the request. |
Content object result cf.waf.content_scan.obj_results Array<String> |
An array of scan results in the order the content objects were detected in the request. Possible values: clean, suspicious, infected, and not scanned. |
For examples of rule expressions using these fields, refer to Example rules.