Anyquery has Path Traversal through `clear_plugin_cache`, Allowing Arbitrary Directory Deletion
Date: 2026-06
Affected: go/github.com/julien040/anyquery
Attack vector: path-traversal
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-47253
CWE: CWE-22
CVSS: 7.3 (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:H)

# Path Traversal in `clear_plugin_cache` Allows Arbitrary Directory Deletion | Field | Value | | ---------------- | ----- | | Repository | julien040/anyquery | | Affected version | 0.4.4 | | Vulnerability | CWE-22 — Improper Limitation of a Pathname to a Restricted Directory | | Severity | High | ## Summary The SQL scalar function `clear_plugin_cache(plugin)` in `namespace/other_functions.go` passes the caller-supplied `plugin` argument directly to `path.Join` and then to `os.RemoveAll`, with only an empty-string check as a guard. Because `path.Join` silently resolves `..` segments, a low-privileged bearer-token holder can submit `SELECT clear_plugin_cache('../../../../tmp/target')` to the `/v1/query` HTTP endpoint and delete any directory reachable by the server process. In the verified scenario, a directory outside `$XDG_CACHE_HOME/anyquery/plugins/` was successfully deleted, confirming full path-traversal exploitation. ## Affected Code `namespace/other_functions.go:46` — `pathlib.Join` resolves `..` segments in attacker-controlled `plugin`, producing a path outside the cache root `namespace/other_functions.go:53` — `os.RemoveAll` unconditionally deletes the traversed path ```go func clear_plugin_cache(plugin string) string { pathToRemove := pathlib.Join(xdg.CacheHome, "anyquery", "plugins", plugin) if plugin == "" { return "The plugin name is empty" } // Remove the directory err := os.RemoveAll(pathToRemove) if err != nil { r


Mitigations:

Architectural layers (MAESTRO):