feat: Enhance security and validation in backend

- Added helmet for security headers and configured content security policy
- Implemented CORS with a whitelist for allowed origins
- Introduced express-validator for input validation in API endpoints
- Set request size limits to prevent DoS attacks
- Added global error handling and 404 response
- Updated TypeScript configuration to use node16 module resolution
- Improved Docker Compose configuration for security and resource limits
- Created a comprehensive .env.example for environment configuration
- Implemented automated security scans in CI/CD with Trivy
- Added cleanup script for debugging ports
- Established a detailed security policy document
This commit is contained in:
2025-12-01 08:37:35 +01:00
parent b13e7d1228
commit 4a6b4a0ae8
20 changed files with 1296 additions and 764 deletions

View File

@@ -0,0 +1,301 @@
name: 🚀 Docker Image Build & Security Scan
on:
push:
branches:
- main
- beta
- alpha
- Nachweise
workflow_dispatch: # Manueller Trigger
schedule:
# Täglicher Security-Scan um 6:00 UTC
- cron: '0 6 * * *'
env:
# ⚠️ ANPASSEN: Nur die Registry-URL anpassen
REGISTRY: git.csnetworkx.dev
# Image-Name wird automatisch aus Repository generiert: REGISTRY/owner/repo
# Beispiel: git.csnetworkx.dev/user/project
TRIVY_VERSION: 0.58.1
jobs:
# 🔍 Security-Scan des Quellcodes und der Abhängigkeiten
security-scan:
name: 🔍 Sicherheitsüberprüfung
runs-on: ubuntu-latest
steps:
- name: 📥 Repository auschecken
uses: actions/checkout@v4
- name: 🔧 Trivy installieren
run: |
echo "📦 Installiere Trivy Security Scanner..."
# Moderne Installation ohne deprecated apt-key
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy-archive-keyring.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install -y trivy
trivy --version
- name: 🔍 Quellcode & Abhängigkeiten scannen
run: |
echo "🔍 Scanne Quellcode und npm-Abhängigkeiten..."
trivy fs --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed .
- name: 🔍 Dockerfile & Konfiguration scannen
run: |
echo "🔍 Scanne Dockerfile und IaC-Konfigurationen..."
# Erzwinge auch kleingeschriebene Dockerfiles (z.B. ./dockerfile)
trivy config --severity CRITICAL,HIGH --exit-code 1 \
--file-patterns "dockerfile:.*[Dd]ockerfile.*" .
# 🔄 Täglicher Scan und automatische Fixes (nur bei scheduled runs)
daily-security-scan:
name: 🔄 Täglicher Security-Scan & Auto-Fix
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
steps:
- name: 📥 Repository auschecken (main Branch)
uses: actions/checkout@v4
with:
ref: main
- name: 🏷️ Image-Namen generieren
id: image_name
run: |
# Generiere Image-Name: REGISTRY/repository-lowercase
# Gitea: nutze GITHUB_REPOSITORY oder GITEA_REPOSITORY
REPO="${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}"
IMAGE="${{ env.REGISTRY }}/${REPO}"
IMAGE_LOWER=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]')
echo "image=${IMAGE_LOWER}" >> "$GITHUB_OUTPUT"
echo "✅ Image-Name: ${IMAGE_LOWER}"
echo "📦 Repository: ${REPO}"
- name: 🟢 Node.js einrichten
uses: actions/setup-node@v4
with:
node-version: '20'
- name: 🔧 Trivy installieren
run: |
echo "📦 Installiere Trivy Security Scanner..."
# Moderne Installation ohne deprecated apt-key
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy-archive-keyring.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install -y trivy
trivy --version
- name: 🔐 In Docker Registry einloggen
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 🔍 Docker Image scannen (latest)
id: image_scan
continue-on-error: true
run: |
echo "🐳 Scanne Docker Image: ${{ steps.image_name.outputs.image }}:latest"
trivy image --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed ${{ steps.image_name.outputs.image }}:latest || echo "scan_failed=true" >> "$GITHUB_OUTPUT"
- name: 🔍 Dateisystem scannen
id: fs_scan
continue-on-error: true
run: |
echo "📁 Scanne Dateisystem und Abhängigkeiten..."
trivy fs --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed . || echo "scan_failed=true" >> "$GITHUB_OUTPUT"
- name: 🔧 npm audit fix ausführen (Frontend)
if: steps.fs_scan.outcome == 'failure'
working-directory: ./frontend
run: |
echo "🔧 Führe npm audit fix aus (Frontend)..."
npm audit fix --force || true
npm update || true
- name: 🔧 npm audit fix ausführen (Backend)
if: steps.fs_scan.outcome == 'failure'
working-directory: ./backend
run: |
echo "🔧 Führe npm audit fix aus (Backend)..."
npm audit fix --force || true
npm update || true
- name: 🔎 Änderungen prüfen
id: changes
run: |
if git diff --quiet; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
echo "✅ Keine Änderungen durch npm audit fix"
else
echo "has_changes=true" >> "$GITHUB_OUTPUT"
echo "📝 Änderungen wurden vorgenommen"
fi
- name: 💾 Änderungen committen & pushen
if: steps.changes.outputs.has_changes == 'true'
run: |
echo "💾 Committe automatische Security-Fixes..."
git config user.name "Security Bot"
git config user.email "security-bot@csnetworkx.dev"
git add -A
git commit -m "🔒 Security: Automatische Dependency-Updates [skip ci]
- npm audit fix ausgeführt
- Schwachstellen in Abhängigkeiten behoben
🤖 Automatisch generiert durch den täglichen Security-Scan
Der Build wird beim nächsten manuellen Push ausgeführt."
git push
- name: 🔨 Docker Buildx einrichten
if: steps.image_scan.outcome == 'failure' || steps.changes.outputs.has_changes == 'true'
uses: docker/setup-buildx-action@v3
- name: 🏗️ Docker Image neu bauen & pushen
if: steps.image_scan.outcome == 'failure' || steps.changes.outputs.has_changes == 'true'
uses: docker/build-push-action@v5
with:
context: .
push: true
pull: true # Zieht immer das neueste Base-Image
build-args: |
VERSION_TAG=latest
VERSION_SHA=${{ github.sha }}
tags: ${{ steps.image_name.outputs.image }}:latest
- name: 📊 Security-Report erstellen
if: always()
run: |
echo "╔════════════════════════════════════════╗"
echo "║ 🔒 SECURITY SCAN REPORT 🔒 ║"
echo "╚════════════════════════════════════════╝"
echo ""
echo "📋 Scan-Ergebnisse:"
echo " • Docker Image: ${{ steps.image_scan.outcome }}"
echo " • Dateisystem: ${{ steps.fs_scan.outcome }}"
echo " • Änderungen: ${{ steps.changes.outputs.has_changes }}"
echo ""
if [[ "${{ steps.image_scan.outcome }}" == "failure" ]] || [[ "${{ steps.fs_scan.outcome }}" == "failure" ]]; then
echo "⚠️ SCHWACHSTELLEN GEFUNDEN!"
if [[ "${{ steps.changes.outputs.has_changes }}" == "true" ]]; then
echo "✅ Automatische Fixes wurden angewendet und committed."
else
echo "❌ Keine automatischen Fixes möglich - manuelle Überprüfung erforderlich!"
fi
else
echo "✅ Keine kritischen Schwachstellen gefunden."
fi
echo ""
# 🐳 Docker Image bauen und pushen
docker-build-and-push:
name: 🐳 Docker Image Build & Push
runs-on: ubuntu-latest
needs: security-scan
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.security-scan.result == 'success'
steps:
- name: 📥 Repository auschecken
uses: actions/checkout@v4
- name: 🏷️ Image-Namen & Tags berechnen
id: vars
shell: bash
run: |
# Generiere Image-Name aus Repository (lowercase)
# Gitea: nutze GITHUB_REPOSITORY oder GITEA_REPOSITORY
REPO="${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}"
IMAGE="${{ env.REGISTRY }}/${REPO}"
IMAGE_LOWER=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]')
echo "image_name=${IMAGE_LOWER}" >> "$GITHUB_OUTPUT"
echo "✅ Image-Name: ${IMAGE_LOWER}"
echo "📦 Repository: ${REPO}"
# Berechne Branch-Tag (Gitea kompatibel)
BRANCH="${GITHUB_REF_NAME:-$GITEA_REF_NAME}"
echo "🏷️ Berechne Image-Tags für Branch: ${BRANCH}"
case "${BRANCH}" in
main) echo "branch_tag=latest" >> "$GITHUB_OUTPUT" ;;
beta) echo "branch_tag=beta" >> "$GITHUB_OUTPUT" ;;
alpha) echo "branch_tag=alpha" >> "$GITHUB_OUTPUT" ;;
Nachweise) echo "branch_tag=Nachweise" >> "$GITHUB_OUTPUT" ;;
*) echo "branch_tag=${BRANCH}" >> "$GITHUB_OUTPUT" ;;
esac
# SHA (Gitea kompatibel)
SHA="${GITHUB_SHA:-$GITEA_SHA}"
echo "short_sha=${SHA::8}" >> "$GITHUB_OUTPUT"
echo "✅ Branch-Tag: $(cat $GITHUB_OUTPUT | grep branch_tag | cut -d'=' -f2)"
echo "✅ SHA-Tag: ${SHA::8}"
- name: 🖥️ QEMU einrichten (Multi-Arch Support)
uses: docker/setup-qemu-action@v3
- name: 🔨 Docker Buildx einrichten
uses: docker/setup-buildx-action@v3
- name: 🔌 Registry-Verbindung testen
run: |
echo "🔌 Teste Verbindung zur Registry: ${{ env.REGISTRY }}"
echo ""
echo "1⃣ HTTP-Verbindungstest..."
curl -v --connect-timeout 10 https://${{ env.REGISTRY }}/v2/ || echo "⚠️ Curl fehlgeschlagen"
echo ""
echo "2⃣ DNS-Auflösung..."
nslookup ${{ env.REGISTRY }} || echo "⚠️ DNS-Lookup fehlgeschlagen"
echo ""
echo "3⃣ Netzwerk-Ping..."
ping -c 3 ${{ env.REGISTRY }} || echo "⚠️ Ping fehlgeschlagen"
- name: 🔐 Manueller Login-Test
run: |
echo "🔐 Teste manuellen Docker-Login..."
echo ${{ secrets.DOCKER_PASSWORD }} | docker login --username ${{ secrets.DOCKER_USERNAME }} --password-stdin ${{ env.REGISTRY }}
echo "✅ Login erfolgreich!"
- name: 🔐 In Docker Registry einloggen
uses: docker/login-action@v3
env:
DOCKER_CLI_DEBUG: 1
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 🏗️ Docker Image bauen & pushen
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
build-args: |
VERSION_TAG=${{ steps.vars.outputs.branch_tag }}
VERSION_SHA=${{ steps.vars.outputs.short_sha }}
tags: |
${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.branch_tag }}
${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.short_sha }}
- name: ✅ Build-Zusammenfassung
if: success()
run: |
echo "╔════════════════════════════════════════╗"
echo "║ ✅ BUILD ERFOLGREICH ✅ ║"
echo "╚════════════════════════════════════════╝"
echo ""
echo "📦 Gebaute Images:"
echo " • ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.branch_tag }}"
echo " • ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.short_sha }}"
echo ""
echo "🎯 Plattformen: linux/amd64, linux/arm64"
echo "📤 Erfolgreich in Registry gepusht!"
echo ""
echo "🏷️ Image-Name: ${{ steps.vars.outputs.image_name }}"
echo "📍 Registry: ${{ env.REGISTRY }}"
echo "🔗 Repository: ${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}"
echo ""