Skip to content

Commit 154eda1

Browse files
authored
Merge pull request #535 from alphagov/improve-vulnerability-scanning
Merging as changes are to GithHub actions, no changes to actual Gem codebase.
2 parents 38e0201 + 3402c09 commit 154eda1

6 files changed

Lines changed: 124 additions & 39 deletions

File tree

.github/dependabot.yml

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# To get started with Dependabot version updates, you'll need to specify which
2-
# package ecosystems to update and where the package manifests are located.
3-
# Please see the documentation for all configuration options:
4-
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5-
61
version: 2
72
updates:
83
# 1. Update Ruby dependencies (Gemfile/gemspec) in the root
@@ -12,9 +7,11 @@ updates:
127
interval: "weekly"
138
day: "monday"
149
time: "06:00"
10+
# Essential for gem projects without a Gemfile.lock:
11+
versioning-strategy: "increase"
1512
commit-message:
1613
prefix: chore
17-
open-pull-requests-limit: 3
14+
open-pull-requests-limit: 5
1815
groups:
1916
prod-safe-updates:
2017
dependency-type: "production"
@@ -23,9 +20,15 @@ updates:
2320
update-types:
2421
- "minor"
2522
- "patch"
23+
dev-safe-updates:
24+
dependency-type: "development"
25+
patterns:
26+
- "*"
27+
update-types:
28+
- "minor"
29+
- "patch"
2630

27-
28-
# 2. Update GitHub Actions (keeps your CI workflows secure)
31+
# 2. Update GitHub Actions
2932
- package-ecosystem: "github-actions"
3033
directory: "/"
3134
schedule:
@@ -39,28 +42,26 @@ updates:
3942
patterns:
4043
- "*"
4144

45+
# 3. Update npm dependencies
4246
- package-ecosystem: "npm"
43-
directory: "/"
47+
directory: "/"
4448
schedule:
4549
interval: "weekly"
4650
day: "monday"
4751
time: "06:00"
48-
open-pull-requests-limit: 3
52+
open-pull-requests-limit: 5
4953
groups:
50-
# Group all "development" dependencies (linters, test runners, etc.)
5154
dev-dependencies:
5255
dependency-type: "development"
5356
patterns:
5457
- "*"
5558
update-types:
5659
- "patch"
5760
- "minor"
58-
# Group all "production" dependencies (react, express, etc.)
59-
# but ONLY for minor/patch versions to avoid breaking changes
6061
prod-safe-updates:
6162
dependency-type: "production"
6263
patterns:
6364
- "*"
6465
update-types:
6566
- "patch"
66-
- "minor"
67+
- "minor"

.github/workflows/dependency-review.yaml

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: NPM Audit Security Check
2+
3+
on:
4+
workflow_call:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
npm-audit:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout Code
15+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
19+
with:
20+
node-version: '20'
21+
cache: 'npm'
22+
23+
- name: Run NPM Audit & Generate Summary
24+
run: |
25+
# 1. Run npm audit in JSON mode to capture raw audit metadata
26+
AUDIT_JSON=$(npm audit --audit-level=high --json 2>/dev/null) || true
27+
28+
# 2. Extract counts using node's built-in JSON parser
29+
CRITICAL_COUNT=$(echo "$AUDIT_JSON" | node -e "let d=''; process.stdin.on('data', c => d += c); process.stdin.on('end', () => { try { console.log(JSON.parse(d).metadata.vulnerabilities.critical || 0) } catch { console.log(0) } })")
30+
HIGH_COUNT=$(echo "$AUDIT_JSON" | node -e "let d=''; process.stdin.on('data', c => d += c); process.stdin.on('end', () => { try { console.log(JSON.parse(d).metadata.vulnerabilities.high || 0) } catch { console.log(0) } })")
31+
32+
# 3. Build GitHub Job Summary Markdown
33+
echo "## 🛡️ NPM Dependency Audit Summary" >> $GITHUB_STEP_SUMMARY
34+
echo "" >> $GITHUB_STEP_SUMMARY
35+
36+
if [ "$CRITICAL_COUNT" -eq 0 ] && [ "$HIGH_COUNT" -eq 0 ]; then
37+
echo "✅ **No high or critical vulnerabilities found!** All JS packages passed security checks." >> $GITHUB_STEP_SUMMARY
38+
else
39+
echo "⚠️ **High/Critical Vulnerabilities Detected in npm Dependencies**" >> $GITHUB_STEP_SUMMARY
40+
echo "" >> $GITHUB_STEP_SUMMARY
41+
echo "| Vulnerability Severity | Total Count |" >> $GITHUB_STEP_SUMMARY
42+
echo "| :--- | :--- |" >> $GITHUB_STEP_SUMMARY
43+
echo "| 🔴 **Critical** | $CRITICAL_COUNT \vert{}" >> $GITHUB_STEP_SUMMARY
44+
echo "| 🟠 **High** | $HIGH_COUNT \vert{}" >> $GITHUB_STEP_SUMMARY
45+
echo "" >> $GITHUB_STEP_SUMMARY
46+
echo "### Detailed Audit Report" >> $GITHUB_STEP_SUMMARY
47+
echo '```text' >> $GITHUB_STEP_SUMMARY
48+
# Output human-readable audit text into the summary block
49+
npm audit --audit-level=high 2>/dev/null || true
50+
echo '```' >> $GITHUB_STEP_SUMMARY
51+
52+
# 4. Fail the workflow step
53+
echo "::error::npm audit detected $CRITICAL_COUNT critical and $HIGH_COUNT high vulnerabilities."
54+
exit 1
55+
fi

.github/workflows/pipeline.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ on:
66
branches: [ "main"]
77

88
jobs:
9-
dependency-review:
10-
uses: ./.github/workflows/dependency-review.yaml
9+
npm-vulnerability-scanner:
10+
uses: ./.github/workflows/npm-vulnerability-scanner.yaml
11+
permissions:
12+
contents: read
13+
14+
ruby-vulnerability-scanner:
15+
needs: npm-vulnerability-scanner
16+
uses: ./.github/workflows/ruby-vulnerability-scanner.yaml
1117
permissions:
1218
contents: read
1319

1420
test:
15-
needs: dependency-review
21+
needs: ruby-vulnerability-scanner
1622
uses: ./.github/workflows/test.yaml
1723
permissions:
1824
contents: read # Allows the action to check out your repository code
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Ruby vulnerability scanner
2+
3+
on:
4+
workflow_call:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
bundler-audit:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout Code
15+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
16+
17+
- name: Setup Ruby
18+
uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b
19+
with:
20+
ruby-version: '3.3'
21+
bundler-cache: true
22+
23+
- name: Run Audit Check
24+
run: |
25+
gem install bundler-audit
26+
27+
# Run audit and save output to file (preventing immediate job failure via || true)
28+
bundle-audit check --update > audit_results.txt || AUDIT_EXIT_CODE=$?
29+
30+
echo "## 🛡️ Ruby Dependency Audit Summary" >> $GITHUB_STEP_SUMMARY
31+
32+
if [ -z "$AUDIT_EXIT_CODE" ]; then
33+
echo "::notice::No vulnerabilities found in Ruby dependencies."
34+
echo "✅ **No vulnerabilities found!** All resolved gems from your `.gemspec` passed security checks." >> $GITHUB_STEP_SUMMARY
35+
else
36+
echo "⚠️ **Vulnerabilities Detected in Ruby Dependencies**" >> $GITHUB_STEP_SUMMARY
37+
echo "" >> $GITHUB_STEP_SUMMARY
38+
echo '```text' >> $GITHUB_STEP_SUMMARY
39+
cat audit_results.txt >> $GITHUB_STEP_SUMMARY
40+
echo '```' >> $GITHUB_STEP_SUMMARY
41+
42+
# Fail the step if vulnerabilities were found
43+
exit $AUDIT_EXIT_CODE
44+
fi

.github/workflows/test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: Test
22

33
on:
44
workflow_call:
5+
workflow_dispatch:
56

67
permissions:
78
contents: read # Allows the action to check out your repository code

0 commit comments

Comments
 (0)