Skip to content

Commit 2d00c4a

Browse files
authored
fix: GitHub Actions shell injection in _build.yml (#249)
Replace direct `${{ ... }}` interpolation in `run:` steps of `.github/workflows/_build.yml` with `env:` blocks per GitHub's hardening guide. Every workflow input (`inputs.version`) and matrix value (`matrix.cc`, `matrix.cxx`, `matrix.goos`, `matrix.goarch`, `matrix.arch`) now flows into the shell through a named environment variable rather than being textually spliced into the script. Pattern applied uniformly across the 6 flagged steps plus the archive steps that used `${{ matrix.* }}` in tar filenames. The values become opaque shell variables on expansion, so attacker input becomes a literal argv entry rather than interpreted shell code. The if/else form on `$VERSION` avoids word-splitting pitfalls of conditional arg construction. semgrep `run-shell-injection` findings: 6 → 0. Behaviour preserved — same build.sh invocations, same artefact names, same conditional version handling. Reference: https://securitylab.github.com/research/github-actions-untrusted-input/ Closes #247.
1 parent 10a9b83 commit 2d00c4a

1 file changed

Lines changed: 66 additions & 10 deletions

File tree

.github/workflows/_build.yml

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,41 @@ jobs:
5252
node-version: "22"
5353

5454
- name: Build standard binary
55-
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
55+
env:
56+
VERSION: ${{ inputs.version }}
57+
CC: ${{ matrix.cc }}
58+
CXX: ${{ matrix.cxx }}
59+
run: |
60+
if [ -n "$VERSION" ]; then
61+
scripts/build.sh --version "$VERSION" "CC=$CC" "CXX=$CXX"
62+
else
63+
scripts/build.sh "CC=$CC" "CXX=$CXX"
64+
fi
5665
5766
- name: Ad-hoc sign macOS binary
5867
if: startsWith(matrix.os, 'macos')
5968
run: codesign --sign - --force build/c/codebase-memory-mcp
6069

6170
- name: Archive standard binary
71+
env:
72+
GOOS: ${{ matrix.goos }}
73+
GOARCH: ${{ matrix.goarch }}
6274
run: |
6375
cp LICENSE install.sh build/c/
64-
tar -czf codebase-memory-mcp-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz \
76+
tar -czf "codebase-memory-mcp-${GOOS}-${GOARCH}.tar.gz" \
6577
-C build/c codebase-memory-mcp LICENSE install.sh
6678
6779
- name: Build UI binary
68-
run: scripts/build.sh --with-ui ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
80+
env:
81+
VERSION: ${{ inputs.version }}
82+
CC: ${{ matrix.cc }}
83+
CXX: ${{ matrix.cxx }}
84+
run: |
85+
if [ -n "$VERSION" ]; then
86+
scripts/build.sh --with-ui --version "$VERSION" "CC=$CC" "CXX=$CXX"
87+
else
88+
scripts/build.sh --with-ui "CC=$CC" "CXX=$CXX"
89+
fi
6990
7091
- name: Ad-hoc sign macOS UI binary
7192
if: startsWith(matrix.os, 'macos')
@@ -76,9 +97,12 @@ jobs:
7697
run: scripts/security-ui.sh
7798

7899
- name: Archive UI binary
100+
env:
101+
GOOS: ${{ matrix.goos }}
102+
GOARCH: ${{ matrix.goarch }}
79103
run: |
80104
cp LICENSE install.sh build/c/
81-
tar -czf codebase-memory-mcp-ui-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz \
105+
tar -czf "codebase-memory-mcp-ui-${GOOS}-${GOARCH}.tar.gz" \
82106
-C build/c codebase-memory-mcp LICENSE install.sh
83107
84108
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -108,7 +132,14 @@ jobs:
108132

109133
- name: Build standard binary
110134
shell: msys2 {0}
111-
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=clang CXX=clang++
135+
env:
136+
VERSION: ${{ inputs.version }}
137+
run: |
138+
if [ -n "$VERSION" ]; then
139+
scripts/build.sh --version "$VERSION" CC=clang CXX=clang++
140+
else
141+
scripts/build.sh CC=clang CXX=clang++
142+
fi
112143
113144
- name: Archive standard binary
114145
shell: msys2 {0}
@@ -120,7 +151,14 @@ jobs:
120151
121152
- name: Build UI binary
122153
shell: msys2 {0}
123-
run: scripts/build.sh --with-ui ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=clang CXX=clang++
154+
env:
155+
VERSION: ${{ inputs.version }}
156+
run: |
157+
if [ -n "$VERSION" ]; then
158+
scripts/build.sh --with-ui --version "$VERSION" CC=clang CXX=clang++
159+
else
160+
scripts/build.sh --with-ui CC=clang CXX=clang++
161+
fi
124162
125163
- name: Archive UI binary
126164
shell: msys2 {0}
@@ -159,26 +197,44 @@ jobs:
159197
node-version: "22"
160198

161199
- name: Build standard binary (static)
162-
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=gcc CXX=g++ STATIC=1
200+
env:
201+
VERSION: ${{ inputs.version }}
202+
run: |
203+
if [ -n "$VERSION" ]; then
204+
scripts/build.sh --version "$VERSION" CC=gcc CXX=g++ STATIC=1
205+
else
206+
scripts/build.sh CC=gcc CXX=g++ STATIC=1
207+
fi
163208
164209
- name: Verify static linking
165210
run: |
166211
file build/c/codebase-memory-mcp
167212
ldd build/c/codebase-memory-mcp 2>&1 | grep -q "not a dynamic executable" || ldd build/c/codebase-memory-mcp 2>&1 | grep -q "statically linked"
168213
169214
- name: Archive standard binary
215+
env:
216+
ARCH: ${{ matrix.arch }}
170217
run: |
171218
cp LICENSE install.sh build/c/
172-
tar -czf codebase-memory-mcp-linux-${{ matrix.arch }}-portable.tar.gz \
219+
tar -czf "codebase-memory-mcp-linux-${ARCH}-portable.tar.gz" \
173220
-C build/c codebase-memory-mcp LICENSE install.sh
174221
175222
- name: Build UI binary (static)
176-
run: scripts/build.sh --with-ui ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=gcc CXX=g++ STATIC=1
223+
env:
224+
VERSION: ${{ inputs.version }}
225+
run: |
226+
if [ -n "$VERSION" ]; then
227+
scripts/build.sh --with-ui --version "$VERSION" CC=gcc CXX=g++ STATIC=1
228+
else
229+
scripts/build.sh --with-ui CC=gcc CXX=g++ STATIC=1
230+
fi
177231
178232
- name: Archive UI binary
233+
env:
234+
ARCH: ${{ matrix.arch }}
179235
run: |
180236
cp LICENSE install.sh build/c/
181-
tar -czf codebase-memory-mcp-ui-linux-${{ matrix.arch }}-portable.tar.gz \
237+
tar -czf "codebase-memory-mcp-ui-linux-${ARCH}-portable.tar.gz" \
182238
-C build/c codebase-memory-mcp LICENSE install.sh
183239
184240
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1

0 commit comments

Comments
 (0)