Skip to content

Commit 18f2cea

Browse files
committed
Dependency Supply Chain Security via Sigstore 179,177,175,180
1 parent b42aca2 commit 18f2cea

21 files changed

Lines changed: 5807 additions & 123 deletions
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
name: Automated Security Testing
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
schedule:
9+
# Run daily at 2 AM UTC
10+
- cron: '0 2 * * *'
11+
workflow_dispatch:
12+
13+
jobs:
14+
security-fuzzing:
15+
name: Security Fuzzing & Vulnerability Scanning
16+
runs-on: ubuntu-latest
17+
18+
services:
19+
postgres:
20+
image: postgres:14-alpine
21+
env:
22+
POSTGRES_DB: substream_test
23+
POSTGRES_USER: test_user
24+
POSTGRES_PASSWORD: test_password
25+
options: >-
26+
--health-cmd pg_isready
27+
--health-interval 10s
28+
--health-timeout 5s
29+
--health-retries 5
30+
ports:
31+
- 5432:5432
32+
33+
redis:
34+
image: redis:7-alpine
35+
options: >-
36+
--health-cmd "redis-cli ping"
37+
--health-interval 10s
38+
--health-timeout 5s
39+
--health-retries 5
40+
ports:
41+
- 6379:6379
42+
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
47+
- name: Setup Node.js
48+
uses: actions/setup-node@v4
49+
with:
50+
node-version: '18'
51+
cache: 'npm'
52+
53+
- name: Install dependencies
54+
run: |
55+
npm ci
56+
npm install -g @zaproxy/zaproxy-cli
57+
58+
- name: Run database migrations
59+
env:
60+
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/substream_test
61+
REDIS_URL: redis://localhost:6379
62+
run: |
63+
npm run migrate
64+
65+
- name: Start backend application
66+
env:
67+
NODE_ENV: test
68+
DATABASE_URL: postgresql://test_user:test_password@localhost:5432/substream_test
69+
REDIS_URL: redis://localhost:6379
70+
PORT: 3000
71+
SOROBAN_RPC_URL: https://soroban-testnet.stellar.org
72+
SOROBAN_NETWORK_PASSPHRASE: Test SDF Network ; September 2015
73+
SOROBAN_CONTRACT_ID: test_contract_id
74+
SOROBAN_SOURCE_SECRET: test_secret
75+
run: |
76+
npm start &
77+
echo $! > backend.pid
78+
# Wait for backend to be ready
79+
for i in {1..30}; do
80+
if curl -s http://localhost:3000/health > /dev/null; then
81+
echo "Backend is ready"
82+
break
83+
fi
84+
echo "Waiting for backend... ($i/30)"
85+
sleep 2
86+
done
87+
88+
- name: Run authentication bypass tests
89+
env:
90+
BACKEND_URL: http://localhost:3000
91+
run: |
92+
npm test -- tests/security/auth-bypass.test.js
93+
94+
- name: Run SQL injection tests
95+
env:
96+
BACKEND_URL: http://localhost:3000
97+
run: |
98+
npm test -- tests/security/sql-injection.test.js
99+
100+
- name: Run XSS tests
101+
env:
102+
BACKEND_URL: http://localhost:3000
103+
run: |
104+
npm test -- tests/security/xss.test.js
105+
106+
- name: Run path traversal tests
107+
env:
108+
BACKEND_URL: http://localhost:3000
109+
run: |
110+
npm test -- tests/security/path-traversal.test.js
111+
112+
- name: Run Soroban webhook fuzzing tests
113+
env:
114+
BACKEND_URL: http://localhost:3000
115+
run: |
116+
npm test -- tests/security/soroban-webhook-fuzzing.test.js
117+
118+
- name: Run OWASP ZAP active scan
119+
env:
120+
BACKEND_URL: http://localhost:3000
121+
run: |
122+
mkdir -p zap-reports
123+
zap-cli quick-scan \
124+
--self-contained \
125+
--start-options '-config api.disablekey=true' \
126+
--spider \
127+
--scanners all \
128+
--alertLevel HIGH \
129+
$BACKEND_URL \
130+
-r zap-reports/zap-report.html \
131+
-l INFO
132+
133+
- name: Generate security report
134+
run: |
135+
node scripts/generate-security-report.js
136+
137+
- name: Upload security reports
138+
if: always()
139+
uses: actions/upload-artifact@v4
140+
with:
141+
name: security-reports
142+
path: |
143+
security-reports/
144+
zap-reports/
145+
retention-days: 30
146+
147+
- name: Comment PR with security results
148+
if: github.event_name == 'pull_request'
149+
uses: actions/github-script@v7
150+
with:
151+
script: |
152+
const fs = require('fs');
153+
const reportPath = 'security-reports/summary.json';
154+
155+
if (fs.existsSync(reportPath)) {
156+
const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
157+
158+
const comment = `## 🔒 Security Testing Results
159+
160+
**Overall Status:** ${report.passed ? '✅ PASSED' : '❌ FAILED'}
161+
162+
### Test Summary
163+
- Authentication Bypass: ${report.results.authBypass.passed ? '✅' : '❌'} (${report.results.authBypass.tests} tests)
164+
- SQL Injection: ${report.results.sqlInjection.passed ? '✅' : '❌'} (${report.results.sqlInjection.tests} tests)
165+
- XSS: ${report.results.xss.passed ? '✅' : '❌'} (${report.results.xss.tests} tests)
166+
- Path Traversal: ${report.results.pathTraversal.passed ? '✅' : '❌'} (${report.results.pathTraversal.tests} tests)
167+
- Soroban Webhook: ${report.results.sorobanWebhook.passed ? '✅' : '❌'} (${report.results.sorobanWebhook.tests} tests)
168+
- OWASP ZAP: ${report.results.zap.passed ? '✅' : '❌'} (${report.results.zap.alerts} alerts)
169+
170+
${!report.passed ? '### ⚠️ Critical Issues Found\n\nPlease review the full security report in the artifacts.' : ''}
171+
172+
[View Full Report](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`;
173+
174+
github.rest.issues.createComment({
175+
issue_number: context.issue.number,
176+
owner: context.repo.owner,
177+
repo: context.repo.repo,
178+
body: comment
179+
});
180+
}
181+
182+
- name: Stop backend
183+
if: always()
184+
run: |
185+
if [ -f backend.pid ]; then
186+
kill $(cat backend.pid) || true
187+
rm backend.pid
188+
fi
189+
190+
- name: Fail if security tests failed
191+
if: always()
192+
run: |
193+
node scripts/check-security-results.js
194+
195+
dependency-scan:
196+
name: Dependency Vulnerability Scan
197+
runs-on: ubuntu-latest
198+
199+
steps:
200+
- name: Checkout code
201+
uses: actions/checkout@v4
202+
203+
- name: Setup Node.js
204+
uses: actions/setup-node@v4
205+
with:
206+
node-version: '18'
207+
cache: 'npm'
208+
209+
- name: Install dependencies
210+
run: npm ci
211+
212+
- name: Run npm audit
213+
run: npm audit --audit-level=moderate
214+
continue-on-error: true
215+
216+
- name: Run Snyk security scan
217+
uses: snyk/actions/node@master
218+
env:
219+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
220+
with:
221+
args: --severity-threshold=high
222+
223+
secret-scan:
224+
name: Secret Scanning
225+
runs-on: ubuntu-latest
226+
227+
steps:
228+
- name: Checkout code
229+
uses: actions/checkout@v4
230+
with:
231+
fetch-depth: 0
232+
233+
- name: Run Gitleaks
234+
uses: gitleaks/gitleaks-action@v2
235+
env:
236+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
237+
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
238+
with:
239+
version: latest

0 commit comments

Comments
 (0)