This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/scripts/security-scan.sh
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

218 lines
7.7 KiB
Bash
Executable File

#!/bin/bash
# BreakPilot DevSecOps Security Scanning Script
#
# Usage: ./scripts/security-scan.sh [options]
# --all Run all scans
# --secrets Run secrets detection (Gitleaks)
# --sast Run static analysis (Semgrep, Bandit)
# --sca Run dependency scanning (Trivy, Grype)
# --sbom Generate SBOM (Syft)
# --image Scan Docker images (Trivy)
# --ci CI mode (exit on critical findings)
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default values
RUN_ALL=false
RUN_SECRETS=false
RUN_SAST=false
RUN_SCA=false
RUN_SBOM=false
RUN_IMAGE=false
CI_MODE=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--all) RUN_ALL=true; shift ;;
--secrets) RUN_SECRETS=true; shift ;;
--sast) RUN_SAST=true; shift ;;
--sca) RUN_SCA=true; shift ;;
--sbom) RUN_SBOM=true; shift ;;
--image) RUN_IMAGE=true; shift ;;
--ci) CI_MODE=true; shift ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
# If no specific option, run all
if ! $RUN_SECRETS && ! $RUN_SAST && ! $RUN_SCA && ! $RUN_SBOM && ! $RUN_IMAGE; then
RUN_ALL=true
fi
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ BreakPilot DevSecOps Security Scanner ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
SCAN_RESULTS_DIR="$PROJECT_DIR/security-reports"
mkdir -p "$SCAN_RESULTS_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
CRITICAL_FOUND=false
# =============================================
# 1. Secrets Detection (Gitleaks)
# =============================================
run_secrets_scan() {
echo -e "\n${YELLOW}[1/5] Secrets Detection (Gitleaks)${NC}"
if command -v gitleaks &> /dev/null; then
echo "Running Gitleaks..."
if gitleaks detect --source . --config .gitleaks.toml --report-path "$SCAN_RESULTS_DIR/gitleaks-${TIMESTAMP}.json" --report-format json 2>&1; then
echo -e "${GREEN}✓ No secrets found${NC}"
else
echo -e "${RED}✗ Secrets detected! Check $SCAN_RESULTS_DIR/gitleaks-${TIMESTAMP}.json${NC}"
CRITICAL_FOUND=true
fi
else
echo -e "${YELLOW}⚠ Gitleaks not installed. Install: brew install gitleaks${NC}"
fi
}
# =============================================
# 2. Static Analysis (Semgrep + Bandit)
# =============================================
run_sast_scan() {
echo -e "\n${YELLOW}[2/5] Static Analysis (SAST)${NC}"
# Semgrep
if command -v semgrep &> /dev/null; then
echo "Running Semgrep..."
semgrep scan --config auto --config .semgrep.yml \
--json --output "$SCAN_RESULTS_DIR/semgrep-${TIMESTAMP}.json" \
--severity ERROR || true
echo -e "${GREEN}✓ Semgrep scan complete${NC}"
else
echo -e "${YELLOW}⚠ Semgrep not installed. Install: pip install semgrep${NC}"
fi
# Bandit (Python)
if command -v bandit &> /dev/null; then
echo "Running Bandit..."
bandit -r backend/ -ll -x backend/tests/* \
-f json -o "$SCAN_RESULTS_DIR/bandit-${TIMESTAMP}.json" 2>/dev/null || true
echo -e "${GREEN}✓ Bandit scan complete${NC}"
else
echo -e "${YELLOW}⚠ Bandit not installed. Install: pip install bandit${NC}"
fi
}
# =============================================
# 3. Dependency Scanning (Trivy + Grype)
# =============================================
run_sca_scan() {
echo -e "\n${YELLOW}[3/5] Dependency Scanning (SCA)${NC}"
# Trivy filesystem scan
if command -v trivy &> /dev/null; then
echo "Running Trivy filesystem scan..."
trivy fs . --config .trivy.yaml \
--format json --output "$SCAN_RESULTS_DIR/trivy-fs-${TIMESTAMP}.json" \
--severity HIGH,CRITICAL || true
echo -e "${GREEN}✓ Trivy filesystem scan complete${NC}"
else
echo -e "${YELLOW}⚠ Trivy not installed. Install: brew install trivy${NC}"
fi
# Grype
if command -v grype &> /dev/null; then
echo "Running Grype..."
grype dir:. -o json > "$SCAN_RESULTS_DIR/grype-${TIMESTAMP}.json" 2>/dev/null || true
echo -e "${GREEN}✓ Grype scan complete${NC}"
else
echo -e "${YELLOW}⚠ Grype not installed. Install: brew install grype${NC}"
fi
}
# =============================================
# 4. SBOM Generation (Syft)
# =============================================
run_sbom_generation() {
echo -e "\n${YELLOW}[4/5] SBOM Generation (Syft)${NC}"
if command -v syft &> /dev/null; then
echo "Generating SBOM..."
syft dir:. -o cyclonedx-json="$SCAN_RESULTS_DIR/sbom-${TIMESTAMP}.json" 2>/dev/null || true
syft dir:. -o spdx-json="$SCAN_RESULTS_DIR/sbom-spdx-${TIMESTAMP}.json" 2>/dev/null || true
echo -e "${GREEN}✓ SBOM generated (CycloneDX + SPDX)${NC}"
else
echo -e "${YELLOW}⚠ Syft not installed. Install: brew install syft${NC}"
fi
}
# =============================================
# 5. Container Image Scanning (Trivy)
# =============================================
run_image_scan() {
echo -e "\n${YELLOW}[5/5] Container Image Scanning${NC}"
if command -v trivy &> /dev/null; then
# Scan each built image
for IMAGE in breakpilot-pwa-backend breakpilot-pwa-consent-service breakpilot-pwa-school-service; do
if docker image inspect "$IMAGE" &> /dev/null; then
echo "Scanning $IMAGE..."
trivy image "$IMAGE" \
--format json --output "$SCAN_RESULTS_DIR/trivy-image-${IMAGE}-${TIMESTAMP}.json" \
--severity HIGH,CRITICAL || true
else
echo -e "${YELLOW}⚠ Image $IMAGE not found, skipping${NC}"
fi
done
echo -e "${GREEN}✓ Container image scans complete${NC}"
else
echo -e "${YELLOW}⚠ Trivy not installed. Install: brew install trivy${NC}"
fi
}
# =============================================
# Run selected scans
# =============================================
if $RUN_ALL || $RUN_SECRETS; then
run_secrets_scan
fi
if $RUN_ALL || $RUN_SAST; then
run_sast_scan
fi
if $RUN_ALL || $RUN_SCA; then
run_sca_scan
fi
if $RUN_ALL || $RUN_SBOM; then
run_sbom_generation
fi
if $RUN_ALL || $RUN_IMAGE; then
run_image_scan
fi
# =============================================
# Summary
# =============================================
echo -e "\n${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Scan Summary ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
echo -e "Reports saved to: ${GREEN}$SCAN_RESULTS_DIR${NC}"
ls -la "$SCAN_RESULTS_DIR"/*-${TIMESTAMP}.* 2>/dev/null || echo "No reports generated"
if $CRITICAL_FOUND && $CI_MODE; then
echo -e "\n${RED}✗ Critical security findings detected. CI pipeline should fail.${NC}"
exit 1
else
echo -e "\n${GREEN}✓ Security scan completed${NC}"
exit 0
fi