Introduction
In the slurpcode/slurp Go project, a high-severity vulnerability was identified in the dependency tree through the go.mod file. The project depends on github.com/antchfx/xpath at version v1.3.3, which contains a critical flaw: certain boolean XPath expressions can cause the evaluation engine to enter an infinite loop, effectively hanging the application and consuming all available CPU resources.
This matters because the slurp project uses github.com/gocolly/colly/v2 for web scraping, which transitively depends on antchfx/htmlquery and antchfx/xmlquery—both of which rely on antchfx/xpath for XPath expression evaluation. Any scraped HTML or XML content that triggers XPath evaluation with a malicious boolean expression could bring the entire application to a halt.
The Vulnerability Explained
What Goes Wrong
The github.com/antchfx/xpath library is a Go implementation of the XPath 1.0 specification, used to navigate and query XML/HTML document trees. When evaluating boolean XPath expressions (expressions using and, or, not(), true(), false(), or comparison operators), the library's internal evaluation loop in versions prior to 1.3.6 can fail to reach its exit condition under specific crafted inputs.
Consider the dependency chain in this project:
github.com/gocolly/colly/v2
→ github.com/antchfx/htmlquery v1.3.4
→ github.com/antchfx/xpath v1.3.3 ← VULNERABLE
→ github.com/antchfx/xmlquery v1.4.4
→ github.com/antchfx/xpath v1.3.3 ← VULNERABLE
Attack Scenario
An attacker who can influence the content being scraped—or who can inject XPath expressions into the application's query logic—could craft a boolean XPath expression that triggers the infinite loop. For example:
- The
slurpapplication uses Colly to scrape a web page - The scraping logic uses XPath selectors (via
htmlqueryorxmlquery) to extract data - If an attacker controls a page being scraped, they could structure the DOM in a way that, combined with certain XPath boolean predicates, triggers the infinite loop
- Alternatively, if the application accepts user-provided XPath expressions, a direct attack payload could be submitted
The result: the goroutine evaluating the XPath expression never returns, the CPU spins at 100%, and the application becomes completely unresponsive. In a server context, this is a classic resource exhaustion DoS.
Real-World Impact
For the slurp project specifically:
- Web scraping becomes a DoS vector: Any malicious website in the crawl queue could hang the scraper
- Resource exhaustion: In containerized deployments, this could trigger OOM kills or CPU throttling affecting co-located services
- No timeout recovery: Without explicit context cancellation, the infinite loop persists until the process is killed
The Fix
The fix is straightforward but comprehensive—upgrading the vulnerable dependency and its ecosystem of related packages to ensure compatibility:
Before (Vulnerable)
// go.mod - vulnerable dependency versions
require (
github.com/antchfx/htmlquery v1.3.4 // indirect
github.com/antchfx/xmlquery v1.4.4 // indirect
github.com/antchfx/xpath v1.3.3 // indirect ← VULNERABLE
)
After (Fixed)
// go.mod - patched dependency versions
require (
github.com/antchfx/htmlquery v1.3.5 // indirect
github.com/antchfx/xmlquery v1.5.0 // indirect
github.com/antchfx/xpath v1.3.6 // indirect ← PATCHED
)
Why Multiple Dependencies Changed
The fix wasn't limited to just bumping antchfx/xpath. Several related changes were necessary:
github.com/antchfx/xpathv1.3.3 → v1.3.6: The core fix—patches the infinite loop in boolean expression evaluationgithub.com/antchfx/htmlqueryv1.3.4 → v1.3.5: Updated to depend on the patched xpath versiongithub.com/antchfx/xmlqueryv1.4.4 → v1.5.0: Same reason—ensures the new xpath version is pulled ingithub.com/PuerkitoBio/goqueryv1.10.2 → v1.11.0: Compatibility updategolang.org/x/netv0.38.0 → v0.47.0: Transitive dependency update for compatibilitygolang.org/x/textv0.23.0 → v0.31.0: Transitive dependency update- Go version
1.23.0→1.24.0: Minimum Go version bumped to support newer dependency features
Additionally, a duplicate dependency line was cleaned up:
// Before: duplicate entry
github.com/urfave/cli/v3 v3.11.0
github.com/urfave/cli/v3 v3.11.0
// After: corrected to single entry
github.com/urfave/cli/v2 v2.27.7
This is important because the go.mod file is the single source of truth for dependency resolution in Go modules. The go.sum file was also updated to reflect the new checksums for all updated packages.
Prevention & Best Practices
1. Automated Dependency Scanning
Use tools like Trivy, Snyk, or Go's native govulncheck to continuously monitor your dependency tree:
# Check for known vulnerabilities in Go dependencies
govulncheck ./...
# Or using Trivy
trivy fs --scanners vuln .
2. Pin and Audit Dependencies
Always review what your transitive dependencies pull in. In this case, the vulnerability was three levels deep in the dependency tree:
your-app → colly → htmlquery → xpath (vulnerable)
3. Implement Timeouts for XPath Evaluation
Even with patched libraries, defense in depth matters:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Use context-aware APIs where available
result, err := htmlquery.QueryWithContext(ctx, doc, xpathExpr)
4. Validate XPath Expressions
If your application accepts user-provided XPath expressions, validate them before evaluation:
// Compile XPath to catch syntax errors early
_, err := xpath.Compile(userProvidedXPath)
if err != nil {
return fmt.Errorf("invalid xpath expression: %w", err)
}
5. Keep Dependencies Current
Set up automated dependency update tools (Dependabot, Renovate, or Orbis AppSec) to receive timely notifications about security patches.
Key Takeaways
- Transitive dependencies are attack surface: The vulnerable
antchfx/xpathv1.3.3 was never directly imported byslurp, but it was reachable through Colly's HTML/XML query packages—making it exploitable through the scraping pipeline. - Boolean XPath expressions are a non-obvious DoS vector: Developers rarely think of XPath boolean logic as dangerous, but the infinite loop in
antchfx/xpathproves that any input-processing loop without guaranteed termination is a risk. - Dependency upgrades often cascade: Fixing one library (xpath v1.3.3 → v1.3.6) required updating five other packages and the Go version itself to maintain compatibility—this is why automated tooling is essential.
- Duplicate dependency entries (
urfave/cli/v3listed twice) signal maintenance debt: The go.mod file had a duplicate line that was also corrected in this fix, suggesting the dependency file hadn't been carefully reviewed recently. - "Not confirmed reachable" still warrants fixing: Even though the scanner noted the vulnerability was "present in dependency tree, not confirmed reachable," the fix was applied because the Colly scraping pipeline makes XPath evaluation highly likely during normal operation.
How Orbis AppSec Detected This
- Source: Untrusted HTML/XML content fetched during web scraping via
github.com/gocolly/colly/v2, which passes document trees to XPath evaluation - Sink:
github.com/antchfx/xpathv1.3.3 boolean expression evaluation engine (internal loop with unreachable exit condition) - Missing control: No loop termination guarantee in the xpath library's boolean expression evaluator; no timeout wrapper around XPath evaluation calls
- CWE: CWE-835 (Loop with Unreachable Exit Condition)
- Fix: Upgraded
github.com/antchfx/xpathfrom v1.3.3 to v1.3.6, which patches the boolean expression evaluation loop to guarantee termination
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-32287 demonstrates a subtle but dangerous class of vulnerability: infinite loops triggered by crafted input in parsing libraries. The antchfx/xpath library is widely used across the Go ecosystem for HTML and XML processing, making this a high-impact issue. The fix—upgrading from v1.3.3 to v1.3.6—is simple to apply but required careful coordination of multiple transitive dependencies.
For Go developers working with web scraping, XML processing, or any XPath evaluation: audit your go.mod for the vulnerable version, apply the upgrade, and consider adding context timeouts around XPath operations as an additional layer of defense. The cost of a dependency upgrade is trivial compared to the cost of a production DoS incident.