Disclaimer:
All information provided on this page was developed by TPimenta LAB. Please consult the official documentation for the most accurate and up-to-date information. We are not responsible for any issues, damages, or data loss that may occur from using this information.

USE AT YOUR OWN RISK.

Cloudflare WAF — Content Scanning Lab

Content Scanning - content scanning attempts to detect content objects, such as uploaded files, and scans them for malicious signatures like malware.

Test file upload scenarios that exercise cf.waf.content_scan.* fields. Requires the zone to have Malicious Uploads Detection enabled (Enterprise + add-on).

ATTENTION: For testing, please remember to disable the WARP client.

Test 1 — Standard File Upload multipart/form-data

Upload any file. If the WAF custom rule is set to Block on cf.waf.content_scan.has_malicious_obj, infected files return 403. Clean files reach the origin.
Waiting for upload…

Test 2 — EICAR Antivirus Test String Should Block

The EICAR test file is an industry-standard, harmless string universally recognised as malware by AV engines. Cloudflare's AV scanner will flag it as infected. Expect a 403 if a block rule exists.
Waiting for EICAR test…

Test 3 — Base64-Encoded File in JSON Body Custom Scan Expression

Some APIs receive files as Base64 strings inside JSON. Configure a custom scan expression such as lookup_json_string(http.request.body.raw, "file") so the scanner knows where to look.
Waiting for JSON test…

Test 4 — Multiple Files in One Request cf.waf.content_scan.num_obj

num_obj counts all content objects. Use rules like cf.waf.content_scan.num_obj > 2 to limit bulk uploads.
Waiting for multi-file upload…

Content Scanning Fields Reference

Field Type Description
cf.waf.content_scan.has_obj Boolean Request contains at least one content object
cf.waf.content_scan.has_malicious_obj Boolean At least one object is malicious (infected/suspicious)
cf.waf.content_scan.num_obj Integer Total number of content objects detected
cf.waf.content_scan.num_malicious_obj Integer Number of malicious content objects
cf.waf.content_scan.obj_sizes Array<Integer> File sizes (bytes) in detection order
cf.waf.content_scan.obj_types Array<String> MIME types in detection order
cf.waf.content_scan.obj_results Array<String> Scan results: clean | suspicious | infected | not scanned
cf.waf.content_scan.has_failed Boolean AV scanner timed out or could not scan an object

How Cloudflare Content Scanning Works

Client sends request
(with file upload)
Cloudflare Edge receives request
Content Scanner
detects objects via heuristics
AV Scanner
(same engine as Zero Trust)
Scan results populate
cf.waf.content_scan.* fields
WAF Custom Rules evaluate fields
Block / Log / Allow

What counts as a content object?

Any payload that is NOT text/html, text/x-shellscript, application/json, text/csv, or text/xml. Includes executables, documents, archives, images, audio/video. Detection is by heuristics — the Content-Type header is ignored since it can be spoofed.

Key limits & behaviours
  • Files scanned up to 50 MB (first 50 MB for larger objects)
  • Password-protected archives: not scanned
  • Archives with >3 recursion levels or >300 files: skipped
  • PGP-encrypted files: not scanned
  • Scanning adds latency (proportional to object size)
  • Detection only — you must create rules to block

Example WAF Custom Rule Expressions
# Block all malicious uploads
(cf.waf.content_scan.has_malicious_obj)

# Block malicious uploads to a specific endpoint
(cf.waf.content_scan.has_malicious_obj and http.request.uri.path contains "/upload")

# Block if scanner could not scan (fail-closed posture)
(cf.waf.content_scan.has_failed)

# Block more than 2 objects in a single request
(cf.waf.content_scan.num_obj > 2 and http.request.uri.path eq "/upload")

# Block bots uploading files
(cf.waf.content_scan.has_obj and cf.bot_management.score lt 10)

# Custom scan expression for Base64 in JSON (configure in dashboard Security->Settings->Malicious uploads detection)
lookup_json_string(http.request.body.raw, "file")