summaryrefslogtreecommitdiff
path: root/.github/workflows
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-05-10 22:26:48 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-05-10 22:26:48 +0300
commite39d9b2c79f7f1c06004d551f3c22f5d866e401a (patch)
treea23ad359d0f89fa1ae87294d47a56cf7f825406d /.github/workflows
parentbab5cf059d26735b5f13b621e75c2d56ba8e5b81 (diff)
downloadvyos-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.yml16
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) ;;