Repository
go-task/task
Title
Git Remote Taskfile ref allows path traversal outside task-git-repos cache
Severity
Moderate
Affected product/package
- Ecosystem: Go
- Package:
github.com/go-task/task/v3
- Reviewed commit:
5f78da2d0af3bcdf3ac0bb253eca6900ef84706f
- Latest release observed:
v3.50.0
- Affected versions:
<= v3.50.0 if current release matches reviewed code
- Patched versions: none known
Weakness
CWE-22 / CWE-73.
Summary
The Git Remote Taskfile cache key uses the untrusted ref query parameter as a filesystem path component:
return filepath.Join(node.url.Host, repoPath, ref)
When ref contains traversal components, the clone cache directory can resolve outside os.TempDir()/task-git-repos. On clone failure, getOrCloneRepo() calls os.RemoveAll(cacheDir), which can delete that escaped path. The same cache path is also used as the clone destination, so a successful clone could write outside the intended cache root.
Reproduction
Use the local proof I prepared on the reviewed vulnerable tree:
cp evidence/vulnerable-node_git_path_traversal_probe_test.go taskfile/node_git_path_traversal_probe_test.go
go test ./taskfile -run TestGitNodeRepoCacheKeyTraversalRemovesOutsideCacheDir -count=1 -v
The proof uses a local invalid file:// Git URL with ref=../../victim-delete-me. No live Git service is contacted.
Observed vulnerable output:
=== RUN TestGitNodeRepoCacheKeyTraversalRemovesOutsideCacheDir
--- PASS: TestGitNodeRepoCacheKeyTraversalRemovesOutsideCacheDir (0.09s)
PASS
ok github.com/go-task/task/v3/taskfile 0.985s
Impact
An attacker who can influence a Git Remote Taskfile entrypoint can make Task delete or write outside the intended Git Taskfile cache directory. The cleanup deletion occurs before the remote Taskfile trust/checksum prompt, because trust is checked after node.ReadContext() returns content.
I am not claiming RCE or third-party service compromise. The proof demonstrates local filesystem impact only.
Suggested Fix
Use a stable hash for the clone cache directory instead of raw path components. The attached patch hashes host/repo?ref=... and stores it under a fixed git/<hash> prefix.
Patch verification:
TestGitNodeRepoCacheKeyBlocksTraversalRef: PASS
Existing TestRepoCacheKey_* tests: PASS
Evidence prepared locally and available on request:
- vulnerable local Go test: vulnerable-node_git_path_traversal_probe_test.go
- vulnerable test output
- proposed patch
- patched regression test output
- reviewed commit
Researcher: Francesco Sabiu
Repository
go-task/taskTitle
Git Remote Taskfile ref allows path traversal outside task-git-repos cache
Severity
Moderate
Affected product/package
github.com/go-task/task/v35f78da2d0af3bcdf3ac0bb253eca6900ef84706fv3.50.0<= v3.50.0if current release matches reviewed codeWeakness
CWE-22 / CWE-73.
Summary
The Git Remote Taskfile cache key uses the untrusted
refquery parameter as a filesystem path component:When
refcontains traversal components, the clone cache directory can resolve outsideos.TempDir()/task-git-repos. On clone failure,getOrCloneRepo()callsos.RemoveAll(cacheDir), which can delete that escaped path. The same cache path is also used as the clone destination, so a successful clone could write outside the intended cache root.Reproduction
Use the local proof I prepared on the reviewed vulnerable tree:
cp evidence/vulnerable-node_git_path_traversal_probe_test.go taskfile/node_git_path_traversal_probe_test.go go test ./taskfile -run TestGitNodeRepoCacheKeyTraversalRemovesOutsideCacheDir -count=1 -vThe proof uses a local invalid
file://Git URL withref=../../victim-delete-me. No live Git service is contacted.Observed vulnerable output:
Impact
An attacker who can influence a Git Remote Taskfile entrypoint can make Task delete or write outside the intended Git Taskfile cache directory. The cleanup deletion occurs before the remote Taskfile trust/checksum prompt, because trust is checked after
node.ReadContext()returns content.I am not claiming RCE or third-party service compromise. The proof demonstrates local filesystem impact only.
Suggested Fix
Use a stable hash for the clone cache directory instead of raw path components. The attached patch hashes
host/repo?ref=...and stores it under a fixedgit/<hash>prefix.Patch verification:
Evidence prepared locally and available on request:
Researcher: Francesco Sabiu