Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
run: npm run contracts:check

- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify all action refs and detect non-SHA pins in workflows.
# Expected: no `uses:` entries pinned only by tag/version.
rg -nP '^\s*uses:\s*[^@]+@([vV]?\d+(\.\d+){0,2}|main|master)$' .github/workflows || true

# Show all setup-go uses with context.
rg -n -C2 'actions/setup-go@' .github/workflows

Repository: AIX-Format/PiWorker-OS

Length of output: 1785


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact setup-go blocks for both occurrences.
nl -ba .github/workflows/ci.yml | sed -n '45,75p'
echo "----"
nl -ba .github/workflows/ci.yml | sed -n '135,165p'

Repository: AIX-Format/PiWorker-OS

Length of output: 109


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- setup-go @ first occurrence (approx 45-75) ----"
cat -n .github/workflows/ci.yml | sed -n '45,75p'
echo "---- setup-go @ second occurrence (approx 135-165) ----"
cat -n .github/workflows/ci.yml | sed -n '135,165p'

Repository: AIX-Format/PiWorker-OS

Length of output: 2075


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show workflow triggers and relevant job context around the setup-go steps.
cat -n .github/workflows/ci.yml | sed -n '1,120p'
echo "----"
cat -n .github/workflows/ci.yml | sed -n '120,220p'

Repository: AIX-Format/PiWorker-OS

Length of output: 5432


🌐 Web query:

actions/setup-go cache-dependency-path cache poisoning pull_request from forks write to cache

💡 Result:

Summary: In GitHub Actions, cache poisoning becomes practical when untrusted code (e.g., from a forked PR) can write to the same cache entries that a more-privileged workflow later restores. Two key pieces matter for your query (setup-go + pull_request from forks + write to cache). 1) What actions/setup-go does with cache-dependency-path - actions/setup-go has built-in caching for “Go modules and build outputs”. Caching is enabled by default via its cache input; you can disable it with cache: false.[1] - The cache key includes hashes of dependency files. By default, it looks for go.mod and uses its hash as part of the cache key; to use go.sum (or other files), set cache-dependency-path (supports glob patterns).[1] 2) Whether forked pull_request workflows can write to caches used elsewhere - GitHub Docs warn not to store sensitive information in caches because “Anyone with read access can create a pull request on a repository and access the contents of a cache” and “forks of a repository can create pull requests on the base branch and access caches on the base branch.”[2] - GitHub Docs also describe cache scope behavior specifically for PRs: when a workflow run is triggered for a pull request, the cache is created for the merge ref (refs/pull/.../merge), so it “can only be restored by re-runs of the pull request” and “cannot be restored by the base branch or other pull requests targeting that base branch.”[2] - Implication: with the normal pull_request event (and the typical security model), PR-created caches should not be a simple “write once, poison later in main” channel, because of that limited scope.[2] 3) The main way “write to cache from forks” becomes dangerous: pull_request_target - The practical “poison the cache for a later trusted run” pattern appears when workflows are triggered with pull_request_target, because it runs in the context of the base repository (so the attacker’s code can execute with base-repo permissions, including the ability to interact with cache). This is described in the TanStack cache poisoning write-up: the attack used pull_request_target instead of pull_request, noting that it runs in the context of the base repository and “can access secrets and can write to the Actions cache — even from a forked PR.”[3] 4) Mitigations that follow from the above (what to do for setup-go caching) - Security conservative mitigation: disable setup-go caching in workflows that may execute untrusted code (especially anything resembling pull_request_target). This is explicitly recommended/implemented in a GitHub change: “disable Go module cache in agentic setup actions to prevent cache poisoning”, changing actions/setup-go usage to set cache: false (because caching enabled by default exposes a cache poisoning vector).[4] - If you need caching, isolate by context: GitHub’s cache poisoning guidance emphasizes preventing untrusted PR workflows from writing to caches used by privileged/release pipelines; one key rule is to “separate caches” so PR workflows cannot overwrite what release workflows will restore.[5] - Use restore-only patterns when appropriate: actions/cache provides actions/cache/restore that restores but does not save (so it’s “granular ability to restore a cache without having to save it”).[6] (Separating restore and save reduces write capability from untrusted contexts.) Concrete answer to your query terms - cache-dependency-path: controls what dependency file(s) are hashed for the setup-go cache key (default uses go.mod hash; you can point it at go.sum via cache-dependency-path).[1] - pull_request from forks write to cache: under normal pull_request scope rules, PR-created caches are tied to refs/pull/.../merge and aren’t restorable by base branch or other PRs, so “write to cache then have main restore it” is not straightforward.[2] - However, with pull_request_target (base repo context), forked PR code can gain access that enables cache poisoning/write scenarios.[3] Recommended workflow guidance (short) - For workflows that may run untrusted PR code (particularly anything using pull_request_target), set cache: false on actions/setup-go.[4][1] - For trusted workflows (main/release), you can keep caching enabled, but ensure untrusted workflows never have permission or execution context that allows them to save/poison the same cache keys that trusted workflows restore.[5][3]

Citations:


Pin actions/setup-go to an immutable commit SHA (mutable @v6 in two steps).

uses: actions/setup-go@v6 is a mutable reference and weakens CI supply-chain integrity; pin to a full commit SHA in both the build and contract-tests jobs.

Suggested hardening diff
-        uses: actions/setup-go@v6
+        uses: actions/setup-go@<full-length-commit-sha-for-v6>
...
-        uses: actions/setup-go@v6
+        uses: actions/setup-go@<full-length-commit-sha-for-v6>
  • Workflow runs on pull_request (not pull_request_target), so cross-branch cache poisoning is less straightforward; if your policy treats PR caches as untrusted, consider setting cache: false for pull_request.
🧰 Tools
🪛 zizmor (1.25.2)

[error] 57-57: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 57-57: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 57, Replace the mutable reference uses:
actions/setup-go@v6 with a pinned immutable commit SHA in both the build and
contract-tests jobs (locate the occurrences of "uses: actions/setup-go@v6" and
update them to "uses: actions/setup-go@<COMMIT_SHA>"); ensure both job entries
are updated consistently, and verify the chosen commit SHA corresponds to the
desired actions/setup-go release tag before committing.

with:
go-version: "1.25.10"
cache-dependency-path: go.sum
Expand Down Expand Up @@ -147,7 +147,7 @@ jobs:
- name: Contract sync check
run: npm run contracts:check
- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "1.25.10"
cache-dependency-path: go.sum
Expand Down
Loading