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")