Skip to content

Commit 5d6f246

Browse files
committed
fix(ci): harden workflows against template injection, pin actions
Template injection: Moved all attacker-controllable values into step-level env: vars so they're never interpreted as shell syntax. Excessive permissions: added top-level permissions: {} and per-job grants. Artipacked: added persist-credentials: false to both checkout steps to prevent token leakage via .git/config in artifacts. Unpinned actions: pinned all external actions to commit SHAs.
1 parent 868525b commit 5d6f246

2 files changed

Lines changed: 32 additions & 18 deletions

File tree

.github/workflows/cleanup.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
packages: write
2828
steps:
2929
- name: Delete untagged versions
30-
uses: actions/delete-package-versions@v5
30+
uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5
3131
with:
3232
package-name: ${{ env.PACKAGE_NAME }}
3333
package-type: container
@@ -42,7 +42,7 @@ jobs:
4242
packages: write
4343
steps:
4444
- name: Delete old SHA-tagged versions
45-
uses: actions/delete-package-versions@v5
45+
uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5
4646
with:
4747
package-name: ${{ env.PACKAGE_NAME }}
4848
package-type: container
@@ -58,14 +58,15 @@ jobs:
5858
steps:
5959
- name: Compute branch tag
6060
id: tag
61+
env:
62+
EVENT_REF: ${{ github.event.ref }}
6163
run: |
6264
# refs/heads/j4n/foo -> j4n-foo
63-
BRANCH="${{ github.event.ref }}"
64-
TAG=$(echo "$BRANCH" | sed 's|/|-|g')
65+
TAG=$(echo "$EVENT_REF" | sed 's|/|-|g')
6566
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
6667
6768
- name: Delete branch-tagged versions
68-
uses: actions/delete-package-versions@v5
69+
uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5
6970
with:
7071
package-name: ${{ env.PACKAGE_NAME }}
7172
package-type: container

.github/workflows/docker-ci.yaml

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ on:
3838
description: 'Relay commit SHA (leave empty for HEAD of ref)'
3939
default: ''
4040

41+
permissions: {}
42+
4143
env:
4244
REGISTRY: ghcr.io
4345
IMAGE_NAME: chatmail/docker
@@ -55,40 +57,50 @@ jobs:
5557
steps:
5658
- name: Compute relay ref
5759
id: relay
60+
env:
61+
PAYLOAD_REF: ${{ github.event.client_payload.relay_ref }}
62+
PAYLOAD_SHA: ${{ github.event.client_payload.relay_sha }}
63+
INPUT_REF: ${{ github.event.inputs.relay_ref }}
64+
INPUT_SHA: ${{ github.event.inputs.relay_sha }}
5865
run: |
59-
# Precedence: repository_dispatch payload > workflow_dispatch input > main
60-
REF="${{ github.event.client_payload.relay_ref || github.event.inputs.relay_ref || 'main' }}"
61-
SHA="${{ github.event.client_payload.relay_sha || github.event.inputs.relay_sha || '' }}"
66+
REF="${PAYLOAD_REF:-${INPUT_REF:-main}}"
67+
SHA="${PAYLOAD_SHA:-${INPUT_SHA:-}}"
6268
echo "ref=${REF}" >> "$GITHUB_OUTPUT"
6369
echo "sha=${SHA}" >> "$GITHUB_OUTPUT"
6470
6571
- name: Checkout relay repo as build context
66-
uses: actions/checkout@v6
72+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
6773
with:
6874
repository: chatmail/relay
6975
ref: ${{ steps.relay.outputs.sha || steps.relay.outputs.ref }}
76+
persist-credentials: false
7077

7178
- name: Checkout docker repo
72-
uses: actions/checkout@v6
79+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
7380
with:
7481
path: docker
82+
persist-credentials: false
7583

7684
- name: Set up Docker Buildx
77-
uses: docker/setup-buildx-action@v4
85+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
7886

7987
- name: Login to GHCR
8088
if: github.event_name != 'pull_request'
81-
uses: docker/login-action@v4
89+
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
8290
with:
8391
registry: ${{ env.REGISTRY }}
8492
username: ${{ github.actor }}
8593
password: ${{ secrets.GITHUB_TOKEN }}
8694

8795
- name: Compute build metadata
8896
id: meta
97+
env:
98+
RELAY_REF_INPUT: ${{ steps.relay.outputs.ref }}
99+
EVENT_NAME: ${{ github.event_name }}
100+
REF_NAME: ${{ github.ref_name }}
89101
run: |
90-
IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
91-
RELAY_REF="${{ steps.relay.outputs.ref }}"
102+
IMAGE="${REGISTRY}/${IMAGE_NAME}"
103+
RELAY_REF="${RELAY_REF_INPUT}"
92104
93105
# Relay SHA comes from the relay checkout at workspace root
94106
RELAY_SHA=$(git rev-parse HEAD)
@@ -105,10 +117,10 @@ jobs:
105117
# -- Tags --
106118
# Always: relay SHA tag
107119
TAGS="${IMAGE}:sha-${RELAY_SHA_SHORT}"
108-
if [ "${{ github.event_name }}" = "push" ] || \
109-
[ "${{ github.event_name }}" = "pull_request" ]; then
120+
if [ "$EVENT_NAME" = "push" ] || \
121+
[ "$EVENT_NAME" = "pull_request" ]; then
110122
# Docker-repo push/PR: add docker branch tag
111-
TAGS="${TAGS}"$'\n'"${IMAGE}:${{ github.ref_name }}"
123+
TAGS="${TAGS}"$'\n'"${IMAGE}:${REF_NAME}"
112124
else
113125
# Dispatch: tags based on relay ref
114126
BRANCH_TAG=$(echo "${RELAY_REF}" | sed 's|/|-|g')
@@ -175,7 +187,7 @@ jobs:
175187
run: cp docker/.dockerignore .dockerignore
176188

177189
- name: Build and push
178-
uses: docker/build-push-action@v7
190+
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
179191
with:
180192
context: .
181193
file: docker/chatmail_relay.dockerfile
@@ -193,6 +205,7 @@ jobs:
193205
test:
194206
name: Integration test
195207
needs: build
208+
permissions: {}
196209
if: github.event_name != 'pull_request'
197210
# TODO: revert to @main once cmlxc docker support is merged
198211
uses: chatmail/cmlxc/.github/workflows/lxc-test.yml@j4n/docker-support

0 commit comments

Comments
 (0)