# Woodpecker CI Security Pipeline # Dedizierte Security-Scans fuer DevSecOps # # Laeuft taeglich via Cron und bei jedem PR when: - event: cron cron: "0 3 * * *" # Taeglich um 3:00 Uhr - event: pull_request clone: git: image: woodpeckerci/plugin-git settings: depth: 1 extra_hosts: - macmini:192.168.178.100 steps: # ======================================== # Static Analysis # ======================================== semgrep-scan: image: returntocorp/semgrep:latest commands: - semgrep scan --config auto --json -o semgrep-results.json . || true - | if [ -f semgrep-results.json ]; then echo "=== Semgrep Findings ===" cat semgrep-results.json | head -100 fi when: event: [pull_request, cron] bandit-python: image: python:3.12-slim commands: - pip install --quiet bandit - bandit -r backend/ -f json -o bandit-results.json || true - | if [ -f bandit-results.json ]; then echo "=== Bandit Findings ===" cat bandit-results.json | head -50 fi when: event: [pull_request, cron] gosec-go: image: securego/gosec:latest commands: - gosec -fmt json -out gosec-consent.json ./consent-service/... || true - gosec -fmt json -out gosec-billing.json ./billing-service/... || true - echo "Go Security Scan abgeschlossen" when: event: [pull_request, cron] # ======================================== # Secrets Detection # ======================================== gitleaks-scan: image: zricethezav/gitleaks:latest commands: - gitleaks detect --source . --report-format json --report-path gitleaks-report.json || true - | if [ -s gitleaks-report.json ]; then echo "=== WARNUNG: Potentielle Secrets gefunden ===" cat gitleaks-report.json else echo "Keine Secrets gefunden" fi trufflehog-scan: image: trufflesecurity/trufflehog:latest commands: - trufflehog filesystem . --json > trufflehog-results.json 2>&1 || true - echo "TruffleHog Scan abgeschlossen" # ======================================== # Dependency Vulnerabilities # ======================================== npm-audit: image: node:20-alpine commands: - cd website && npm audit --json > ../npm-audit-website.json || true - cd ../studio-v2 && npm audit --json > ../npm-audit-studio.json || true - cd ../admin-v2 && npm audit --json > ../npm-audit-admin.json || true - echo "NPM Audit abgeschlossen" when: event: [pull_request, cron] pip-audit: image: python:3.12-slim commands: - pip install --quiet pip-audit - pip-audit -r backend/requirements.txt --format json -o pip-audit-backend.json || true - pip-audit -r voice-service/requirements.txt --format json -o pip-audit-voice.json || true - echo "Pip Audit abgeschlossen" when: event: [pull_request, cron] go-vulncheck: image: golang:1.21-alpine commands: - go install golang.org/x/vuln/cmd/govulncheck@latest - cd consent-service && govulncheck ./... || true - cd ../billing-service && govulncheck ./... || true - echo "Go Vulncheck abgeschlossen" when: event: [pull_request, cron] # ======================================== # Container Security # ======================================== trivy-filesystem: image: aquasec/trivy:latest commands: - trivy fs --severity HIGH,CRITICAL --format json -o trivy-fs.json . || true - echo "Trivy Filesystem Scan abgeschlossen" when: event: cron # ======================================== # SBOM Generation (taeglich) # ======================================== daily-sbom: image: anchore/syft:latest commands: - mkdir -p sbom-reports - syft dir:. -o cyclonedx-json > sbom-reports/sbom-full-$(date +%Y%m%d).json - echo "SBOM generiert" when: event: cron # ======================================== # AUTO-FIX: Dependency Vulnerabilities # Laeuft nur bei Cron (nightly), nicht bei PRs # ======================================== auto-fix-npm: image: node:20-alpine commands: - apk add --no-cache git - | echo "=== Auto-Fix: NPM Dependencies ===" FIXES_APPLIED=0 for dir in website studio-v2 admin-v2 h5p-service; do if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then echo "Pruefe $dir..." cd $dir # Speichere Hash vor Fix BEFORE=$(md5sum package-lock.json 2>/dev/null || echo "none") # npm audit fix (ohne --force fuer sichere Updates) npm audit fix --package-lock-only 2>/dev/null || true # Pruefe ob Aenderungen AFTER=$(md5sum package-lock.json 2>/dev/null || echo "none") if [ "$BEFORE" != "$AFTER" ]; then echo " -> Fixes angewendet in $dir" FIXES_APPLIED=$((FIXES_APPLIED + 1)) fi cd .. fi done echo "NPM Auto-Fix abgeschlossen: $FIXES_APPLIED Projekte aktualisiert" echo "NPM_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env when: event: cron auto-fix-python: image: python:3.12-slim commands: - apt-get update && apt-get install -y git - pip install --quiet pip-audit - | echo "=== Auto-Fix: Python Dependencies ===" FIXES_APPLIED=0 for reqfile in backend/requirements.txt voice-service/requirements.txt klausur-service/backend/requirements.txt; do if [ -f "$reqfile" ]; then echo "Pruefe $reqfile..." DIR=$(dirname $reqfile) # pip-audit mit --fix (aktualisiert requirements.txt) pip-audit -r $reqfile --fix 2>/dev/null || true # Pruefe ob requirements.txt geaendert wurde if git diff --quiet $reqfile 2>/dev/null; then echo " -> Keine Aenderungen in $reqfile" else echo " -> Fixes angewendet in $reqfile" FIXES_APPLIED=$((FIXES_APPLIED + 1)) fi fi done echo "Python Auto-Fix abgeschlossen: $FIXES_APPLIED Dateien aktualisiert" echo "PYTHON_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env when: event: cron auto-fix-go: image: golang:1.21-alpine commands: - apk add --no-cache git - | echo "=== Auto-Fix: Go Dependencies ===" FIXES_APPLIED=0 for dir in consent-service billing-service school-service edu-search ai-compliance-sdk; do if [ -d "$dir" ] && [ -f "$dir/go.mod" ]; then echo "Pruefe $dir..." cd $dir # Go mod tidy und update go get -u ./... 2>/dev/null || true go mod tidy 2>/dev/null || true # Pruefe ob go.mod/go.sum geaendert wurden if git diff --quiet go.mod go.sum 2>/dev/null; then echo " -> Keine Aenderungen in $dir" else echo " -> Updates angewendet in $dir" FIXES_APPLIED=$((FIXES_APPLIED + 1)) fi cd .. fi done echo "Go Auto-Fix abgeschlossen: $FIXES_APPLIED Module aktualisiert" echo "GO_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env when: event: cron # ======================================== # Commit & Push Auto-Fixes # ======================================== commit-security-fixes: image: alpine/git:latest commands: - | echo "=== Commit Security Fixes ===" # Git konfigurieren git config --global user.email "security-bot@breakpilot.de" git config --global user.name "Security Bot" git config --global --add safe.directory /woodpecker/src # Pruefe ob es Aenderungen gibt if git diff --quiet && git diff --cached --quiet; then echo "Keine Security-Fixes zum Committen" exit 0 fi # Zeige was geaendert wurde echo "Geaenderte Dateien:" git status --short # Stage alle relevanten Dateien git add -A \ */package-lock.json \ */requirements.txt \ */go.mod \ */go.sum \ 2>/dev/null || true # Commit erstellen TIMESTAMP=$(date +%Y-%m-%d) git commit -m "fix(security): auto-fix vulnerable dependencies [$TIMESTAMP] Automatische Sicherheitsupdates durch CI/CD Pipeline: - npm audit fix fuer Node.js Projekte - pip-audit --fix fuer Python Projekte - go get -u fuer Go Module Co-Authored-By: Security Bot " || echo "Nichts zu committen" # Push zum Repository git push origin HEAD:main || echo "Push fehlgeschlagen - manueller Review erforderlich" echo "Security-Fixes committed und gepusht" when: event: cron status: success # ======================================== # Report to Dashboard # ======================================== update-security-dashboard: image: curlimages/curl:latest commands: - | curl -X POST "http://backend:8000/api/security/scan-results" \ -H "Content-Type: application/json" \ -d "{ \"scan_type\": \"daily\", \"timestamp\": \"$(date -Iseconds)\", \"tools\": [\"semgrep\", \"bandit\", \"gosec\", \"gitleaks\", \"trivy\"] }" || true when: status: [success, failure] event: cron