-
Notifications
You must be signed in to change notification settings - Fork 1
341 lines (285 loc) · 12 KB
/
dependency-review.yml
File metadata and controls
341 lines (285 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
name: Dependency Review
# Concurrency control
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main ]
schedule:
# Weekly dependency scans on Saturdays at 2 AM UTC
- cron: '0 2 * * 6'
workflow_dispatch:
permissions:
contents: read
pull-requests: write
security-events: write
actions: read
jobs:
dependency-review:
name: Dependency Review
runs-on: ubuntu-24.04
timeout-minutes: 20
# Only run on pull requests (dependency-review-action requires base/head refs)
if: github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
# Fail the build on critical vulnerabilities
fail-on-severity: critical
# Comment on PR with results
comment-summary-in-pr: true
# Deny specific licenses (cannot use both allow and deny)
deny-licenses: GPL-2.0, GPL-3.0, AGPL-1.0, AGPL-3.0
# Allow all other vulnerabilities but warn
warn-only: true
# Enable vulnerability database check
vulnerability-check: true
# Enable license check
license-check: true
go-mod-scan:
name: Go Modules Security Scan
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24.7'
cache: true
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run Go vulnerability check
run: |
echo "## Go Vulnerability Scan Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Find all Go modules and scan them
module_count=0
vulnerable_modules=0
find . -name "go.mod" -type f | while read -r modfile; do
moddir=$(dirname "$modfile")
module_name=$(basename "$moddir")
module_count=$((module_count + 1))
echo "### Scanning module: $module_name" >> $GITHUB_STEP_SUMMARY
cd "$moddir"
# Run govulncheck
if govulncheck ./... 2>&1 | tee "$GITHUB_WORKSPACE/vuln-$module_name.txt"; then
echo "✅ No vulnerabilities found in $module_name" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Vulnerabilities found in $module_name" >> $GITHUB_STEP_SUMMARY
vulnerable_modules=$((vulnerable_modules + 1))
# Add vulnerability details to summary
echo "<details>" >> $GITHUB_STEP_SUMMARY
echo "<summary>Vulnerability details for $module_name</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
cat "$GITHUB_WORKSPACE/vuln-$module_name.txt" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
fi
cd - > /dev/null
done
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Summary**: Scanned $module_count modules, found vulnerabilities in $vulnerable_modules modules" >> $GITHUB_STEP_SUMMARY
- name: Upload vulnerability reports
if: always()
uses: actions/upload-artifact@v4
with:
name: go-vulnerability-reports
path: vuln-*.txt
retention-days: 30
npm-audit:
name: NPM Security Audit
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Find and audit NPM packages
run: |
echo "## NPM Security Audit Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Find all package.json files
package_files=$(find . -name "package.json" -type f | grep -v node_modules || true)
if [ -z "$package_files" ]; then
echo "No package.json files found in this repository." >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "$package_files" | while read -r pkgfile; do
pkgdir=$(dirname "$pkgfile")
pkg_name=$(basename "$pkgdir")
echo "### Auditing package: $pkg_name" >> $GITHUB_STEP_SUMMARY
cd "$pkgdir"
# Install dependencies first
npm ci --ignore-scripts 2>/dev/null || npm install --ignore-scripts 2>/dev/null || {
echo "❌ Failed to install dependencies for $pkg_name" >> $GITHUB_STEP_SUMMARY
cd - > /dev/null
continue
}
# Run npm audit
if npm audit --audit-level=moderate 2>&1 | tee "$GITHUB_WORKSPACE/npm-audit-$pkg_name.json"; then
echo "✅ No moderate+ vulnerabilities found in $pkg_name" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ Vulnerabilities found in $pkg_name" >> $GITHUB_STEP_SUMMARY
# Try to get a summary
npm audit --json > "$GITHUB_WORKSPACE/npm-audit-$pkg_name.json" 2>/dev/null || true
fi
cd - > /dev/null
done
- name: Upload NPM audit results
if: always()
uses: actions/upload-artifact@v4
with:
name: npm-audit-reports
path: npm-audit-*.json
retention-days: 30
python-safety-check:
name: Python Safety Check
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install safety
run: pip install safety
- name: Find and check Python requirements
run: |
echo "## Python Safety Check Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Find all requirements files
req_files=$(find . -name "requirements*.txt" -o -name "Pipfile*" -o -name "pyproject.toml" | grep -v .venv || true)
if [ -z "$req_files" ]; then
echo "No Python dependency files found in this repository." >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "$req_files" | while read -r reqfile; do
req_name=$(basename "$reqfile")
req_dir=$(dirname "$reqfile")
echo "### Checking file: $req_name" >> $GITHUB_STEP_SUMMARY
cd "$req_dir"
case "$req_name" in
requirements*.txt)
# For requirements.txt files
if safety check -r "$req_name" --json 2>&1 | tee "$GITHUB_WORKSPACE/safety-$(basename $req_dir)-$req_name.json"; then
echo "✅ No vulnerabilities found in $req_name" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ Vulnerabilities found in $req_name" >> $GITHUB_STEP_SUMMARY
fi
;;
pyproject.toml)
# For pyproject.toml files, try to extract dependencies
if command -v pip-audit >/dev/null 2>&1; then
pip-audit --format=json --output="$GITHUB_WORKSPACE/pip-audit-$(basename $req_dir).json" . || {
echo "⚠️ Could not audit $req_name" >> $GITHUB_STEP_SUMMARY
}
else
echo "ℹ️ pip-audit not available for $req_name" >> $GITHUB_STEP_SUMMARY
fi
;;
esac
cd - > /dev/null
done
- name: Upload Python safety results
if: always()
uses: actions/upload-artifact@v4
with:
name: python-safety-reports
path: |
safety-*.json
pip-audit-*.json
retention-days: 30
# Summary job that aggregates all dependency scan results
dependency-summary:
name: Dependency Scan Summary
runs-on: ubuntu-24.04
needs: [dependency-review, go-mod-scan, npm-audit, python-safety-check]
if: always()
timeout-minutes: 10
steps:
- name: Generate summary report
run: |
echo "# 🔍 Dependency Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Scanner | Status | Notes |" >> $GITHUB_STEP_SUMMARY
echo "|---------|--------|-------|" >> $GITHUB_STEP_SUMMARY
# Dependency Review status
if [[ "${{ needs.dependency-review.result }}" == "success" ]]; then
echo "| Dependency Review | ✅ Passed | No critical vulnerabilities found |" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.dependency-review.result }}" == "failure" ]]; then
echo "| Dependency Review | ❌ Failed | Critical vulnerabilities detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| Dependency Review | ⏭️ Skipped | Not applicable for this event |" >> $GITHUB_STEP_SUMMARY
fi
# Go vulnerability check status
if [[ "${{ needs.go-mod-scan.result }}" == "success" ]]; then
echo "| Go Vulnerability Check | ✅ Passed | No Go vulnerabilities found |" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.go-mod-scan.result }}" == "failure" ]]; then
echo "| Go Vulnerability Check | ⚠️ Issues | Go vulnerabilities detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| Go Vulnerability Check | ➖ N/A | No Go modules found |" >> $GITHUB_STEP_SUMMARY
fi
# NPM audit status
if [[ "${{ needs.npm-audit.result }}" == "success" ]]; then
echo "| NPM Security Audit | ✅ Passed | No NPM vulnerabilities found |" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.npm-audit.result }}" == "failure" ]]; then
echo "| NPM Security Audit | ⚠️ Issues | NPM vulnerabilities detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| NPM Security Audit | ➖ N/A | No NPM packages found |" >> $GITHUB_STEP_SUMMARY
fi
# Python safety check status
if [[ "${{ needs.python-safety-check.result }}" == "success" ]]; then
echo "| Python Safety Check | ✅ Passed | No Python vulnerabilities found |" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.python-safety-check.result }}" == "failure" ]]; then
echo "| Python Safety Check | ⚠️ Issues | Python vulnerabilities detected |" >> $GITHUB_STEP_SUMMARY
else
echo "| Python Safety Check | ➖ N/A | No Python packages found |" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📊 Overall Status" >> $GITHUB_STEP_SUMMARY
# Determine overall status
if [[ "${{ needs.dependency-review.result }}" == "failure" ]]; then
echo "❌ **CRITICAL**: Dependency review failed - immediate action required" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.go-mod-scan.result }}" == "failure" || "${{ needs.npm-audit.result }}" == "failure" || "${{ needs.python-safety-check.result }}" == "failure" ]]; then
echo "⚠️ **WARNING**: Some dependency scans found issues - review recommended" >> $GITHUB_STEP_SUMMARY
else
echo "✅ **PASSED**: All dependency scans completed successfully" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 🛠️ Next Steps" >> $GITHUB_STEP_SUMMARY
echo "1. Review detailed scan results in job logs" >> $GITHUB_STEP_SUMMARY
echo "2. Update vulnerable dependencies to secure versions" >> $GITHUB_STEP_SUMMARY
echo "3. Consider adding dependency pinning for critical packages" >> $GITHUB_STEP_SUMMARY
echo "4. Set up automated dependency updates with Dependabot" >> $GITHUB_STEP_SUMMARY