An extraction caller did not have to supply an obvious js_code field to make the browser run code. Some Crawl4AI selector values were interpolated into page.evaluate expressions, and wait conditions could take a JavaScript branch. Passing a selector as a string gave the operator a type check but did not prevent the browser from interpreting parts of that…
Case · DiggingBeagle record
Crawl4AI selector and wait expressions became executable browser JavaScript
Crawl4AI accepted selector and wait options that became executable JavaScript despite restrictions on explicit user-provided script.
Crawl4AI Docker versions 0.9.0 to 0.9.4, with access to affected request configuration; browser-context script execution demonstrated, not Python server-side code execution. Fixed in 0.9.5.
Assessment profile
Assessment method- Setting
- research demonstration
- Exploitation
- demonstrated
- Impact
- Band 2 of 4
- Evidence
- Grade B
- Remediation
- fixed reported
- AI role
- AGAINST AI
Basis and provenance
GHSA-qj46-wp7m-rgj8 documents string interpolation into page.evaluate and permissive wait_for evaluation. The bounded browser-side code effect is demonstrated and the 0.9.5 update changes selector handling and untrusted wait semantics. No real-world victims were shown.
Impact basis: Untrusted CSS selector and wait expression values became executable JavaScript within the browser page, leading to an observable browser-origin request. This does not show host-process Python execution or unrestricted egress.
Assessed Oct 19, 2026 using diggingbeagle.assessment/1.
Evidence basis: CLM-CRAWL4AI-SELECTOR-JS · GHSA-qj46-wp7m-rgj8: Crawl4AI selector and wait expressions became executable browser JavaScript
At a glance
The developer exposed a data-like selector field, but browser evaluation turned that field into executable source. Rejecting an explicit script field did not prevent script execution through a second input.
Read the implicationsThe demonstrated effect is JavaScript execution in the browser context, not arbitrary Python server command execution. The affected release path was corrected by treating selectors as data and limiting untrusted waits to CSS in v0.9.5.
Limits and uncertaintyFull account
An extraction caller did not have to supply an obvious js_code field to make the browser run code. Some Crawl4AI selector values were interpolated into page.evaluate expressions, and wait conditions could take a JavaScript branch. Passing a selector as a string gave the operator a type check but did not prevent the browser from interpreting parts of that string as executable statements.
The researchers demonstrated a browser-context network request to a controlled listener. That is significant because it crosses the intended restriction on user-supplied scripts, yet it is not evidence of Python host remote code execution or automatic access to private internal services. The browser's own sandbox and network policy still determine downstream reach.
The 0.9.5 remediation passes CSS selectors as data and constrains untrusted wait predicates to CSS forms. To test it, exercise every call to page.evaluate, including alternate extraction strategies and error handlers. Rejecting the most obvious script field is insufficient while neighboring parameters are compiled into JavaScript.
Claims & evidence
CLM-CRAWL4AI-SELECTOR-JSUntrusted selector and wait parameters were interpreted as JavaScript in browser evaluation paths, despite separate rejection of direct js_code configuration.supported
Basis: reported finding
- supportsGHSA-qj46-wp7m-rgj8: Crawl4AI selector and wait expressions became executable browser JavaScriptprimary disclosure
css_selector and wait_for configuration; fixed v0.9.5
Implications
The developer exposed a data-like selector field, but browser evaluation turned that field into executable source. Rejecting an explicit script field did not prevent script execution through a second input.
Controls and mitigations
- Pass CSS selectors as values to browser APIs and use a non-executable predicate grammar for untrusted waits.
Unknowns and contradictions
- The demonstrated effect is JavaScript execution in the browser context, not arbitrary Python server command execution. The affected release path was corrected by treating selectors as data and limiting untrusted waits to CSS in v0.9.5.
Sources and citation
Material revision history
- Oct 19, 2026 · Published version · first publication · revision 174
- Oct 19, 2026 · Canonical change recorded · material revision · revision 175Public fields changed: assessment_profile