Back to Blog
high SEVERITY6 min read

How Denial of Service via Infinite Loop happens in Go XPath libraries and how to fix it

A high-severity denial of service vulnerability (CVE-2026-32287) was discovered in the `github.com/antchfx/xpath` Go library, where crafted boolean XPath expressions could trigger an infinite loop, consuming CPU resources indefinitely. The fix upgrades the dependency from v1.3.3 to v1.3.6 in the `go.mod` file of the affected project. This vulnerability is particularly dangerous for any Go application that parses or evaluates XPath expressions from untrusted input.

O
By Orbis AppSec
Published August 19, 2026Reviewed August 19, 2026

Answer Summary

CVE-2026-32287 is a high-severity Denial of Service vulnerability in the Go library `github.com/antchfx/xpath` (versions prior to 1.3.6), classified under CWE-835 (Loop with Unreachable Exit Condition). Specially crafted boolean XPath expressions cause the XPath evaluation engine to enter an infinite loop, exhausting CPU resources. The fix is to upgrade the `antchfx/xpath` dependency to version 1.3.6 or later in your `go.mod` file, which patches the loop termination logic for boolean expression evaluation.

Vulnerability at a Glance

cweCWE-835
fixUpgrade github.com/antchfx/xpath from v1.3.3 to v1.3.6
riskApplication hangs indefinitely, consuming CPU and becoming unresponsive
languageGo
root causeBoolean XPath expression evaluation logic lacks proper loop termination
vulnerabilityDenial of Service (Infinite Loop)

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:

  1. The slurp application uses Colly to scrape a web page
  2. The scraping logic uses XPath selectors (via htmlquery or xmlquery) to extract data
  3. 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
  4. 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:

  1. github.com/antchfx/xpath v1.3.3 → v1.3.6: The core fix—patches the infinite loop in boolean expression evaluation
  2. github.com/antchfx/htmlquery v1.3.4 → v1.3.5: Updated to depend on the patched xpath version
  3. github.com/antchfx/xmlquery v1.4.4 → v1.5.0: Same reason—ensures the new xpath version is pulled in
  4. github.com/PuerkitoBio/goquery v1.10.2 → v1.11.0: Compatibility update
  5. golang.org/x/net v0.38.0 → v0.47.0: Transitive dependency update for compatibility
  6. golang.org/x/text v0.23.0 → v0.31.0: Transitive dependency update
  7. Go version 1.23.01.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.

Key Takeaways

  • Transitive dependencies are attack surface: The vulnerable antchfx/xpath v1.3.3 was never directly imported by slurp, 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/xpath proves 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/v3 listed 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/xpath v1.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/xpath from 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.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3537

Related Articles

critical

deleteNestedProperty Prototype Pollution via Dot-Notation Path

The `deleteNestedProperty` function in propertyUtils.ts allowed attackers to manipulate JavaScript object prototypes by passing specially crafted dot-notation paths like `__proto__.polluted`. A fix now blocks dangerous keys before processing, preventing prototype pollution attacks that could affect all objects in the application.

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.