Security Scanning #21
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 Scanning | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| pull_request: | |
| branches: | |
| - main | |
| - develop | |
| schedule: | |
| # Run security scans every Monday at 9 AM UTC | |
| - cron: '0 9 * * 1' | |
| workflow_dispatch: | |
| jobs: | |
| dependency-audit: | |
| name: NPM Dependency Audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run npm audit | |
| run: npm audit --audit-level=moderate | |
| continue-on-error: true | |
| - name: Run npm audit fix | |
| run: npm audit fix --dry-run > audit-report.txt | |
| continue-on-error: true | |
| - name: Upload audit report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: npm-audit-report | |
| path: audit-report.txt | |
| codeql-analysis: | |
| name: CodeQL Security Analysis | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: ['javascript', 'typescript'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v2 | |
| with: | |
| languages: ${{ matrix.language }} | |
| queries: +security-and-quality | |
| - name: Autobuild | |
| uses: github/codeql-action/autobuild@v2 | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v2 | |
| with: | |
| category: "/language:${{ matrix.language }}" | |
| secret-scanning: | |
| name: Secret Scanning | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: TruffleHog Secret Scan | |
| uses: trufflesecurity/trufflehog@main | |
| continue-on-error: true | |
| with: | |
| path: ./ | |
| base: ${{ github.event.repository.default_branch }} | |
| head: HEAD | |
| extra_args: --only-verified | |
| smart-contract-security: | |
| name: Smart Contract Security Scan | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: packages/contracts | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Compile contracts | |
| run: npm run compile | |
| - name: Run Slither | |
| uses: crytic/slither-action@v0.3.0 | |
| id: slither | |
| continue-on-error: true | |
| with: | |
| target: 'packages/contracts' | |
| slither-args: '--filter-paths "node_modules|test"' | |
| fail-on: medium | |
| sarif: results.sarif | |
| - name: Upload Slither SARIF | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: ${{ steps.slither.outputs.sarif }} | |
| - name: Mythril Security Analysis | |
| continue-on-error: true | |
| run: | | |
| pip3 install mythril | |
| myth analyze contracts/**/*.sol --solv 0.8.20 || true | |
| sast-scan: | |
| name: SAST (Static Analysis) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint Security Plugin | |
| run: | | |
| npx eslint . \ | |
| --ext .js,.jsx,.ts,.tsx \ | |
| --format json \ | |
| --output-file eslint-report.json \ | |
| --plugin security \ | |
| --rule 'security/detect-object-injection: error' \ | |
| --rule 'security/detect-non-literal-regexp: error' \ | |
| --rule 'security/detect-unsafe-regex: error' || true | |
| - name: Upload ESLint report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: eslint-security-report | |
| path: eslint-report.json | |
| dependency-review: | |
| name: Dependency Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Dependency Review | |
| uses: actions/dependency-review-action@v3 | |
| with: | |
| fail-on-severity: moderate | |
| deny-licenses: GPL-2.0, GPL-3.0 | |
| license-check: | |
| name: License Compliance Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Check licenses | |
| run: | | |
| npx license-checker \ | |
| --summary \ | |
| --excludePrivatePackages \ | |
| --failOn 'GPL;AGPL;LGPL' \ | |
| > license-report.txt || true | |
| - name: Upload license report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: license-report | |
| path: license-report.txt | |
| security-report: | |
| name: Generate Security Report | |
| runs-on: ubuntu-latest | |
| needs: [dependency-audit, codeql-analysis, secret-scanning, smart-contract-security, sast-scan] | |
| if: always() | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: '*' | |
| merge-multiple: true | |
| - name: Create security summary | |
| run: | | |
| echo "# Security Scan Summary" > security-summary.md | |
| echo "" >> security-summary.md | |
| echo "**Date:** $(date)" >> security-summary.md | |
| echo "**Commit:** ${{ github.sha }}" >> security-summary.md | |
| echo "" >> security-summary.md | |
| echo "## Scan Results" >> security-summary.md | |
| echo "- Dependency Audit: ${{ needs.dependency-audit.result }}" >> security-summary.md | |
| echo "- CodeQL Analysis: ${{ needs.codeql-analysis.result }}" >> security-summary.md | |
| echo "- Secret Scanning: ${{ needs.secret-scanning.result }}" >> security-summary.md | |
| echo "- Contract Security: ${{ needs.smart-contract-security.result }}" >> security-summary.md | |
| echo "- SAST Scan: ${{ needs.sast-scan.result }}" >> security-summary.md | |
| - name: Upload security summary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-summary | |
| path: security-summary.md | |
| - name: Comment PR with security results | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const summary = fs.readFileSync('security-summary.md', 'utf8'); | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: summary | |
| }); |