Skip to content

Commit cae60bd

Browse files
committed
fix: harden all reusable workflows against code scanning alerts
Security fixes across 11 workflow files: - Pin all 3rd party action references to commit SHAs with version comments - Move all ${{ inputs.* }}, ${{ env.* }}, ${{ steps.*.outputs.* }}, and ${{ job.status }} expressions from run: blocks to step env: blocks to prevent code injection - Use heredoc format for all $GITHUB_ENV writes to prevent env var injection via newline characters - Add persist-credentials: false to untrusted PR checkouts - Execute pre_build_script via temp file instead of inline interpolation with EXIT trap for guaranteed cleanup - Use openssl rand -hex 8 for heredoc delimiters consistently - Fix helm-chart-package: invalid if: condition, scan-ref path separator, PR notification condition for reusable workflows, PREVIOUS_VERSION same-step usage - Fix docker-promote-jfrog: typo, target_env validation alignment, whitespace trimming for comma-separated tags - Fix docker-promote-dockerhub: whitespace trimming for tags - Validate secret key names in get_infisical_secrets action - Add dependency checks, path traversal validation, domain normalization, and workflow command escaping in get_infisical_secrets action
1 parent 2f0ac6f commit cae60bd

11 files changed

+216
-94
lines changed

.github/workflows/commitizen.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@ jobs:
1717
version: ${{ steps.cz.outputs.version }}
1818
steps:
1919
- name: Check out
20-
uses: actions/checkout@v6.0.2
20+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2121
with:
2222
fetch-depth: 0
2323
token: "${{ secrets.access-token }}"
2424

2525
- id: cz
2626
name: Create bump and changelog
27-
uses: commitizen-tools/commitizen-action@master
27+
uses: commitizen-tools/commitizen-action@338bbd841b75aaee6bf5340e1fa12f6ab58ff9ff # 0.27.1
2828
with:
2929
github_token: ${{ secrets.access-token }}
3030

3131
- name: Print Version
32-
run: echo "Bumped to version ${{ steps.cz.outputs.version }}"
32+
env:
33+
CZ_VERSION: ${{ steps.cz.outputs.version }}
34+
run: echo "Bumped to version ${CZ_VERSION}"

.github/workflows/compute-terraform-module-name.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ jobs:
2020
steps:
2121
- id: compute
2222
shell: bash
23+
env:
24+
INPUT_REPOSITORY_NAME: ${{ inputs.repository_name }}
2325
run: |
24-
REPOSITORY_NAME=${{ inputs.repository_name }}
26+
REPOSITORY_NAME="${INPUT_REPOSITORY_NAME}"
2527
REPOSITORY_NAME=${REPOSITORY_NAME#*/}
2628
PROVIDER_AND_MODULE=${REPOSITORY_NAME#*-}
2729
MODULE_NAME=${PROVIDER_AND_MODULE#*-}

.github/workflows/docker-build-push-dockerhub.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ jobs:
130130
ref: ${{ inputs.git_ref }}
131131
submodules: ${{ inputs.checkout_submodules }}
132132
fetch-depth: ${{ inputs.fetch-depth }}
133+
persist-credentials: false
133134

134135
- name: Login to Docker Hub
135136
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
@@ -139,8 +140,15 @@ jobs:
139140

140141
- name: Run pre-build script
141142
if: ${{ inputs.pre_build_script != '' }}
143+
env:
144+
PRE_BUILD_SCRIPT: ${{ inputs.pre_build_script }}
142145
run: |
143-
${{ inputs.pre_build_script }}
146+
# Accepted risk: pre_build_script is intentionally executed as caller-provided code
147+
SCRIPT_PATH="${RUNNER_TEMP:-/tmp}/pre_build_$$.sh"
148+
trap 'rm -f "$SCRIPT_PATH"' EXIT
149+
printf '%s\n' "$PRE_BUILD_SCRIPT" > "$SCRIPT_PATH"
150+
chmod +x "$SCRIPT_PATH"
151+
bash "$SCRIPT_PATH"
144152
145153
- name: Build and push
146154
uses: NethermindEth/github-action-image-build-and-push@fefef12a2baef6d339fb4b244b4cd45c40146161

.github/workflows/docker-build-push-jfrog.yaml

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,26 +134,31 @@ jobs:
134134
ref: ${{ inputs.git_ref }}
135135
submodules: ${{ inputs.checkout_submodules }}
136136
fetch-depth: ${{ inputs.fetch-depth }}
137+
persist-credentials: false
137138

138139
- name: Set env vars
139140
id: env-vars
141+
env:
142+
INPUT_REPO_NAME: ${{ inputs.repo_name }}
143+
INPUT_GROUP_NAME: ${{ inputs.group_name }}
144+
INPUT_IMAGE_NAME: ${{ inputs.image_name }}
140145
run: |
141146
# Set Repo name
142-
if [[ -n "${{ inputs.repo_name }}" ]]; then
143-
export REPO_NAME="${{ inputs.repo_name }}"
144-
elif [[ -n "${{ inputs.group_name }}" ]]; then
145-
export REPO_NAME="${{ inputs.group_name }}-oci-local-dev"
147+
if [[ -n "${INPUT_REPO_NAME}" ]]; then
148+
export REPO_NAME="${INPUT_REPO_NAME}"
149+
elif [[ -n "${INPUT_GROUP_NAME}" ]]; then
150+
export REPO_NAME="${INPUT_GROUP_NAME}-oci-local-dev"
146151
else
147152
echo "Unable to determine the repo name. Please set either group_name or the repo_name."
148153
exit 1
149154
fi
150155
151156
# Set image name
152-
echo "IMAGE_NAME=${REPO_NAME}/${{ inputs.image_name }}" >> $GITHUB_OUTPUT
157+
echo "IMAGE_NAME=${REPO_NAME}/${INPUT_IMAGE_NAME}" >> $GITHUB_OUTPUT
153158
154159
- name: Install JFrog CLI
155160
id: jfrog
156-
uses: jfrog/setup-jfrog-cli@v4
161+
uses: jfrog/setup-jfrog-cli@86dacb6974c66cc99e7651e1205f6581aaddba9a # v4.10.0
157162
env:
158163
JF_URL: https://${{ inputs.jfrog_url }}
159164
with:
@@ -168,8 +173,15 @@ jobs:
168173

169174
- name: Run pre-build script
170175
if: ${{ inputs.pre_build_script != '' }}
176+
env:
177+
PRE_BUILD_SCRIPT: ${{ inputs.pre_build_script }}
171178
run: |
172-
${{ inputs.pre_build_script }}
179+
# Accepted risk: pre_build_script is intentionally executed as caller-provided code
180+
SCRIPT_PATH="${RUNNER_TEMP:-/tmp}/pre_build_$$.sh"
181+
trap 'rm -f "$SCRIPT_PATH"' EXIT
182+
printf '%s\n' "$PRE_BUILD_SCRIPT" > "$SCRIPT_PATH"
183+
chmod +x "$SCRIPT_PATH"
184+
bash "$SCRIPT_PATH"
173185
174186
- name: Build and push
175187
uses: NethermindEth/github-action-image-build-and-push@fefef12a2baef6d339fb4b244b4cd45c40146161

.github/workflows/docker-promote-dockerhub.yaml

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,22 @@ jobs:
3939
runs-on: ubuntu-latest
4040
steps:
4141
- name: Set environment variables
42+
env:
43+
INPUT_SOURCE_REPO_NAME: ${{ inputs.source_repo_name }}
44+
INPUT_TARGET_REPO_NAME: ${{ inputs.target_repo_name }}
45+
INPUT_IMAGE_NAME: ${{ inputs.image_name }}
4246
run: |
43-
SOURCE_IMAGE="${{ inputs.source_repo_name }}/${{ inputs.image_name }}"
44-
TARGET_IMAGE="${{ inputs.target_repo_name }}/${{ inputs.image_name }}"
45-
echo "SOURCE_IMAGE=${SOURCE_IMAGE}" >> $GITHUB_ENV
46-
echo "TARGET_IMAGE=${TARGET_IMAGE}" >> $GITHUB_ENV
47+
SOURCE_IMAGE="${INPUT_SOURCE_REPO_NAME}/${INPUT_IMAGE_NAME}"
48+
TARGET_IMAGE="${INPUT_TARGET_REPO_NAME}/${INPUT_IMAGE_NAME}"
49+
EOF_MARKER="GHEOF_$(openssl rand -hex 8)"
50+
{
51+
echo "SOURCE_IMAGE<<${EOF_MARKER}"
52+
echo "${SOURCE_IMAGE}"
53+
echo "${EOF_MARKER}"
54+
echo "TARGET_IMAGE<<${EOF_MARKER}"
55+
echo "${TARGET_IMAGE}"
56+
echo "${EOF_MARKER}"
57+
} >> "$GITHUB_ENV"
4758
4859
- name: Checkout code
4960
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -59,12 +70,18 @@ jobs:
5970

6071
- name: Promote Images
6172
id: promote
73+
env:
74+
INPUT_TAGS: ${{ inputs.tags }}
75+
INPUT_SOURCE_TAG: ${{ inputs.source_tag }}
6276
run: |
6377
# Promote all specified tags
64-
IFS=',' read -ra TAGS <<< "${{ inputs.tags }}"
78+
IFS=',' read -ra TAGS <<< "${INPUT_TAGS}"
79+
for i in "${!TAGS[@]}"; do
80+
TAGS[$i]=$(echo "${TAGS[$i]}" | xargs)
81+
done
6582
for TAG in "${TAGS[@]}"; do
66-
if [[ "${{ inputs.source_tag }}" != "none" ]]; then
67-
source_image="${SOURCE_IMAGE}:${{ inputs.source_tag }}"
83+
if [[ "${INPUT_SOURCE_TAG}" != "none" ]]; then
84+
source_image="${SOURCE_IMAGE}:${INPUT_SOURCE_TAG}"
6885
else
6986
source_image="${SOURCE_IMAGE}:${TAG}"
7087
fi
@@ -87,9 +104,11 @@ jobs:
87104
push-to-registry: true
88105

89106
- name: Record Promotion
107+
env:
108+
INPUT_TAGS: ${{ inputs.tags }}
90109
run: |
91110
echo "## Image Promotion :rocket:" >> $GITHUB_STEP_SUMMARY
92111
echo "- From: $SOURCE_IMAGE" >> $GITHUB_STEP_SUMMARY
93112
echo "- To: $TARGET_IMAGE" >> $GITHUB_STEP_SUMMARY
94-
echo "- Tags: ${{ inputs.tags }}" >> $GITHUB_STEP_SUMMARY
113+
echo "- Tags: ${INPUT_TAGS}" >> $GITHUB_STEP_SUMMARY
95114
echo "- Timestamp: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY

.github/workflows/docker-promote-jfrog.yaml

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,39 +45,57 @@ jobs:
4545
name: Promote Docker image
4646
runs-on: ubuntu-latest
4747
steps:
48-
- name: Validade input
48+
- name: Validate input
49+
env:
50+
INPUT_TARGET_ENV: ${{ inputs.target_env }}
51+
INPUT_SOURCE_ENV: ${{ inputs.source_env }}
4952
run: |
50-
if [[ ! "${{ inputs.target_env }}" =~ ^(dev|staging|prod)$ ]]; then
51-
echo "Invalid environment. Choose 'dev', 'staging' or 'prod'"
53+
if [[ ! "${INPUT_TARGET_ENV}" =~ ^(staging|prod)$ ]]; then
54+
echo "Invalid environment. Choose 'staging' or 'prod'"
5255
exit 1
5356
fi
5457
55-
if [[ ! "${{ inputs.source_env }}" =~ ^(dev|staging|none)$ ]]; then
58+
if [[ ! "${INPUT_SOURCE_ENV}" =~ ^(dev|staging|none)$ ]]; then
5659
echo "Invalid environment. Choose 'dev', 'staging' or don't set it"
5760
exit 1
5861
fi
5962
6063
- name: Set environment variables
64+
env:
65+
INPUT_SOURCE_ENV: ${{ inputs.source_env }}
66+
INPUT_TARGET_ENV: ${{ inputs.target_env }}
67+
INPUT_JFROG_URL: ${{ inputs.jfrog_url }}
68+
INPUT_GROUP_NAME: ${{ inputs.group_name }}
69+
INPUT_IMAGE_NAME: ${{ inputs.image_name }}
6170
run: |
62-
if [[ "${{ inputs.source_env }}" == "none" ]]; then
63-
SOURCE_ENV=$([[ "${{ inputs.target_env }}" == "staging" ]] && echo "dev" || echo "staging")
64-
echo "SOURCE_ENV=${SOURCE_ENV}" >> $GITHUB_ENV
71+
if [[ "${INPUT_SOURCE_ENV}" == "none" ]]; then
72+
SOURCE_ENV=$([[ "${INPUT_TARGET_ENV}" == "staging" ]] && echo "dev" || echo "staging")
6573
else
66-
SOURCE_ENV="${{ inputs.source_env }}"
67-
echo "SOURCE_ENV=${SOURCE_ENV}" >> $GITHUB_ENV
74+
SOURCE_ENV="${INPUT_SOURCE_ENV}"
6875
fi
6976
70-
SOURCE_IMAGE="${{ inputs.jfrog_url }}/${{ inputs.group_name }}-oci-local-${SOURCE_ENV}/${{ inputs.image_name }}"
71-
TARGET_IMAGE="${{ inputs.jfrog_url }}/${{ inputs.group_name }}-oci-local-${{ inputs.target_env }}/${{ inputs.image_name }}"
72-
echo "SOURCE_IMAGE=${SOURCE_IMAGE}" >> $GITHUB_ENV
73-
echo "TARGET_IMAGE=${TARGET_IMAGE}" >> $GITHUB_ENV
77+
SOURCE_IMAGE="${INPUT_JFROG_URL}/${INPUT_GROUP_NAME}-oci-local-${SOURCE_ENV}/${INPUT_IMAGE_NAME}"
78+
TARGET_IMAGE="${INPUT_JFROG_URL}/${INPUT_GROUP_NAME}-oci-local-${INPUT_TARGET_ENV}/${INPUT_IMAGE_NAME}"
79+
80+
EOF_MARKER="GHEOF_$(openssl rand -hex 8)"
81+
{
82+
echo "SOURCE_ENV<<${EOF_MARKER}"
83+
echo "${SOURCE_ENV}"
84+
echo "${EOF_MARKER}"
85+
echo "SOURCE_IMAGE<<${EOF_MARKER}"
86+
echo "${SOURCE_IMAGE}"
87+
echo "${EOF_MARKER}"
88+
echo "TARGET_IMAGE<<${EOF_MARKER}"
89+
echo "${TARGET_IMAGE}"
90+
echo "${EOF_MARKER}"
91+
} >> "$GITHUB_ENV"
7492
7593
- name: Checkout code
7694
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
7795

7896
- name: Install JFrog CLI
7997
id: jfrog
80-
uses: jfrog/setup-jfrog-cli@v4
98+
uses: jfrog/setup-jfrog-cli@86dacb6974c66cc99e7651e1205f6581aaddba9a # v4.10.0
8199
env:
82100
JF_URL: https://${{ inputs.jfrog_url }}
83101
with:
@@ -95,12 +113,18 @@ jobs:
95113

96114
- name: Promote Images
97115
id: promote
116+
env:
117+
INPUT_TAGS: ${{ inputs.tags }}
118+
INPUT_SOURCE_TAG: ${{ inputs.source_tag }}
98119
run: |
99120
# Promote all specified tags
100-
IFS=',' read -ra TAGS <<< "${{ inputs.tags }}"
121+
IFS=',' read -ra TAGS <<< "${INPUT_TAGS}"
122+
for i in "${!TAGS[@]}"; do
123+
TAGS[$i]=$(echo "${TAGS[$i]}" | xargs)
124+
done
101125
for TAG in "${TAGS[@]}"; do
102-
if [[ "${{ inputs.source_tag }}" != "none" ]]; then
103-
source_image="${SOURCE_IMAGE}:${{ inputs.source_tag }}"
126+
if [[ "${INPUT_SOURCE_TAG}" != "none" ]]; then
127+
source_image="${SOURCE_IMAGE}:${INPUT_SOURCE_TAG}"
104128
else
105129
source_image="${SOURCE_IMAGE}:${TAG}"
106130
fi
@@ -124,9 +148,11 @@ jobs:
124148
push-to-registry: true
125149

126150
- name: Record Promotion
151+
env:
152+
INPUT_TAGS: ${{ inputs.tags }}
127153
run: |
128154
echo "## Image Promotion :rocket:" >> $GITHUB_STEP_SUMMARY
129155
echo "- From: $SOURCE_IMAGE" >> $GITHUB_STEP_SUMMARY
130156
echo "- To: $TARGET_IMAGE" >> $GITHUB_STEP_SUMMARY
131-
echo "- Tags: ${{ inputs.tags }}" >> $GITHUB_STEP_SUMMARY
157+
echo "- Tags: ${INPUT_TAGS}" >> $GITHUB_STEP_SUMMARY
132158
echo "- Timestamp: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)