Security Scanning #117
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 daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| permissions: | |
| contents: read | |
| security-events: write | |
| pull-requests: write | |
| jobs: | |
| # Dependency scanning with Dependabot | |
| dependency-check: | |
| name: Dependency Vulnerability Scan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.9.0' | |
| cache: 'pnpm' | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v2 | |
| with: | |
| version: '10.33.2' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: npm audit security check | |
| run: npm audit --audit-level=high | |
| continue-on-error: true | |
| - name: Check for outdated packages | |
| run: npm outdated | |
| continue-on-error: true | |
| # CodeQL security scanning | |
| codeql: | |
| name: CodeQL Analysis | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| 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 }} | |
| # SAST with Snyk | |
| snyk: | |
| name: Snyk Security Scan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.9.0' | |
| cache: 'pnpm' | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v2 | |
| with: | |
| version: '10.33.2' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run Snyk test | |
| uses: snyk/actions/node@master | |
| env: | |
| SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
| with: | |
| args: --severity-threshold=high | |
| continue-on-error: true | |
| # Secret scanning | |
| secrets: | |
| name: Secret Detection | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: TruffleHog Secret Scan | |
| uses: trufflesecurity/trufflehog@main | |
| with: | |
| path: ./ | |
| base: ${{ github.event.repository.default_branch }} | |
| head: HEAD | |
| extra_args: --debug --only-verified | |
| continue-on-error: true | |
| - name: GitGuardian scan | |
| uses: GitGuardian/ggshield-action@master | |
| env: | |
| GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} | |
| continue-on-error: true | |
| # OWASP dependency check | |
| owasp: | |
| name: OWASP Dependency Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run OWASP Dependency Check | |
| uses: dependency-check/Dependency-Check_Action@main | |
| with: | |
| project: 'payload-website' | |
| path: '.' | |
| format: 'SARIF' | |
| continue-on-error: true | |
| - name: Upload OWASP results | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: 'dependency-check-report.sarif' | |
| continue-on-error: true | |
| # Security headers verification | |
| headers: | |
| name: Security Headers Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Check security headers in code | |
| run: | | |
| echo "Checking for security headers configuration..." | |
| # Check for HSTS header | |
| if grep -r "Strict-Transport-Security" src/; then | |
| echo "✅ HSTS header found" | |
| else | |
| echo "⚠️ HSTS header not configured" | |
| fi | |
| # Check for CSP header | |
| if grep -r "Content-Security-Policy" src/; then | |
| echo "✅ CSP header found" | |
| else | |
| echo "⚠️ CSP header not configured" | |
| fi | |
| # Check for X-Frame-Options | |
| if grep -r "X-Frame-Options" src/; then | |
| echo "✅ X-Frame-Options header found" | |
| else | |
| echo "⚠️ X-Frame-Options header not configured" | |
| fi | |
| # Check for common vulnerabilities | |
| semgrep: | |
| name: Semgrep Static Analysis | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Semgrep | |
| uses: returntocorp/semgrep-action@v1 | |
| with: | |
| config: >- | |
| p/security-audit | |
| p/owasp-top-ten | |
| p/typescript | |
| generateSarif: true | |
| continue-on-error: true | |
| - name: Upload Semgrep results | |
| uses: github/codeql-action/upload-sarif@v2 | |
| with: | |
| sarif_file: 'semgrep.sarif' | |
| continue-on-error: true | |
| # License compliance check | |
| license: | |
| name: License Compliance | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.9.0' | |
| cache: 'pnpm' | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v2 | |
| with: | |
| version: '10.33.2' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Check licenses with FOSSA | |
| uses: fossa-contrib/fossa-action@main | |
| with: | |
| license-scan: true | |
| continue-on-error: true | |
| # Summary | |
| security-summary: | |
| name: Security Scan Summary | |
| runs-on: ubuntu-latest | |
| needs: [dependency-check, codeql, snyk, secrets, owasp, headers, semgrep, license] | |
| if: always() | |
| steps: | |
| - name: Check security scan results | |
| run: | | |
| echo "Security Scanning Summary:" | |
| echo "==========================" | |
| echo "Dependency Check: ${{ needs.dependency-check.result }}" | |
| echo "CodeQL: ${{ needs.codeql.result }}" | |
| echo "Snyk: ${{ needs.snyk.result }}" | |
| echo "Secret Scan: ${{ needs.secrets.result }}" | |
| echo "OWASP: ${{ needs.owasp.result }}" | |
| echo "Headers: ${{ needs.headers.result }}" | |
| echo "Semgrep: ${{ needs.semgrep.result }}" | |
| echo "License: ${{ needs.license.result }}" | |
| if [ "${{ needs.codeql.result }}" == "failure" ]; then | |
| echo "❌ Security issues found" | |
| exit 1 | |
| else | |
| echo "✅ Security scan passed" | |
| fi |