diff options
| author | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-10 22:26:48 +0300 |
|---|---|---|
| committer | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-10 22:26:48 +0300 |
| commit | e39d9b2c79f7f1c06004d551f3c22f5d866e401a (patch) | |
| tree | a23ad359d0f89fa1ae87294d47a56cf7f825406d /.github/workflows | |
| parent | bab5cf059d26735b5f13b621e75c2d56ba8e5b81 (diff) | |
| download | vyos-documentation-e39d9b2c79f7f1c06004d551f3c22f5d866e401a.tar.gz vyos-documentation-e39d9b2c79f7f1c06004d551f3c22f5d866e401a.zip | |
fix(ci): reject path traversal in fork-controlled diff entries
Copilot finding on .github/workflows/ai-validation.yml:64 — defense
in depth:
Even though git's tree machinery generally rejects `..` segments
and absolute paths at commit time, treat fork-controlled diff
input as untrusted. A path like `docs/../../outside.md` would
let `git show HEAD:<path>` write to `_changed_md/../../outside.md`,
which resolves to a sibling of `_changed_md/` — escaping the
artifact directory and writing into the runner workspace.
Mitigation: validate each path before any mkdir/redirect. Reject:
- absolute paths (`/foo`)
- interior `..` segments (`foo/../bar`)
- leading `..` (`../foo`)
- trailing `..` (`foo/..`)
- bare `..`
Combined with the existing symlink/submodule mode check, the
prepare job now refuses to bundle any tree entry whose path or
type could escape the artifact boundary.
Suppressed-by-Copilot finding (line 68, id-token: write):
Same pushback as previous rounds. claude-code-action@v1 uses OIDC
internally (verified via vyos/vyos-documentation commit b18a399c).
Keeping as-is.
🤖 Generated by [robots](https://vyos.io)
Diffstat (limited to '.github/workflows')
| -rw-r--r-- | .github/workflows/ai-validation.yml | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/.github/workflows/ai-validation.yml b/.github/workflows/ai-validation.yml index 18671c9d..8e254dcc 100644 --- a/.github/workflows/ai-validation.yml +++ b/.github/workflows/ai-validation.yml @@ -54,6 +54,22 @@ jobs: # target path, never the target's content. mkdir _changed_md while IFS= read -r -d '' path; do + # Path-traversal hardening: even though git's tree machinery + # rejects `..` segments and absolute paths in committed entries + # at the porcelain level, treat fork-controlled diff input as + # untrusted and validate explicitly. A path like + # `docs/../../outside.md` would otherwise let `git show` + # write outside _changed_md/. + if [[ "$path" == /* \ + || "$path" == *"/../"* \ + || "$path" == "../"* \ + || "$path" == *"/.." \ + || "$path" == ".." ]]; then + echo "::warning::Skipping unsafe path with traversal/absolute prefix: $path" + continue + fi + # Skip non-regular tree entries (symlinks, submodules) per the + # commit immediately preceding this one. mode=$(git ls-tree HEAD -- "$path" | awk '{print $1}') case "$mode" in 100644|100755) ;; |
