mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
Add security scanning to CI pipeline
- Add pip-audit check to PR workflow (non-blocking warning) - Add npm audit check to PR workflow (non-blocking warning) - Create scheduled weekly security audit workflow that: - Runs strict pip-audit and npm audit - Creates/updates GitHub issues when vulnerabilities found - Uploads audit results as artifacts - Supports manual trigger via workflow_dispatch
This commit is contained in:
@@ -44,6 +44,28 @@ jobs:
|
||||
- name: Run ruff format check
|
||||
run: ruff format --check backend/
|
||||
|
||||
backend-security:
|
||||
name: Backend Security
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.actor != github.repository_owner
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pip-audit
|
||||
|
||||
- name: Run pip-audit
|
||||
run: pip-audit --desc on
|
||||
|
||||
backend-tests:
|
||||
name: Backend Tests
|
||||
runs-on: ubuntu-latest
|
||||
@@ -103,6 +125,29 @@ jobs:
|
||||
working-directory: frontend
|
||||
run: npm run lint
|
||||
|
||||
frontend-security:
|
||||
name: Frontend Security
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.actor != github.repository_owner
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: frontend
|
||||
run: npm ci
|
||||
|
||||
- name: Run npm audit
|
||||
working-directory: frontend
|
||||
run: npm audit --audit-level=moderate
|
||||
|
||||
frontend-typecheck:
|
||||
name: Frontend Type Check
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
name: Security Audit
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run weekly on Monday at 6:00 UTC
|
||||
- cron: '0 6 * * 1'
|
||||
workflow_dispatch:
|
||||
# Allow manual trigger
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: '3.11'
|
||||
NODE_VERSION: '20'
|
||||
|
||||
jobs:
|
||||
backend-audit:
|
||||
name: Backend Security Audit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pip-audit
|
||||
|
||||
- name: Run pip-audit
|
||||
id: pip-audit
|
||||
run: |
|
||||
pip-audit --desc on --format json --output pip-audit-results.json || echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT
|
||||
pip-audit --desc on || true
|
||||
|
||||
- name: Upload audit results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pip-audit-results
|
||||
path: pip-audit-results.json
|
||||
retention-days: 30
|
||||
|
||||
- name: Create issue on vulnerability
|
||||
if: steps.pip-audit.outputs.vulnerabilities_found == 'true'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const results = JSON.parse(fs.readFileSync('pip-audit-results.json', 'utf8'));
|
||||
|
||||
// Build vulnerability table
|
||||
let table = '| Package | Version | Vulnerability | Fix Version |\n';
|
||||
table += '|---------|---------|---------------|-------------|\n';
|
||||
|
||||
for (const vuln of results.dependencies || []) {
|
||||
for (const v of vuln.vulns || []) {
|
||||
table += `| ${vuln.name} | ${vuln.version} | ${v.id} | ${v.fix_versions?.join(', ') || 'N/A'} |\n`;
|
||||
}
|
||||
}
|
||||
|
||||
const title = `Security Alert: ${results.dependencies?.reduce((acc, d) => acc + (d.vulns?.length || 0), 0) || 0} Python vulnerabilities found`;
|
||||
|
||||
// Check for existing open issue
|
||||
const existingIssues = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
labels: 'security,automated'
|
||||
});
|
||||
|
||||
const existingIssue = existingIssues.data.find(i => i.title.startsWith('Security Alert:') && i.title.includes('Python'));
|
||||
|
||||
const body = `## Automated Security Audit Results
|
||||
|
||||
The weekly security audit found vulnerabilities in Python dependencies.
|
||||
|
||||
${table}
|
||||
|
||||
### Recommended Actions
|
||||
|
||||
1. Review each vulnerability
|
||||
2. Update affected packages: \`pip install --upgrade <package>\`
|
||||
3. Run \`pip-audit\` locally to verify fixes
|
||||
4. Close this issue when resolved
|
||||
|
||||
---
|
||||
*This issue was automatically created by the security audit workflow.*`;
|
||||
|
||||
if (existingIssue) {
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: existingIssue.number,
|
||||
body: body
|
||||
});
|
||||
console.log(`Updated existing issue #${existingIssue.number}`);
|
||||
} else {
|
||||
await github.rest.issues.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
title: title,
|
||||
body: body,
|
||||
labels: ['security', 'automated', 'dependencies']
|
||||
});
|
||||
console.log('Created new security issue');
|
||||
}
|
||||
|
||||
frontend-audit:
|
||||
name: Frontend Security Audit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: frontend
|
||||
run: npm ci
|
||||
|
||||
- name: Run npm audit
|
||||
id: npm-audit
|
||||
working-directory: frontend
|
||||
run: |
|
||||
npm audit --json > npm-audit-results.json || echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT
|
||||
npm audit --audit-level=moderate || true
|
||||
|
||||
- name: Upload audit results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: npm-audit-results
|
||||
path: frontend/npm-audit-results.json
|
||||
retention-days: 30
|
||||
|
||||
- name: Create issue on vulnerability
|
||||
if: steps.npm-audit.outputs.vulnerabilities_found == 'true'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const results = JSON.parse(fs.readFileSync('frontend/npm-audit-results.json', 'utf8'));
|
||||
|
||||
const vulns = results.vulnerabilities || {};
|
||||
const vulnCount = Object.keys(vulns).length;
|
||||
|
||||
if (vulnCount === 0) {
|
||||
console.log('No vulnerabilities to report');
|
||||
return;
|
||||
}
|
||||
|
||||
// Build vulnerability table
|
||||
let table = '| Package | Severity | Via | Fix |\n';
|
||||
table += '|---------|----------|-----|-----|\n';
|
||||
|
||||
for (const [name, info] of Object.entries(vulns)) {
|
||||
const via = Array.isArray(info.via) ? info.via.map(v => typeof v === 'string' ? v : v.name).join(', ') : info.via;
|
||||
table += `| ${name} | ${info.severity} | ${via} | ${info.fixAvailable ? 'Yes' : 'No'} |\n`;
|
||||
}
|
||||
|
||||
const title = `Security Alert: ${vulnCount} npm vulnerabilities found`;
|
||||
|
||||
// Check for existing open issue
|
||||
const existingIssues = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
labels: 'security,automated'
|
||||
});
|
||||
|
||||
const existingIssue = existingIssues.data.find(i => i.title.startsWith('Security Alert:') && i.title.includes('npm'));
|
||||
|
||||
const body = `## Automated Security Audit Results
|
||||
|
||||
The weekly security audit found vulnerabilities in npm dependencies.
|
||||
|
||||
${table}
|
||||
|
||||
### Recommended Actions
|
||||
|
||||
1. Review each vulnerability: \`npm audit\`
|
||||
2. Auto-fix if possible: \`npm audit fix\`
|
||||
3. Manual fix for breaking changes: \`npm audit fix --force\` (review changes!)
|
||||
4. Close this issue when resolved
|
||||
|
||||
---
|
||||
*This issue was automatically created by the security audit workflow.*`;
|
||||
|
||||
if (existingIssue) {
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: existingIssue.number,
|
||||
body: body
|
||||
});
|
||||
console.log(`Updated existing issue #${existingIssue.number}`);
|
||||
} else {
|
||||
await github.rest.issues.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
title: title,
|
||||
body: body,
|
||||
labels: ['security', 'automated', 'dependencies']
|
||||
});
|
||||
console.log('Created new security issue');
|
||||
}
|
||||
Reference in New Issue
Block a user