Skip to content

Security Scanning

Security Scanning #16

Workflow file for this run

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
});