Skip to content

chore(deps): bump fastapi in /reference-apps/fastapi (#102) #237

chore(deps): bump fastapi in /reference-apps/fastapi (#102)

chore(deps): bump fastapi in /reference-apps/fastapi (#102) #237

Workflow file for this run

name: Security Scanning
on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main, develop ]
schedule:
# Run weekly on Mondays at 9:00 AM UTC
- cron: '0 9 * * 1'
workflow_dispatch:
permissions:
contents: read
security-events: write
jobs:
secret-scan:
name: Secret Scanning
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0 # Full history for better secret detection
- name: TruffleHog Secret Scan
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified
- name: Gitleaks Secret Scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check for common secret patterns
run: |
echo "Checking for common secret patterns..."
# Check for AWS keys
if git grep -iE 'AKIA[0-9A-Z]{16}' -- ':!.github/workflows/security.yml'; then
echo "⚠ Warning: Found potential AWS access key"
fi
# Check for private keys
if git grep -l 'BEGIN.*PRIVATE KEY' -- ':!.github/workflows/security.yml'; then
echo "⚠ Warning: Found potential private key"
fi
# Check for generic secrets
if git grep -iE '(password|passwd|pwd|secret|token|api_key|apikey).*=.*["\047][^"\047]{20,}["\047]' -- ':!.github/workflows/security.yml' ':!*.md'; then
echo "⚠ Warning: Found potential hardcoded secrets"
fi
echo "✓ Secret pattern check completed"
dependency-scan:
name: Dependency Scanning
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check for Python dependencies
id: check-python
run: |
if [ -f "requirements.txt" ] || find . -name "requirements.txt" -type f | grep -q .; then
echo "has_python=true" >> $GITHUB_OUTPUT
else
echo "has_python=false" >> $GITHUB_OUTPUT
fi
- name: Set up Python
if: steps.check-python.outputs.has_python == 'true'
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install Safety
if: steps.check-python.outputs.has_python == 'true'
run: pip install safety
- name: Check Python dependencies
if: steps.check-python.outputs.has_python == 'true'
run: |
find . -name "requirements.txt" -type f | while read req_file; do
echo "Checking $req_file..."
safety check --file "$req_file" --output text || true
done
continue-on-error: true
- name: Scan Docker images for vulnerabilities
run: |
echo "Installing Trivy for Docker image scanning..."
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.58.0
echo ""
echo "Extracting Docker images from docker-compose.yml..."
# Get unique images from docker-compose.yml (resolve env vars to defaults)
images=$(grep -E "^\s+image:" docker-compose.yml | \
sed 's/.*image:\s*//' | \
sed 's/\${[^:]*:-\([^}]*\)}/\1/g' | \
sort -u)
echo "Found images:"
echo "$images"
echo ""
vuln_count=0
critical_count=0
for image in $images; do
echo ""
echo "=========================================="
echo "Scanning: $image"
echo "=========================================="
# Scan for CRITICAL and HIGH vulnerabilities
if ! trivy image --severity CRITICAL,HIGH --no-progress --exit-code 0 "$image" 2>/dev/null; then
echo "⚠ Warning: Could not scan $image (may need to be pulled first)"
continue
fi
# Count critical vulnerabilities
critical=$(trivy image --severity CRITICAL --no-progress --format json "$image" 2>/dev/null | \
jq '[.Results[]?.Vulnerabilities // [] | length] | add // 0' 2>/dev/null || echo "0")
if [ "$critical" -gt 0 ]; then
echo "⚠ Found $critical CRITICAL vulnerabilities in $image"
critical_count=$((critical_count + critical))
fi
vuln_count=$((vuln_count + 1))
done
echo ""
echo "=========================================="
echo "Scan Summary"
echo "=========================================="
echo "Images scanned: $vuln_count"
echo "Total CRITICAL vulnerabilities: $critical_count"
if [ "$critical_count" -gt 0 ]; then
echo ""
echo "⚠ Warning: Critical vulnerabilities found. Review and update affected images."
fi
trivy-scan:
name: Trivy Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: 'trivy-results.sarif'
- name: Run Trivy for configuration files
uses: aquasecurity/trivy-action@master
with:
scan-type: 'config'
scan-ref: '.'
format: 'table'
exit-code: '0'
severity: 'CRITICAL,HIGH,MEDIUM'
docker-compose-security:
name: Docker Compose Security Review
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check for security best practices
run: |
echo "Checking Docker Compose security configuration..."
issues=0
# Check for privileged containers
if grep -q "privileged: true" docker-compose.yml; then
echo "⚠ Warning: Found privileged containers - security risk"
issues=$((issues + 1))
fi
# Check for host network mode
if grep -q "network_mode:.*host" docker-compose.yml; then
echo "⚠ Warning: Found host network mode - potential security risk"
issues=$((issues + 1))
fi
# Check for volume mounts to root
if grep -q "/:/.*:rw" docker-compose.yml; then
echo "⚠ Warning: Found read-write mount to host root - security risk"
issues=$((issues + 1))
fi
# Check for missing read-only root filesystem
if ! grep -q "read_only: true" docker-compose.yml; then
echo "ℹ Info: Consider using read-only root filesystems where possible"
fi
# Check for missing resource limits
if ! grep -q "limits:" docker-compose.yml; then
echo "ℹ Info: Consider adding resource limits to prevent DoS"
fi
# Check for exposed ports
if grep -q "0.0.0.0:" docker-compose.yml; then
echo "ℹ Info: Services exposed on 0.0.0.0 - ensure this is intended"
fi
if [ $issues -eq 0 ]; then
echo "✓ No critical security issues found in Docker Compose"
else
echo ""
echo "Found $issues security warning(s) in Docker Compose configuration"
fi
env-security:
name: Environment File Security
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check .env.example for weak defaults
run: |
echo "Checking .env.example for security issues..."
issues=0
# Check for weak passwords
weak_patterns=(
"password=password"
"password=admin"
"password=12345"
"password=test"
)
for pattern in "${weak_patterns[@]}"; do
if grep -iq "$pattern" .env.example; then
echo "⚠ Warning: Found weak default password pattern"
issues=$((issues + 1))
break
fi
done
# Check for empty password fields
if grep -E "PASSWORD=\s*$" .env.example; then
echo "⚠ Warning: Found empty password fields"
issues=$((issues + 1))
fi
# Verify security-related settings
if ! grep -q "VAULT_" .env.example; then
echo "ℹ Info: No Vault configuration found"
fi
if [ $issues -eq 0 ]; then
echo "✓ No critical security issues found in .env.example"
else
echo ""
echo "Found $issues security issue(s) in .env.example"
fi
- name: Ensure .env is gitignored
run: |
if [ -f .gitignore ]; then
if grep -q "^\.env$" .gitignore; then
echo "✓ .env is properly gitignored"
else
echo "⚠ Warning: .env should be added to .gitignore"
exit 1
fi
else
echo "⚠ Warning: No .gitignore file found"
exit 1
fi
script-security:
name: Shell Script Security
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check for common shell script vulnerabilities
run: |
echo "Checking shell scripts for security issues..."
scripts=$(find . -name "*.sh" -type f)
for script in $scripts; do
echo "Checking $script..."
# Check for unquoted variables
if grep -E '\$[A-Za-z_][A-Za-z0-9_]*[^"\x27]' "$script" | grep -v "^\s*#"; then
echo " ℹ Info: Consider quoting variables to prevent word splitting"
fi
# Check for use of eval
if grep -q "eval " "$script"; then
echo " ⚠ Warning: Found 'eval' - potential code injection risk"
fi
# Check for curl/wget without verification
if grep -E "(curl|wget).*-k|--insecure" "$script"; then
echo " ⚠ Warning: Found insecure curl/wget usage"
fi
# Check for use of /tmp without mktemp
if grep -q "/tmp/[a-zA-Z]" "$script"; then
echo " ℹ Info: Consider using mktemp for temporary files"
fi
done
echo "✓ Script security check completed"
codeql-analysis-python:
name: CodeQL Analysis (Python)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies for CodeQL analysis
run: |
# Install dependencies from all requirements.txt files
# This helps CodeQL understand imports and dependencies
echo "Installing dependencies from reference apps..."
if [ -f "reference-apps/fastapi/requirements.txt" ]; then
pip install -r reference-apps/fastapi/requirements.txt || true
fi
if [ -f "reference-apps/fastapi-api-first/requirements.txt" ]; then
pip install -r reference-apps/fastapi-api-first/requirements.txt || true
fi
if [ -f "tests/requirements.txt" ]; then
pip install -r tests/requirements.txt || true
fi
if [ -f "reference-apps/shared/test-suite/requirements.txt" ]; then
pip install -r reference-apps/shared/test-suite/requirements.txt || true
fi
echo "✓ Dependencies installed for CodeQL analysis"
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: 'python'
queries: security-and-quality
setup-python-dependencies: false
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:python"
codeql-analysis-go:
name: CodeQL Analysis (Go)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'reference-apps/golang/go.mod'
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: 'go'
queries: security-and-quality
- name: Build Go application
run: |
echo "Building Go application for CodeQL analysis..."
cd reference-apps/golang
go build -v ./...
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:go"
security-summary:
name: Security Summary
runs-on: ubuntu-latest
needs:
- secret-scan
- dependency-scan
- trivy-scan
- docker-compose-security
- env-security
- script-security
- codeql-analysis-python
- codeql-analysis-go
if: always()
steps:
- name: Check security scan results
run: |
failed=0
if [ "${{ needs.secret-scan.result }}" == "failure" ]; then
echo "❌ Secret scanning failed - potential secrets detected"
failed=1
fi
if [ "${{ needs.env-security.result }}" == "failure" ]; then
echo "❌ Environment security check failed"
failed=1
fi
if [ "${{ needs.trivy-scan.result }}" == "failure" ]; then
echo "⚠ Warning: Trivy scan found vulnerabilities"
fi
if [ $failed -eq 1 ]; then
echo ""
echo "Critical security issues detected. Please review and fix before merging."
exit 1
fi
echo "✅ Security scans completed"
echo ""
echo "Please review any warnings in the individual job outputs."