Skip to content

Commit 998302b

Browse files
authored
Merge pull request #41 from NVIDIA/fix/sonarqube-security-issues
fix: resolve SonarQube script injection and permission issues
2 parents 55343cf + 2459091 commit 998302b

4 files changed

Lines changed: 81 additions & 53 deletions

File tree

.github/actions/security-container-scan/action.yml

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ runs:
7070
- name: Precheck local image exists
7171
id: precheck
7272
shell: bash
73+
env:
74+
INPUT_IMAGE: ${{ inputs.image }}
7375
run: |
7476
set +e
75-
IMAGE="${{ inputs.image }}"
76-
docker image inspect "${IMAGE}" >/dev/null 2>&1
77+
docker image inspect "${INPUT_IMAGE}" >/dev/null 2>&1
7778
rc=$?
7879
if [ $rc -eq 0 ]; then
7980
echo "image_exists=true" >> "$GITHUB_OUTPUT"
@@ -96,13 +97,14 @@ runs:
9697
id: grype
9798
if: ${{ steps.precheck.outputs.image_exists == 'true' }}
9899
shell: bash
100+
env:
101+
IMAGE: ${{ inputs.image }}
102+
REPORT_JSON: ${{ inputs.report-json }}
103+
REPORT_SARIF: ${{ inputs.report-sarif }}
104+
FAIL_ON: ${{ inputs.fail-on }}
105+
GRYPE_IMAGE: ${{ inputs.grype-image }}
99106
run: |
100107
set +e
101-
IMAGE="${{ inputs.image }}"
102-
REPORT_JSON="${{ inputs.report-json }}"
103-
REPORT_SARIF="${{ inputs.report-sarif }}"
104-
FAIL_ON="${{ inputs.fail-on }}"
105-
GRYPE_IMAGE="${{ inputs.grype-image }}"
106108
107109
echo "Pulling Grype scanner image..."
108110
docker pull "${GRYPE_IMAGE}" >/dev/null 2>&1
@@ -147,58 +149,67 @@ runs:
147149
- name: Write scan summary
148150
if: ${{ inputs.write-summary == 'true' }}
149151
shell: bash
152+
env:
153+
INPUT_IMAGE: ${{ inputs.image }}
154+
INPUT_ARTIFACT_NAME: ${{ inputs.artifact-name }}
155+
INPUT_REPORT_JSON: ${{ inputs.report-json }}
150156
run: |
151157
set -euo pipefail
152158
echo "### 🔍 Container Scan (SBOM + Grype)" >> "$GITHUB_STEP_SUMMARY"
153159
echo "" >> "$GITHUB_STEP_SUMMARY"
154-
echo "- Image: \`${{ inputs.image }}\`" >> "$GITHUB_STEP_SUMMARY"
155-
echo "- Reports artifact: \`${{ inputs.artifact-name }}\` (sarif + json)" >> "$GITHUB_STEP_SUMMARY"
160+
echo "- Image: \`${INPUT_IMAGE}\`" >> "$GITHUB_STEP_SUMMARY"
161+
echo "- Reports artifact: \`${INPUT_ARTIFACT_NAME}\` (sarif + json)" >> "$GITHUB_STEP_SUMMARY"
156162
157-
if [ -f "${{ inputs.report-json }}" ]; then
158-
python3 "$GITHUB_ACTION_PATH/grype_summary.py" --json "${{ inputs.report-json }}" --max-top 10 >> "$GITHUB_STEP_SUMMARY" || true
163+
if [ -f "${INPUT_REPORT_JSON}" ]; then
164+
python3 "$GITHUB_ACTION_PATH/grype_summary.py" --json "${INPUT_REPORT_JSON}" --max-top 10 >> "$GITHUB_STEP_SUMMARY" || true
159165
fi
160166
161167
- name: Finalize status/outputs
162168
id: final
163169
if: always()
164170
shell: bash
171+
env:
172+
IMAGE_EXISTS: ${{ steps.precheck.outputs.image_exists }}
173+
SBOM_OUTCOME: ${{ steps.sbom.outcome }}
174+
GRYPE_STATUS: ${{ steps.grype.outputs.status }}
175+
GRYPE_EXIT: ${{ steps.grype.outputs.exit_code }}
176+
INPUT_GENERATE_SBOM: ${{ inputs.generate-sbom }}
177+
INPUT_FAIL_ON: ${{ inputs.fail-on }}
178+
INPUT_REPORT_JSON: ${{ inputs.report-json }}
179+
INPUT_REPORT_SARIF: ${{ inputs.report-sarif }}
180+
INPUT_FAIL_BUILD: ${{ inputs.fail-build }}
165181
run: |
166182
set -euo pipefail
167183
168-
IMAGE_EXISTS="${{ steps.precheck.outputs.image_exists }}"
169-
SBOM_OUTCOME="${{ steps.sbom.outcome }}"
170-
GRYPE_STATUS="${{ steps.grype.outputs.status }}"
171-
GRYPE_EXIT="${{ steps.grype.outputs.exit_code }}"
172-
173184
status="ok"
174185
detail="ok"
175186
176187
if [ "${IMAGE_EXISTS}" != "true" ]; then
177188
status="image_not_found"
178189
detail="local docker image not found"
179-
elif [ "${{ inputs.generate-sbom }}" = "true" ] && [ "${SBOM_OUTCOME}" != "success" ]; then
190+
elif [ "${INPUT_GENERATE_SBOM}" = "true" ] && [ "${SBOM_OUTCOME}" != "success" ]; then
180191
status="sbom_failed"
181192
detail="sbom-action failed"
182193
elif [ -z "${GRYPE_STATUS}" ]; then
183194
status="grype_unknown"
184195
detail="grype step did not produce status"
185196
elif [ "${GRYPE_STATUS}" = "ok" ]; then
186197
status="ok"
187-
detail="no vulnerabilities at/above fail-on=${{ inputs.fail-on }}"
198+
detail="no vulnerabilities at/above fail-on=${INPUT_FAIL_ON}"
188199
elif [ "${GRYPE_STATUS}" = "high_or_error" ]; then
189200
status="high_or_error"
190-
detail="grype exit_code=${GRYPE_EXIT} (fail-on=${{ inputs.fail-on }})"
201+
detail="grype exit_code=${GRYPE_EXIT} (fail-on=${INPUT_FAIL_ON})"
191202
else
192203
status="${GRYPE_STATUS}"
193204
detail="grype exit_code=${GRYPE_EXIT}"
194205
fi
195206
196207
echo "status=${status}" >> "$GITHUB_OUTPUT"
197208
echo "detail=${detail}" >> "$GITHUB_OUTPUT"
198-
echo "report_json=${{ inputs.report-json }}" >> "$GITHUB_OUTPUT"
199-
echo "report_sarif=${{ inputs.report-sarif }}" >> "$GITHUB_OUTPUT"
209+
echo "report_json=${INPUT_REPORT_JSON}" >> "$GITHUB_OUTPUT"
210+
echo "report_sarif=${INPUT_REPORT_SARIF}" >> "$GITHUB_OUTPUT"
200211
201-
if [ "${{ inputs.fail-build }}" = "true" ] && [ "${status}" != "ok" ]; then
212+
if [ "${INPUT_FAIL_BUILD}" = "true" ] && [ "${status}" != "ok" ]; then
202213
echo "Failing build due to status=${status}: ${detail}" 1>&2
203214
exit 1
204215
fi

.github/actions/slack-notify/action.yml

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,23 @@ runs:
5656
- name: Prepare Slack Payload
5757
id: prepare-payload
5858
shell: bash
59+
env:
60+
INPUT_CHANNEL_ID: ${{ inputs.channel-id }}
61+
INPUT_PAYLOAD: ${{ inputs.payload }}
62+
INPUT_MESSAGE: ${{ inputs.message }}
5963
run: |
60-
CHANNEL_ID="${{ inputs.channel-id }}"
61-
6264
# If custom payload is provided, merge channel into it
63-
if [ -n '${{ inputs.payload }}' ]; then
65+
if [ -n "${INPUT_PAYLOAD}" ]; then
6466
# Parse the JSON and add/update channel field
65-
PAYLOAD=$(cat <<'PAYLOAD_EOF' | jq -c ". + {channel: \"$CHANNEL_ID\"}"
66-
${{ inputs.payload }}
67-
PAYLOAD_EOF
68-
)
67+
PAYLOAD=$(echo "${INPUT_PAYLOAD}" | jq -c ". + {channel: \"${INPUT_CHANNEL_ID}\"}")
6968
echo "payload<<EOF" >> $GITHUB_OUTPUT
7069
echo "$PAYLOAD" >> $GITHUB_OUTPUT
7170
echo "EOF" >> $GITHUB_OUTPUT
72-
elif [ -n '${{ inputs.message }}' ]; then
71+
elif [ -n "${INPUT_MESSAGE}" ]; then
7372
# Simple message mode - construct basic payload
74-
MESSAGE=$(cat <<'MESSAGE_EOF'
75-
${{ inputs.message }}
76-
MESSAGE_EOF
77-
)
7873
PAYLOAD=$(jq -n \
79-
--arg channel "$CHANNEL_ID" \
80-
--arg text "$MESSAGE" \
74+
--arg channel "${INPUT_CHANNEL_ID}" \
75+
--arg text "${INPUT_MESSAGE}" \
8176
'{channel: $channel, text: $text}')
8277
echo "payload<<EOF" >> $GITHUB_OUTPUT
8378
echo "$PAYLOAD" >> $GITHUB_OUTPUT
@@ -100,32 +95,39 @@ runs:
10095
- name: Display Notification Info
10196
if: steps.slack.outcome == 'success'
10297
shell: bash
98+
env:
99+
SLACK_TS: ${{ steps.slack.outputs.ts }}
100+
SLACK_THREAD_TS: ${{ steps.slack.outputs.thread_ts }}
101+
INPUT_CHANNEL_ID: ${{ inputs.channel-id }}
102+
INPUT_ERRORS: ${{ inputs.errors }}
103103
run: |
104-
if [ -n "${{ steps.slack.outputs.ts }}" ]; then
104+
if [ -n "${SLACK_TS}" ]; then
105105
echo "✅ Slack notification sent successfully!"
106-
echo "📬 Channel ID: ${{ inputs.channel-id }}"
107-
echo "⏰ Timestamp: ${{ steps.slack.outputs.ts }}"
108-
if [ -n "${{ steps.slack.outputs.thread_ts }}" ]; then
109-
echo "🧵 Thread Timestamp: ${{ steps.slack.outputs.thread_ts }}"
106+
echo "📬 Channel ID: ${INPUT_CHANNEL_ID}"
107+
echo "⏰ Timestamp: ${SLACK_TS}"
108+
if [ -n "${SLACK_THREAD_TS}" ]; then
109+
echo "🧵 Thread Timestamp: ${SLACK_THREAD_TS}"
110110
fi
111111
else
112112
echo "⚠️ Slack API call completed but returned no timestamp!"
113113
echo "This usually means the bot doesn't have permission to post to the channel."
114114
echo ""
115115
echo "Common solutions:"
116-
echo " 1. Invite the bot to channel ${{ inputs.channel-id }}: /invite @YourBotName"
116+
echo " 1. Invite the bot to channel ${INPUT_CHANNEL_ID}: /invite @YourBotName"
117117
echo " 2. Add 'chat:write.public' scope to your bot (for public channels)"
118-
echo " 3. Verify the channel ID is correct: ${{ inputs.channel-id }}"
119-
if [ "${{ inputs.errors }}" == "true" ]; then
118+
echo " 3. Verify the channel ID is correct: ${INPUT_CHANNEL_ID}"
119+
if [ "${INPUT_ERRORS}" == "true" ]; then
120120
exit 1
121121
fi
122122
fi
123123
124124
- name: Display Error Info
125125
if: steps.slack.outcome == 'failure'
126126
shell: bash
127+
env:
128+
INPUT_ERRORS: ${{ inputs.errors }}
127129
run: |
128130
echo "❌ Slack notification failed!"
129-
if [ "${{ inputs.errors }}" == "false" ]; then
131+
if [ "${INPUT_ERRORS}" == "false" ]; then
130132
echo "⚠️ Continuing workflow despite failure (errors: false)"
131133
fi

.github/workflows/build-cds-containers.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ env:
1616
IMAGE_NAMESPACE: nvidia
1717
IMAGE_PREFIX: dsx-cds- # Prefix to identify CDS container images
1818

19-
permissions:
20-
contents: read
21-
packages: write # Required to push to GHCR
22-
2319
jobs:
2420
# Job 1: Read version from VERSION.md
2521
get-version:
2622
runs-on: ubuntu-latest
23+
permissions:
24+
contents: read
2725
outputs:
2826
version: ${{ steps.extract-version.outputs.version }}
2927

@@ -41,6 +39,9 @@ jobs:
4139
# Job 2: Build and push all container images
4240
build-and-push-images:
4341
runs-on: ubuntu-latest
42+
permissions:
43+
contents: read
44+
packages: write # Required to push to GHCR
4445
needs: get-version
4546
strategy:
4647
fail-fast: false
@@ -122,6 +123,9 @@ jobs:
122123
# Job 3: Test using the built go-dev image
123124
test-go-dev-image:
124125
runs-on: ubuntu-latest
126+
permissions:
127+
contents: read
128+
packages: read
125129
needs: [get-version, build-and-push-images]
126130
# Only run tests when images are pushed (main only)
127131
if: github.ref == 'refs/heads/main'
@@ -161,6 +165,9 @@ jobs:
161165
# Job 4: Test using tools container
162166
test-tools-image:
163167
runs-on: ubuntu-latest
168+
permissions:
169+
contents: read
170+
packages: read
164171
needs: [get-version, build-and-push-images]
165172
# Only run tests when images are pushed (main only)
166173
if: github.ref == 'refs/heads/main'
@@ -196,6 +203,8 @@ jobs:
196203
# Job 5: Summary
197204
summary:
198205
runs-on: ubuntu-latest
206+
permissions:
207+
contents: read
199208
needs: [get-version, build-and-push-images, test-go-dev-image, test-tools-image]
200209
if: always()
201210

.github/workflows/promote-image.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,24 @@ jobs:
6262
- name: Prepare refs
6363
id: refs
6464
shell: bash
65+
env:
66+
INPUT_DIGEST: ${{ inputs.digest }}
67+
INPUT_SOURCE: ${{ inputs.source }}
68+
INPUT_SOURCE_TAG: ${{ inputs.source_tag }}
69+
INPUT_DESTINATION: ${{ inputs.destination }}
70+
INPUT_DESTINATION_TAG: ${{ inputs.destination_tag }}
6571
run: |
6672
set -euo pipefail
6773
6874
# Assemble source reference
69-
if [[ -n "${{ inputs.digest }}" ]]; then
70-
source_ref="${{ inputs.source }}@${{ inputs.digest }}"
75+
if [[ -n "${INPUT_DIGEST}" ]]; then
76+
source_ref="${INPUT_SOURCE}@${INPUT_DIGEST}"
7177
else
72-
source_ref="${{ inputs.source }}:${{ inputs.source_tag }}"
78+
source_ref="${INPUT_SOURCE}:${INPUT_SOURCE_TAG}"
7379
fi
7480
7581
# Assemble destination reference
76-
destination_ref="${{ inputs.destination }}:${{ inputs.destination_tag }}"
82+
destination_ref="${INPUT_DESTINATION}:${INPUT_DESTINATION_TAG}"
7783
7884
echo "source_ref=${source_ref}" >> "$GITHUB_OUTPUT"
7985
echo "destination_ref=${destination_ref}" >> "$GITHUB_OUTPUT"

0 commit comments

Comments
 (0)