updated codecov config #75
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 Scan | |
on: | |
push: | |
branches: [main, develop] | |
paths-ignore: | |
- "**.md" | |
- "_docs/**" | |
pull_request: | |
branches: [main, develop] | |
schedule: | |
- cron: "0 0 * * 0" # Run weekly on Sunday at midnight | |
workflow_dispatch: | |
jobs: | |
security-check: | |
name: Security Analysis | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
cache: "pip" | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install bandit safety | |
pip install -r requirements.txt | |
- name: Run Safety Check | |
run: | | |
echo "===== RUNNING SAFETY SECURITY SCAN =====" | |
safety check -r requirements.txt --full-report | |
# Generate a JSON report for artifact | |
safety check -r requirements.txt --json > safety-results.json | |
# Check if vulnerabilities are found and can be fixed | |
if grep -q "vulnerabilities found" safety-results.json; then | |
echo "===== ATTEMPTING TO FIX VULNERABILITIES =====" | |
safety scan --apply-fixes | |
fi | |
env: | |
SAFETY_API_KEY: ${{ secrets.SAFETY_API_KEY }} | |
continue-on-error: true | |
- name: Run Bandit | |
run: | | |
# First run with human-readable output directly to console | |
echo "===== RUNNING BANDIT SECURITY SCAN =====" | |
bandit -r backend/ --exclude "**/tests/**,**/test_*.py,**/*_test.py" -f screen || true | |
# Create output directory | |
mkdir -p reports | |
# Generate a more detailed report for CI analysis | |
bandit -r backend/ --exclude "**/tests/**,**/test_*.py,**/*_test.py" -f json -o reports/bandit-results.json || true | |
bandit -r backend/ --exclude "**/tests/**,**/test_*.py,**/*_test.py" -f html -o reports/bandit-results.html || true | |
continue-on-error: true | |
- name: Upload Bandit JSON Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: bandit-results | |
path: reports/bandit-results.json | |
- name: Upload Bandit HTML Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: bandit-html-results | |
path: reports/bandit-results.html | |
- name: Upload Safety Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: safety-results | |
path: safety-results.json | |
- name: Generate Summary | |
run: | | |
echo "## Security Scan Results" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "### Bandit Code Security Analysis" >> $GITHUB_STEP_SUMMARY | |
echo "[Download Bandit Results](../artifacts/bandit-results)" >> $GITHUB_STEP_SUMMARY | |
echo "[Download Bandit HTML Results](../artifacts/bandit-html-results)" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
if grep -q "\"issue_severity\": \"HIGH\"" reports/bandit-results.json; then | |
echo "⚠️ **High severity issues detected in code!** Please review the detailed reports." >> $GITHUB_STEP_SUMMARY | |
else | |
echo "✅ No high severity issues found in application code." >> $GITHUB_STEP_SUMMARY | |
fi | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "### Safety Dependency Analysis" >> $GITHUB_STEP_SUMMARY | |
echo "[Download Safety Results](../artifacts/safety-results)" >> $GITHUB_STEP_SUMMARY | |
echo "" >> $GITHUB_STEP_SUMMARY | |
if [ -f safety-results.json ]; then | |
VULN_COUNT=$(grep -o '"vulnerability"' safety-results.json | wc -l) | |
if [ "$VULN_COUNT" -gt 0 ]; then | |
echo "⚠️ **$VULN_COUNT vulnerabilities detected in dependencies!** Please review the detailed report." >> $GITHUB_STEP_SUMMARY | |
else | |
echo "✅ No vulnerabilities found in dependencies." >> $GITHUB_STEP_SUMMARY | |
fi | |
else | |
echo "⚠️ Safety report file not found." >> $GITHUB_STEP_SUMMARY | |
fi | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "**Note:** The Safety scan requires an API key to be set as a repository secret named 'SAFETY_API_KEY'." >> $GITHUB_STEP_SUMMARY | |
echo "Get your API key from https://docs.safetycli.com/api-key" >> $GITHUB_STEP_SUMMARY | |
dependency-check: | |
name: OWASP Dependency Check | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
cache: "pip" | |
- name: Run OWASP Dependency-Check | |
uses: dependency-check/Dependency-Check_Action@main | |
with: | |
project: "django-supabase-template" | |
path: "." | |
format: "HTML" | |
out: "reports" | |
args: > | |
--enableExperimental | |
--scan requirements.txt | |
--suppression .github/configs/dependency-check-suppressions.xml | |
- name: Upload OWASP Dependency Check Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: dependency-check-report | |
path: reports/dependency-check-report.html | |
- name: Check for Critical Vulnerabilities | |
run: | | |
if grep -q "CVSS Score: [8-9]\|CVSS Score: 10" reports/dependency-check-report.html; then | |
echo "::warning::Critical vulnerabilities found in dependencies!" | |
echo "Critical vulnerabilities with CVSS score >= 8.0 found in dependencies!" >> $GITHUB_STEP_SUMMARY | |
fi | |
# Add to summary | |
echo "" >> $GITHUB_STEP_SUMMARY | |
echo "### OWASP Dependency Check Results" >> $GITHUB_STEP_SUMMARY | |
echo "[Download OWASP Dependency Check Report](../artifacts/dependency-check-report)" >> $GITHUB_STEP_SUMMARY | |
jwt-security: | |
name: JWT Security Analysis | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
cache: "pip" | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install pyjwt cryptography | |
- name: Check JWT Implementation | |
run: | | |
grep -r "jwt\\.decode" backend/ || echo "No insecure JWT decode found" | |
grep -r "verify=False" backend/ || echo "No JWT verification bypasses found" | |
redis-security: | |
name: Redis Security Scan | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
cache: "pip" | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install redis-py-cluster cryptography | |
- name: Check Redis Security Configuration | |
run: | | |
# Check for unprotected Redis URLs | |
grep -r "REDIS_URL\|REDIS_HOST" backend/ --include="*.py" | grep -v "os\\.getenv\|environ" || echo "All Redis connections use environment variables" | |
# Check for missing SSL/TLS in production Redis connections | |
grep -r "StrictRedis\|Redis(" backend/ --include="*.py" | grep -E "ssl=True|ssl_cert_reqs" || echo "SSL verification checks needed for Redis in production" | |
# Check for weak Redis password patterns | |
grep -r "REDIS_PASSWORD" backend/ --include="*.py" | grep -E "os\\.getenv\|environ" || echo "Redis passwords should be retrieved from environment variables" | |
notify-results: | |
name: Notify Security Results | |
needs: [security-check, dependency-check, jwt-security, redis-security] | |
runs-on: ubuntu-latest | |
if: always() | |
steps: | |
- name: Send Security Scan Results | |
uses: slackapi/[email protected] | |
if: ${{ github.event_name != 'pull_request' && always() }} | |
with: | |
payload: | | |
{ | |
"text": "Security scan completed for ${{ github.repository }}", | |
"blocks": [ | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "*Security Scan Completed for ${{ github.repository }}*\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
} | |
}, | |
{ | |
"type": "section", | |
"fields": [ | |
{ | |
"type": "mrkdwn", | |
"text": "*Branch:* ${{ github.ref_name }}" | |
}, | |
{ | |
"type": "mrkdwn", | |
"text": "*Status:* ${{ job.status }}" | |
} | |
] | |
} | |
] | |
} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL || '' }} | |
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK |