Missing path validation on OutputFile/OutputSymlink paths when parsing cached ActionResult (defense-in-depth gap)
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
In `RemoteExecutionService.parseActionResultMetadata()`, `validatePathComponent()` is applied to `Directory`/`Tree` nodes but **not** to top-level `OutputFile.path` / `OutputSymlink.path`. These are passed directly to `RemotePathResolver.outputPathToLocalPath()`, which resolves them against the exec root via `execRoot.getRelative(...)`.
**Current state:** This is not exploitable today, because Bazel's output-matching layer rejects cache entries whose outputs don't match the declared outputs and falls back to local execution. However, the parser should not trust path fields from cache data this is a defense-in-depth gap. If the output-matching layer is ever weakened or bypassed, the unvalidated path becomes an arbitrary-write primitive.
**Repro:** A poisoned disk-cache `ActionResult` with `output_files[0].path = "../../../../.../pwned.txt"` is parsed without validation (verified via byte-level patch of the AC file). Bazel currently rejects the entry at the output-matching stage.
**Disclosure note:** This was reported to the Google VRP, which determined it does not meet their security-escalation threshold and explicitly cleared it for public disclosure.
**Suggested fix:** Apply the same containment check used for `Directory` nodes (reject `..`, absolute paths, `/` in components, or enforce `startsWith(execRoot)` after resolution) to `OutputFile.path`, `OutputSymlink.path/target`, and `OutputDirectory.path`.
Contributor guide
Assessment
This issue has not been assessed yet.