T3MP3ST v1 — hardened launch (AGPL, verify-claims 24/24, leak-scrubbed)

This commit is contained in:
faber committed 2026-07-04 21:11:05 -04:00
1 parent c7a356bde0
commit 6c57e09023
242 files changed
+1761 -51038

No files matched your search

@@ -1 +1 @@
{"id": "GHSA-hx53-77qj-8663", "cve": "CVE-2026-7474", "repo": "hashicorp/nomad", "cwes": ["CWE-22"], "vuln_files": ["client/hostvolumemanager/host_volume_plugin.go", "client/hostvolumemanager/host_volume_plugin_test.go", "client/hostvolumemanager/host_volumes_test.go"], "duration_sec": 95.4, "error": null, "strict": true, "lenient": true, "findings_scored": [{"fileMatch": true, "lineProx": false, "cweMatch": true, "hit": true, "title": "Path traversal in host-volume ID enables arbitrary directory deletion (RemoveAll) and creation on the client host", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 210, "cwe": "CWE-22"}, {"fileMatch": true, "lineProx": true, "cweMatch": true, "hit": true, "title": "Path traversal in PluginID selects and executes an arbitrary on-disk executable", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 229, "cwe": "CWE-22"}], "n_findings": 2, "findings": [{"title": "Path traversal in host-volume ID enables arbitrary directory deletion (RemoveAll) and creation on the client host", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 210, "cwe": "CWE-22", "vuln_class": "path-traversal", "severity": "high", "description": "The built-in 'mkdir' host-volume plugin builds the on-disk target path with path := filepath.Join(p.VolumesDir, req.ID) (lines 105 and 203) and then performs destructive filesystem operations: os.MkdirAll/os.Chmod/os.Chown in Create (lines 133-160) and os.RemoveAll(path) in Delete (line 210). req.ID originates from the ClientHostVolumeDeleteRequest/ClientHostVolumeCreateRequest forwarded verbatim to the client RPC handler (HostVolume.Create/Delete -> HostVolumeManager.Create/Delete -> getPlugin -> HostVolumePluginMkdir). Nowhere in client/hostvolumemanager is req.ID validated to reject '..' or absolute components, and filepath.Join cleans the path so a traversal like '../../../../etc' escapes VolumesDir. Because the Nomad client agent typically runs as root, a request with a traversing ID causes os.RemoveAll to recursively delete an arbitrary host directory (e.g. the volumes dir's parents, /etc, plugin dirs), and Create can chown/chmod arbitrary existing directories. This is a destructive, attacker-influenced filesystem primitive reachable from the dynamic-host-volume RPC path with no sanitizer between source and sink.", "poc": "Issue a dynamic host volume delete (or create) whose volume ID contains traversal, e.g. ClientHostVolumeDeleteRequest{PluginID:\"mkdir\", ID:\"../../../../../../etc/cron.d\", NodeID:<target>} -> client computes path=filepath.Join(VolumesDir, \"../../../../../../etc/cron.d\") and runs os.RemoveAll on it, deleting /etc/cron.d on the host. With Create, ID=\"../../../../some/existing/dir\" plus parameters {mode:777,uid:0} chmods/chowns that dir.", "confidence": 0.7}, {"title": "Path traversal in PluginID selects and executes an arbitrary on-disk executable", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 229, "cwe": "CWE-22", "vuln_class": "rce", "severity": "high", "description": "getPlugin(req.PluginID) (host_volumes.go) falls through to NewHostVolumePluginExternal(log, hvm.pluginDir, id, ...) where id == req.PluginID. The executable path is built as executable := filepath.Join(pluginDir, filename) (line 229) with no rejection of '..' or absolute path components. filepath.Join cleans the path, so a PluginID like '../../../../bin/sh' resolves to an executable outside the configured plugin directory. The only guard is os.Stat + helper.IsExecutable, so any executable file on the host can be selected and then invoked via exec.CommandContext in runPlugin/Fingerprint/Create/Delete with attacker-controlled environment variables (DHV_PARAMETERS, DHV_VOLUME_ID, etc.). The Nomad client runs this as root, allowing execution of arbitrary host binaries with attacker-influenced environment as part of volume create/delete/fingerprint.", "poc": "Send a dynamic host volume create/delete with PluginID=\"../../../../../../usr/bin/<target-binary>\" so filepath.Join(pluginDir, PluginID) resolves to an arbitrary executable, which Nomad then runs as the client process user (typically root) with attacker-controlled DHV_* env vars.", "confidence": 0.55}], "transcript": ""}
{"id": "GHSA-hx53-77qj-8663", "cve": "CVE-2026-7474", "repo": "hashicorp/nomad", "cwes": ["CWE-22"], "vuln_files": ["client/hostvolumemanager/host_volume_plugin.go", "client/hostvolumemanager/host_volume_plugin_test.go", "client/hostvolumemanager/host_volumes_test.go"], "duration_sec": 186.8, "error": null, "strict": true, "lenient": true, "findings_scored": [{"fileMatch": true, "lineProx": true, "cweMatch": true, "hit": true, "title": "Path traversal in external host-volume plugin resolution allows execution of arbitrary host executables", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 229, "cwe": "CWE-22"}, {"fileMatch": true, "lineProx": false, "cweMatch": true, "hit": true, "title": "Path traversal via volume ID in built-in mkdir plugin enables arbitrary directory creation/deletion", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 203, "cwe": "CWE-22"}], "n_findings": 2, "findings": [{"title": "Path traversal in external host-volume plugin resolution allows execution of arbitrary host executables", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 229, "cwe": "CWE-22", "vuln_class": "path-traversal", "severity": "high", "description": "HostVolumeManager.getPlugin() passes the caller-supplied req.PluginID straight to NewHostVolumePluginExternal() as `filename`, which builds the executable path via `filepath.Join(pluginDir, filename)` (line 229) with no filepath.Base()/dot-dot rejection. filepath.Join resolves `..` segments, so a PluginID like `../../../../bin/mount` (or any executable on the host) escapes the configured plugin directory. If the resolved path exists and IsExecutable, HostVolumePluginExternal.runPlugin runs it via exec.CommandContext with attacker-influenced environment variables (DHV_PARAMETERS, DHV_VOLUME_NAME, etc.) as the Nomad client process (commonly root). The data flow is: volume create/delete RPC (cstructs.ClientHostVolumeCreateRequest.PluginID) -> HostVolumeManager.Create/Delete -> getPlugin(req.PluginID) -> NewHostVolumePluginExternal(pluginDir, id) -> filepath.Join -> exec.CommandContext. No sanitizer validates the PluginID against traversal anywhere in the module.", "poc": "Submit a dynamic host volume create request whose plugin_id is a traversal path to a pre-existing executable, e.g. plugin_id = \"../../../../../../bin/sh\" (or any script/binary reachable from the client's plugin dir). getPlugin -> NewHostVolumePluginExternal resolves executable=/bin/sh (outside plugin dir) and Nomad executes it with the attacker-controlled DHV_* environment.", "confidence": 0.8}, {"title": "Path traversal via volume ID in built-in mkdir plugin enables arbitrary directory creation/deletion", "file": "client/hostvolumemanager/host_volume_plugin.go", "line": 203, "cwe": "CWE-22", "vuln_class": "path-traversal", "severity": "high", "description": "HostVolumePluginMkdir.Create (line 105) and Delete (line 203) compute the target path as `filepath.Join(p.VolumesDir, req.ID)` using the caller-supplied req.ID with no validation that it stays under VolumesDir. filepath.Join collapses `..` segments, so a volume ID containing `../` escapes VolumesDir. In Delete this reaches os.RemoveAll(path), giving an arbitrary recursive-delete primitive on the client host; in Create it reaches os.MkdirAll/os.Chmod/os.Chown on an attacker-chosen path. The ID flows unvalidated from the ClientHostVolume RPC args into the plugin.", "poc": "Create/delete a dynamic host volume using the built-in \"mkdir\" plugin with ID = \"../../../../etc/cron.d/evil\" (create) or ID = \"../../../../var/important\" (delete). Delete triggers os.RemoveAll(filepath.Join(VolumesDir, \"../../../../var/important\")) removing arbitrary host paths as the Nomad client user.", "confidence": 0.6}], "transcript": ""}