# XPath Injection in Smolagents search_item_ctrl_f

- **Severity:** High
- **Signature ID:** `7f3c9d21-4b8e-4a15-9c62-8d5f1e2a6b40`
- **OWASP:** LLM05 (Improper Output Handling)

## Summary

A helper function in Hugging Face's Smolagents library builds web page search queries by directly inserting text into a query template, without sanitizing it. If untrusted text reaches this function, an attacker can break out of the intended search and alter what the underlying automated browser does.

## How the attack works

The vulnerable function search_item_ctrl_f() builds an XPath locator by pasting search text straight into a fixed template: //*[contains(text(), '<TEXT>')]. If the text contains a single quote, that quote closes the string early, and anything after it - operators like or, and, |, or bracket expressions - becomes live XPath logic instead of literal search text. This altered locator is then sent as a real Selenium/WebDriver command (either over HTTP to chromedriver/geckodriver/Grid, or as a subprocess call from generated code), so the injected structure actually executes against the live page. The rule catches this by looking for both the tell-tale template shape and an operator character sitting right after a broken-out quote, together with evidence that a WebDriver session or Selenium code actually ran.

## Why it matters

An attacker who controls the search text can redirect a browser-automation agent's page queries to select different elements than intended - potentially exposing hidden data, clicking unintended controls, or otherwise steering the agent's browser actions away from the user's request.

## What you can do

- Do not pass untrusted or user-supplied text directly into search_item_ctrl_f() or any XPath template built by string concatenation.
- Sanitize or escape single quotes in search text before it reaches XPath-building code, or switch to parameterized/quote-safe locator construction.
- Review any agent workflows where an LLM or external source supplies search terms used in browser automation, and add validation on that input.
- Be aware this detection only covers XPath queries sent through WebDriver (HTTP or subprocess); queries applied in-process to already-fetched HTML via lxml/BeautifulSoup are not visible to this or any current detection and need separate code review.

## Known benign look-alikes

- A genuine page-text search whose term contains an apostrophe immediately followed by an XPath keyword or operator - e.g. searching for "it' and that", "rock 'n' roll/blues", "O'Brien | Ltd". This produces a structurally identical malformed locator with no malicious intent. The bounded [^']{0,300} span plus the requirement that an operator (not a letter) sit directly after the closing quote keeps ordinary apostrophes such as "don't", "boys'" and "O'Brien" from matching, but it cannot separate an unlucky search string from a crafted one - hence action report.
- Hand-written Selenium locators that legitimately extend the same shape, e.g. //*[contains(text(), 'Next') and @role='button'] or a union //*[contains(text(), 'Next')]|//button[@id='next']. These are not produced by search_item_ctrl_f but share the "//*[contains(text(), '" prefix. The //* wildcard prefix requirement makes this uncommon (hand-written selectors usually name a tag) but it is the main residual FP class.
- CI runs of the smolagents test suite or a security regression test that asserts on the unsanitised locator - suppressed by filter_test_code.
- Security documentation, advisories, cheat sheets and pentest reports that transit an HTTP request while quoting an XPath injection payload - suppressed by filter_reference_material.
- An agent sending a Selenium snippet to a model API for review or repair, where the payload rides in a chat completion body rather than a WebDriver command - suppressed by filter_llm_api_payload.

## References

- https://github.com/huggingface/smolagents
- https://cwe.mitre.org/data/definitions/643.html
- https://www.w3.org/TR/webdriver2/#find-elements

---
Source: https://www.netzilo.com/threats/smolagents-xpath-injection
