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>
218 lines
7.7 KiB
Bash
Executable File
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
|