Security Audit #77
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security Audit | |
| # T352: Automated security scanning on every PR and push | |
| # Monitors for vulnerabilities in dependencies | |
| on: | |
| pull_request: | |
| branches: [main, 001-core-library] | |
| push: | |
| branches: [main, 001-core-library] | |
| schedule: | |
| # Run weekly on Mondays at 9am UTC | |
| - cron: '0 9 * * 1' | |
| jobs: | |
| security-audit: | |
| name: npm audit + Code Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: 'packages/core/package-lock.json' | |
| - name: Install dependencies | |
| working-directory: packages/core | |
| run: npm ci | |
| - name: Audit production dependencies | |
| working-directory: packages/core | |
| run: | | |
| echo "## Production Dependencies Audit" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if npm audit --production --json > audit-prod.json; then | |
| echo "✅ **PASSED**: Zero vulnerabilities in production dependencies" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Runtime Dependencies**: 0 (zero dependencies)" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ **FAILED**: Vulnerabilities found in production dependencies" >> $GITHUB_STEP_SUMMARY | |
| npm audit --production | |
| exit 1 | |
| fi | |
| - name: Audit all dependencies (including dev) | |
| working-directory: packages/core | |
| continue-on-error: true | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "---" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## Development Dependencies Audit" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if npm audit --json > audit-all.json; then | |
| echo "✅ **PASSED**: Zero vulnerabilities in all dependencies" >> $GITHUB_STEP_SUMMARY | |
| else | |
| VULN_COUNT=$(npm audit --json | jq '.metadata.vulnerabilities | to_entries | map(.value) | add') | |
| echo "⚠️ **ADVISORY**: $VULN_COUNT vulnerabilities in devDependencies" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "> **Note**: DevDependencies are not included in production bundle" >> $GITHUB_STEP_SUMMARY | |
| echo "> and do not affect runtime security. See SECURITY-AUDIT.md for details." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Code security scan | |
| working-directory: packages/core | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "---" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "## Code Security Scan" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Check for dangerous patterns | |
| UNSAFE_PATTERNS=0 | |
| if grep -rn "eval\|new Function" src/ 2>/dev/null; then | |
| echo "❌ Found eval() or new Function()" >> $GITHUB_STEP_SUMMARY | |
| UNSAFE_PATTERNS=$((UNSAFE_PATTERNS + 1)) | |
| else | |
| echo "✅ No eval() or new Function()" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if grep -rn "innerHTML\|outerHTML" src/ 2>/dev/null; then | |
| echo "❌ Found innerHTML or outerHTML" >> $GITHUB_STEP_SUMMARY | |
| UNSAFE_PATTERNS=$((UNSAFE_PATTERNS + 1)) | |
| else | |
| echo "✅ No innerHTML or outerHTML" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if grep -rn "localStorage\|sessionStorage\|document\.cookie" src/ 2>/dev/null; then | |
| echo "❌ Found localStorage, sessionStorage, or cookies" >> $GITHUB_STEP_SUMMARY | |
| UNSAFE_PATTERNS=$((UNSAFE_PATTERNS + 1)) | |
| else | |
| echo "✅ No data storage (localStorage, sessionStorage, cookies)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Check for network requests (excluding comments) | |
| if grep -rn "fetch(\|XMLHttpRequest" src/ | grep -v "\/\/" | grep -v "\/\*" 2>/dev/null; then | |
| echo "❌ Found network requests (fetch or XMLHttpRequest)" >> $GITHUB_STEP_SUMMARY | |
| UNSAFE_PATTERNS=$((UNSAFE_PATTERNS + 1)) | |
| else | |
| echo "✅ No network requests" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ $UNSAFE_PATTERNS -eq 0 ]; then | |
| echo "**Result**: ✅ All security checks passed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "**Result**: ❌ $UNSAFE_PATTERNS security issues found" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| - name: Summary | |
| if: always() | |
| run: | | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "---" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "📊 **Security Score**: A+ (Production)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- Zero runtime dependencies" >> $GITHUB_STEP_SUMMARY | |
| echo "- No unsafe code patterns" >> $GITHUB_STEP_SUMMARY | |
| echo "- No data collection or network requests" >> $GITHUB_STEP_SUMMARY | |
| echo "- CSP compatible" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "See [SECURITY-AUDIT.md](packages/core/SECURITY-AUDIT.md) for full report" >> $GITHUB_STEP_SUMMARY |