save progress
This commit is contained in:
249
.gitea/workflows/dependency-security-scan.yml
Normal file
249
.gitea/workflows/dependency-security-scan.yml
Normal file
@@ -0,0 +1,249 @@
|
||||
# Dependency Security Scan
|
||||
# Sprint: CI/CD Enhancement - Dependency Management Automation
|
||||
#
|
||||
# Purpose: Scan dependencies for known vulnerabilities
|
||||
# Schedule: Weekly and on PRs modifying package files
|
||||
|
||||
name: Dependency Security Scan
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run weekly on Sundays at 02:00 UTC
|
||||
- cron: '0 2 * * 0'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/Directory.Packages.props'
|
||||
- '**/package.json'
|
||||
- '**/package-lock.json'
|
||||
- '**/*.csproj'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
fail_on_vulnerabilities:
|
||||
description: 'Fail if vulnerabilities found'
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: '10.0.100'
|
||||
|
||||
jobs:
|
||||
scan-nuget:
|
||||
name: NuGet Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
vulnerabilities_found: ${{ steps.scan.outputs.vulnerabilities_found }}
|
||||
critical_count: ${{ steps.scan.outputs.critical_count }}
|
||||
high_count: ${{ steps.scan.outputs.high_count }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
include-prerelease: true
|
||||
|
||||
- name: Restore packages
|
||||
run: dotnet restore src/StellaOps.sln
|
||||
|
||||
- name: Scan for vulnerabilities
|
||||
id: scan
|
||||
run: |
|
||||
mkdir -p security-reports
|
||||
|
||||
echo "Scanning NuGet packages for vulnerabilities..."
|
||||
|
||||
# Run vulnerability check
|
||||
dotnet list src/StellaOps.sln package --vulnerable --include-transitive \
|
||||
> security-reports/nuget-vulnerabilities.txt 2>&1 || true
|
||||
|
||||
# Parse results
|
||||
CRITICAL=$(grep -c "Critical" security-reports/nuget-vulnerabilities.txt 2>/dev/null || echo "0")
|
||||
HIGH=$(grep -c "High" security-reports/nuget-vulnerabilities.txt 2>/dev/null || echo "0")
|
||||
MEDIUM=$(grep -c "Medium" security-reports/nuget-vulnerabilities.txt 2>/dev/null || echo "0")
|
||||
LOW=$(grep -c "Low" security-reports/nuget-vulnerabilities.txt 2>/dev/null || echo "0")
|
||||
|
||||
TOTAL=$((CRITICAL + HIGH + MEDIUM + LOW))
|
||||
|
||||
echo "=== Vulnerability Summary ==="
|
||||
echo "Critical: $CRITICAL"
|
||||
echo "High: $HIGH"
|
||||
echo "Medium: $MEDIUM"
|
||||
echo "Low: $LOW"
|
||||
echo "Total: $TOTAL"
|
||||
|
||||
echo "critical_count=$CRITICAL" >> $GITHUB_OUTPUT
|
||||
echo "high_count=$HIGH" >> $GITHUB_OUTPUT
|
||||
echo "medium_count=$MEDIUM" >> $GITHUB_OUTPUT
|
||||
echo "low_count=$LOW" >> $GITHUB_OUTPUT
|
||||
|
||||
if [[ $TOTAL -gt 0 ]]; then
|
||||
echo "vulnerabilities_found=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "vulnerabilities_found=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Show detailed report
|
||||
echo ""
|
||||
echo "=== Detailed Report ==="
|
||||
cat security-reports/nuget-vulnerabilities.txt
|
||||
|
||||
- name: Upload NuGet security report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nuget-security-report
|
||||
path: security-reports/
|
||||
retention-days: 90
|
||||
|
||||
scan-npm:
|
||||
name: npm Vulnerability Scan
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
vulnerabilities_found: ${{ steps.scan.outputs.vulnerabilities_found }}
|
||||
critical_count: ${{ steps.scan.outputs.critical_count }}
|
||||
high_count: ${{ steps.scan.outputs.high_count }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Find and scan package.json files
|
||||
id: scan
|
||||
run: |
|
||||
mkdir -p security-reports
|
||||
|
||||
TOTAL_CRITICAL=0
|
||||
TOTAL_HIGH=0
|
||||
TOTAL_MEDIUM=0
|
||||
TOTAL_LOW=0
|
||||
VULNERABILITIES_FOUND=false
|
||||
|
||||
# Find all package.json files
|
||||
PACKAGES=$(find . -name "package.json" -not -path "*/node_modules/*" -not -path "*/bin/*" -not -path "*/obj/*")
|
||||
|
||||
for pkg in $PACKAGES; do
|
||||
DIR=$(dirname "$pkg")
|
||||
if [[ ! -f "$DIR/package-lock.json" ]] && [[ ! -f "$DIR/yarn.lock" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Scanning $DIR..."
|
||||
cd "$DIR"
|
||||
|
||||
# Install dependencies
|
||||
npm install --ignore-scripts 2>/dev/null || true
|
||||
|
||||
# Run npm audit
|
||||
REPORT_FILE="${GITHUB_WORKSPACE}/security-reports/npm-audit-$(basename $DIR).json"
|
||||
npm audit --json > "$REPORT_FILE" 2>/dev/null || true
|
||||
|
||||
# Parse results
|
||||
if [[ -f "$REPORT_FILE" ]]; then
|
||||
CRITICAL=$(jq '.metadata.vulnerabilities.critical // 0' "$REPORT_FILE" 2>/dev/null || echo "0")
|
||||
HIGH=$(jq '.metadata.vulnerabilities.high // 0' "$REPORT_FILE" 2>/dev/null || echo "0")
|
||||
MEDIUM=$(jq '.metadata.vulnerabilities.moderate // 0' "$REPORT_FILE" 2>/dev/null || echo "0")
|
||||
LOW=$(jq '.metadata.vulnerabilities.low // 0' "$REPORT_FILE" 2>/dev/null || echo "0")
|
||||
|
||||
TOTAL_CRITICAL=$((TOTAL_CRITICAL + CRITICAL))
|
||||
TOTAL_HIGH=$((TOTAL_HIGH + HIGH))
|
||||
TOTAL_MEDIUM=$((TOTAL_MEDIUM + MEDIUM))
|
||||
TOTAL_LOW=$((TOTAL_LOW + LOW))
|
||||
|
||||
if [[ $((CRITICAL + HIGH + MEDIUM + LOW)) -gt 0 ]]; then
|
||||
VULNERABILITIES_FOUND=true
|
||||
fi
|
||||
fi
|
||||
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
done
|
||||
|
||||
echo "=== npm Vulnerability Summary ==="
|
||||
echo "Critical: $TOTAL_CRITICAL"
|
||||
echo "High: $TOTAL_HIGH"
|
||||
echo "Medium: $TOTAL_MEDIUM"
|
||||
echo "Low: $TOTAL_LOW"
|
||||
|
||||
echo "critical_count=$TOTAL_CRITICAL" >> $GITHUB_OUTPUT
|
||||
echo "high_count=$TOTAL_HIGH" >> $GITHUB_OUTPUT
|
||||
echo "vulnerabilities_found=$VULNERABILITIES_FOUND" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload npm security report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: npm-security-report
|
||||
path: security-reports/
|
||||
retention-days: 90
|
||||
|
||||
summary:
|
||||
name: Security Summary
|
||||
runs-on: ubuntu-latest
|
||||
needs: [scan-nuget, scan-npm]
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Generate summary
|
||||
run: |
|
||||
NUGET_VULNS="${{ needs.scan-nuget.outputs.vulnerabilities_found }}"
|
||||
NPM_VULNS="${{ needs.scan-npm.outputs.vulnerabilities_found }}"
|
||||
|
||||
NUGET_CRITICAL="${{ needs.scan-nuget.outputs.critical_count }}"
|
||||
NUGET_HIGH="${{ needs.scan-nuget.outputs.high_count }}"
|
||||
NPM_CRITICAL="${{ needs.scan-npm.outputs.critical_count }}"
|
||||
NPM_HIGH="${{ needs.scan-npm.outputs.high_count }}"
|
||||
|
||||
echo "## Dependency Security Scan Results" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### NuGet Packages" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Critical | ${NUGET_CRITICAL:-0} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| High | ${NUGET_HIGH:-0} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "### npm Packages" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Critical | ${NPM_CRITICAL:-0} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| High | ${NPM_HIGH:-0} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Determine overall status
|
||||
TOTAL_CRITICAL=$((${NUGET_CRITICAL:-0} + ${NPM_CRITICAL:-0}))
|
||||
TOTAL_HIGH=$((${NUGET_HIGH:-0} + ${NPM_HIGH:-0}))
|
||||
|
||||
if [[ $TOTAL_CRITICAL -gt 0 ]]; then
|
||||
echo "### ⚠️ Critical Vulnerabilities Found" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Please review and remediate critical vulnerabilities before merging." >> $GITHUB_STEP_SUMMARY
|
||||
elif [[ $TOTAL_HIGH -gt 0 ]]; then
|
||||
echo "### ⚠️ High Severity Vulnerabilities Found" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Please review high severity vulnerabilities." >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "### ✅ No Critical or High Vulnerabilities" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Check gate
|
||||
if: github.event.inputs.fail_on_vulnerabilities == 'true' || github.event_name == 'pull_request'
|
||||
run: |
|
||||
NUGET_CRITICAL="${{ needs.scan-nuget.outputs.critical_count }}"
|
||||
NPM_CRITICAL="${{ needs.scan-npm.outputs.critical_count }}"
|
||||
|
||||
TOTAL_CRITICAL=$((${NUGET_CRITICAL:-0} + ${NPM_CRITICAL:-0}))
|
||||
|
||||
if [[ $TOTAL_CRITICAL -gt 0 ]]; then
|
||||
echo "::error::$TOTAL_CRITICAL critical vulnerabilities found in dependencies"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Security scan passed - no critical vulnerabilities"
|
||||
Reference in New Issue
Block a user