Skip to content

Security Scanning

Security Scanning #114

Workflow file for this run

name: Security Scanning
on:
push:
branches: [ main, develop ]
paths:
- '**/*.py'
- '**/*.js'
- '**/*.ts'
- '**/*.jsx'
- '**/*.tsx'
- '**/*.sh'
- '**/*.yml'
- '**/*.yaml'
- '**/requirements*.txt'
- '**/package*.json'
- '**/Dockerfile*'
- '**/.env*'
- '**/nginx.conf'
- '**/*.toml'
- '**/*.conf'
- '**/*.config'
- '.github/workflows/security-scan.yml'
pull_request:
branches: [ main ]
paths:
- '**/*.py'
- '**/*.js'
- '**/*.ts'
- '**/*.jsx'
- '**/*.tsx'
- '**/*.sh'
- '**/*.yml'
- '**/*.yaml'
- '**/requirements*.txt'
- '**/package*.json'
- '**/Dockerfile*'
- '**/.env*'
- '**/nginx.conf'
- '**/*.toml'
- '**/*.conf'
- '**/*.config'
- '.github/workflows/security-scan.yml'
schedule:
# Daily quick scan at 2 AM UTC
- cron: '0 2 * * *'
# Weekly comprehensive scan on Sundays at 3 AM UTC
- cron: '0 3 * * 0'
workflow_dispatch:
inputs:
scan_type:
description: 'Type of security scan'
required: false
default: 'standard'
type: choice
options:
- standard
- comprehensive
- quick
permissions:
contents: read
security-events: write
issues: write
pull-requests: write
jobs:
# Monitor queue time before scans
queue-monitor:
name: Queue Time Monitor
uses: ./.github/workflows/queue-monitor-reusable.yml
security-headers-check:
name: Security Headers Validation
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Validate nginx security headers
run: |
echo "🔍 Checking nginx security headers..."
# Check for required security headers in nginx.conf
REQUIRED_HEADERS=(
"Content-Security-Policy"
"X-Frame-Options"
"X-Content-Type-Options"
"Strict-Transport-Security"
"Referrer-Policy"
"Permissions-Policy"
)
MISSING_HEADERS=()
for header in "${REQUIRED_HEADERS[@]}"; do
if ! grep -q "$header" fly/web/nginx.conf; then
MISSING_HEADERS+=("$header")
fi
done
if [ ${#MISSING_HEADERS[@]} -eq 0 ]; then
echo "✅ All required security headers are present"
else
echo "❌ Missing security headers:"
printf '%s\n' "${MISSING_HEADERS[@]}"
exit 1
fi
- name: Check for wildcard CORS
run: |
echo "🔍 Checking for wildcard CORS configurations..."
if grep -r "Access-Control-Allow-Origin.*\*" fly/; then
echo "❌ Found wildcard CORS configuration - this is a security risk!"
exit 1
else
echo "✅ No wildcard CORS found"
fi
dependency-security-scan:
name: Dependency Security Scan
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Python Safety Check
run: |
echo "🔍 Checking Python dependencies for vulnerabilities..."
pip install safety
cd fly/eagle-monitor
safety check -r requirements.txt || true
- name: Cache npm dependencies
uses: actions/cache@v3
if: hashFiles('package-lock.json') != ''
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Run npm audit
run: |
echo "🔍 Checking npm dependencies for vulnerabilities..."
if [ -f "package.json" ]; then
npm audit --production || true
fi
code-security-scan:
name: Code Security Analysis
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Semgrep Security Scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/owasp-top-ten
p/flask
p/python
p/javascript
p/typescript
generateSarif: true
continue-on-error: true
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
if: always()
continue-on-error: true
api-security-check:
name: API Security Validation
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for API authentication
run: |
echo "🔍 Checking API authentication implementation..."
# Check for API key authentication in eagle-monitor
if grep -q "require_api_key" fly/eagle-monitor/app.py; then
echo "✅ API authentication decorator found"
else
echo "⚠️ Warning: API authentication may not be properly implemented"
fi
# Check for rate limiting
if grep -q "rate_limit" fly/eagle-monitor/app.py; then
echo "✅ Rate limiting implementation found"
else
echo "⚠️ Warning: Rate limiting may not be implemented"
fi
secrets-scan:
name: Secrets Detection
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
docker-security-scan:
name: Docker Security Scan
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 20
strategy:
matrix:
service: [web, eagle-monitor, grafana, influxdb]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'config'
scan-ref: 'fly/${{ matrix.service }}/Dockerfile'
format: 'sarif'
output: 'trivy-${{ matrix.service }}-results.sarif'
continue-on-error: true
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-${{ matrix.service }}-results.sarif'
if: always()
configuration-security-scan:
name: Configuration Security Scan
runs-on: ubuntu-latest
needs: [queue-monitor]
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for exposed secrets in configs
run: |
echo "🔍 Scanning configuration files for potential secrets..."
# Define patterns to search for
PATTERNS=(
"password.*=.*['\"].*['\"]"
"api_key.*=.*['\"].*['\"]"
"secret.*=.*['\"].*['\"]"
"token.*=.*['\"].*['\"]"
"private_key.*=.*['\"].*['\"]"
"aws_access_key.*=.*['\"].*['\"]"
)
# Define files to scan
CONFIG_FILES=$(find . -type f \( -name "*.yml" -o -name "*.yaml" -o -name "*.toml" -o -name "*.json" -o -name "*.conf" -o -name "*.config" -o -name ".env*" \) -not -path "./.git/*" -not -path "./node_modules/*")
FOUND_ISSUES=false
# Scan configuration files
for pattern in "${PATTERNS[@]}"; do
echo "Checking pattern: $pattern"
if echo "$CONFIG_FILES" | xargs grep -l -E -i "$pattern" 2>/dev/null; then
echo "::warning::Potential secret pattern found in configuration files"
FOUND_ISSUES=true
fi
done
if [ "$FOUND_ISSUES" = false ]; then
echo "✅ No potential secrets found in configuration files"
fi
- name: Check shell script security
if: github.event.inputs.scan_type != 'quick'
run: |
echo "🔍 Scanning shell scripts for security issues..."
# Find all shell scripts
SHELL_SCRIPTS=$(find . -type f -name "*.sh" -not -path "./.git/*" -not -path "./node_modules/*")
if [ -z "$SHELL_SCRIPTS" ]; then
echo "No shell scripts found to scan"
exit 0
fi
# Check for common security issues
echo "Checking for hardcoded credentials..."
echo "$SHELL_SCRIPTS" | xargs grep -l -E "password=|PASSWORD=|token=|TOKEN=" 2>/dev/null || echo "✅ No hardcoded credentials found"
echo "Checking for unsafe curl usage..."
echo "$SHELL_SCRIPTS" | xargs grep -l "curl.*-k\|curl.*--insecure" 2>/dev/null || echo "✅ No insecure curl usage found"
echo "Checking for unsafe file permissions..."
echo "$SHELL_SCRIPTS" | xargs grep -l "chmod 777\|chmod 666" 2>/dev/null || echo "✅ No unsafe file permissions found"
- name: Validate YAML files
run: |
echo "🔍 Validating YAML configuration files..."
# Install yamllint
pip install yamllint
# Find and validate YAML files
find . -type f \( -name "*.yml" -o -name "*.yaml" \) -not -path "./.git/*" -not -path "./node_modules/*" | while read -r file; do
if ! yamllint -d relaxed "$file" 2>/dev/null; then
echo "::warning::YAML validation failed for $file"
fi
done || echo "✅ YAML validation complete"
security-report:
name: Security Report Summary
runs-on: ubuntu-latest
needs: [queue-monitor, security-headers-check, dependency-security-scan, code-security-scan, api-security-check, secrets-scan, docker-security-scan, configuration-security-scan]
if: always()
timeout-minutes: 5
steps:
- name: Generate Security Report
run: |
echo "## 🔒 Security Scan Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Scan Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check job statuses
if [ "${{ needs.security-headers-check.result }}" == "success" ]; then
echo "✅ **Security Headers**: All required headers present" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **Security Headers**: Missing or incorrect headers" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.api-security-check.result }}" == "success" ]; then
echo "✅ **API Security**: Authentication and rate limiting implemented" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ **API Security**: Review authentication implementation" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.configuration-security-scan.result }}" == "success" ]; then
echo "✅ **Configuration Security**: No exposed secrets in config files" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ **Configuration Security**: Review configuration files for issues" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Scan Type" >> $GITHUB_STEP_SUMMARY
if [ "${{ github.event_name }}" == "schedule" ]; then
if [ "$(date +%w)" == "0" ]; then
echo "🔍 **Weekly Comprehensive Scan**" >> $GITHUB_STEP_SUMMARY
else
echo "🔍 **Daily Quick Scan**" >> $GITHUB_STEP_SUMMARY
fi
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "🔍 **Manual Scan**: ${{ github.event.inputs.scan_type || 'standard' }}" >> $GITHUB_STEP_SUMMARY
else
echo "🔍 **Triggered by**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
echo "1. Review any security findings in the detailed logs" >> $GITHUB_STEP_SUMMARY
echo "2. Update dependencies with known vulnerabilities" >> $GITHUB_STEP_SUMMARY
echo "3. Address any code security issues identified by Semgrep" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Report Generated**: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_STEP_SUMMARY
notify-security-issues:
name: Notify Security Issues
runs-on: ubuntu-latest
needs: [security-report]
if: failure()
steps:
- name: Create Issue for Security Findings
uses: actions/github-script@v7
with:
script: |
const title = '🔒 Security Scan Found Issues';
const body = `
## Security Scan Results
The automated security scan has identified potential security issues.
**Scan Date**: ${new Date().toISOString()}
**Workflow Run**: [#${context.runNumber}](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
### Required Actions:
1. Review the security scan results in the workflow logs
2. Address any high-priority findings
3. Update this issue with remediation status
### Security Checklist:
- [ ] Security headers properly configured
- [ ] No wildcard CORS configurations
- [ ] API authentication implemented
- [ ] Rate limiting active
- [ ] No secrets in code
- [ ] Dependencies up to date
cc @${context.actor}
`;
// Check if similar issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security'
});
const existingIssue = issues.data.find(issue =>
issue.title.includes('Security Scan Found Issues')
);
if (!existingIssue) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['security', 'automated']
});
}