# Audyt bezpieczeństwa Supabase Edge Functions

Jesteś Senior DevOps Security Auditorem. Twoim zadaniem jest sprawdzenie, czy
Supabase Edge Functions zostały prawidłowo wdrożone zgodnie z runbookiem (artykuł 3).

Wykonaj poniższe kontrole po kolei. Korzystaj z dostępnych narzędzi.
Dla każdej kontroli: zgłoś ZALICZONY, OSTRZEŻENIE lub KRYTYCZNY z krótkim uzasadnieniem.
Na końcu sporządź podsumowanie z rekomendacjami działań.

---

## A1: Edge Functions wyłącznie do integracji

Sprawdź, czy Edge Functions są wykorzystywane jako punkty integracyjne, a nie jako drugi backend.

```bash
# Alle Edge Functions auflisten
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

echo "=== Functions Verzeichnis: $FUNCTIONS_DIR ==="
ls -d ${FUNCTIONS_DIR}/*/ 2>/dev/null | grep -v "main\|_shared"

# Für jede Function prüfen: Webhook/Integration oder Business-Logik?
echo "=== Webhook/Integration Patterns ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  echo "--- $name ---"

  # Webhook-Patterns vorhanden?
  grep -l "signature\|webhook\|stripe\|github\|trigger\|event" "$dir"*.ts 2>/dev/null || true

  # Business-Logik Patterns (Warnung)?
  if grep -qE "getUser\|session\|createServerClient\|\.from\(.*\)\.select\(.*\)\.eq\(" "$dir/index.ts" 2>/dev/null; then
    echo "WARNUNG: Enthält möglicherweise Business-Logik (User-Kontext, komplexe Queries)"
  fi

  # CRUD-Patterns (Warnung)?
  if grep -qE "\.insert\(|\.update\(|\.delete\(" "$dir/index.ts" 2>/dev/null; then
    COUNT=$(grep -cE "\.insert\(|\.update\(|\.delete\(" "$dir/index.ts" 2>/dev/null || echo 0)
    if [ "$COUNT" -gt 2 ]; then
      echo "WARNUNG: $COUNT DB-Mutationen. Möglicherweise Business-Logik statt Integration."
    fi
  fi
done
```

Oczekiwanie: Functions są webhookami, handlerami zdarzeń lub integracjami API. Złożona logika biznesowa (CRUD, sesja użytkownika, Ownership) należy do Next.js.
Ryzyko: Podwójna logika w Edge Functions i Next.js prowadzi do niespójnej walidacji i trudnych do debugowania błędów.

---

## A2: Endpointy webhookowe izolowane

Sprawdź, czy każdy dostawca webhooka ma własną Function.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

echo "=== Webhook Functions ==="
ls -d ${FUNCTIONS_DIR}/*webhook*/ 2>/dev/null || echo "Keine Webhook-Functions gefunden"

# Prüfe ob eine Function mehrere Provider bedient
for dir in ${FUNCTIONS_DIR}/*-webhook/; do
  [ -d "$dir" ] || continue
  name=$(basename "$dir")
  providers=$(grep -ciE "stripe|github|trigger|slack|sendgrid|twilio" "$dir/index.ts" 2>/dev/null || echo 0)
  if [ "$providers" -gt 1 ]; then
    echo "WARNUNG: $name referenziert mehrere Provider ($providers)"
  else
    echo "OK: $name"
  fi
done
```

Oczekiwanie: Jeden dostawca webhooków na Function (stripe-webhook, github-webhook, itd.).
Ryzyko: Współdzielone handlery błędów. Błędny payload Stripe blokuje webhook GitHuba.

---

## A3: CORS prawidłowo skonfigurowany

Sprawdź, czy CORS jest prawidłowo ustawiony na wszystkich Functions.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Shared CORS Config vorhanden?
echo "=== Shared CORS Config ==="
ls ${FUNCTIONS_DIR}/_shared/cors.ts 2>/dev/null || echo "WARNUNG: Keine shared cors.ts"

if [ -f "${FUNCTIONS_DIR}/_shared/cors.ts" ]; then
  cat "${FUNCTIONS_DIR}/_shared/cors.ts"
fi

# Wildcard CORS in Produktion?
echo "=== Wildcard CORS ==="
grep -rn "'\\*'" ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | grep -i "origin" || \
  echo "Kein Wildcard-Origin gefunden (gut)"

# Alle Functions haben OPTIONS Handler?
echo "=== OPTIONS Handler ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  if ! grep -q "OPTIONS" "$dir/index.ts" 2>/dev/null; then
    echo "WARNUNG: $name hat keinen OPTIONS Handler"
  else
    echo "OK: $name"
  fi
done

# CORS Headers in ALLEN Responses (auch Error)?
echo "=== CORS in Error Responses ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  ERROR_RESPONSES=$(grep -c "new Response" "$dir/index.ts" 2>/dev/null || echo 0)
  CORS_RESPONSES=$(grep -c "corsHeaders\|getCorsHeaders" "$dir/index.ts" 2>/dev/null || echo 0)
  if [ "$ERROR_RESPONSES" -gt "$CORS_RESPONSES" ] && [ "$ERROR_RESPONSES" -gt 0 ]; then
    echo "WARNUNG: $name hat $ERROR_RESPONSES Responses aber nur $CORS_RESPONSES mit CORS Headers"
  fi
done
```

Oczekiwanie:
- Współdzielony cors.ts istnieje w _shared/
- Brak Wildcard-Origin (`'*'`) w produkcji
- Wszystkie Functions mają handler OPTIONS dla preflight
- Nagłówki CORS we wszystkich odpowiedziach (także odpowiedziach błędów)

Ryzyko: Bez CORS requesty przeglądarki kończą się niepowodzeniem. Z Wildcard każda strona może wysyłać requesty.

---

## B1: Sygnatury webhooków weryfikowane

Sprawdź, czy wszystkie Functions webhookowe weryfikują sygnatury.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

echo "=== Signaturprüfung ==="
for dir in ${FUNCTIONS_DIR}/*-webhook/ ${FUNCTIONS_DIR}/*webhook*/; do
  [ -d "$dir" ] || continue
  name=$(basename "$dir")

  if grep -qE "signature|verify|hmac|crypto\.subtle" "$dir/index.ts" 2>/dev/null; then
    echo "OK: $name prüft Signaturen"

    # Timing-Check vorhanden (Replay-Schutz)?
    if grep -qE "timestamp|Date\.now\|time" "$dir/index.ts" 2>/dev/null; then
      echo "  + Timing/Replay-Schutz vorhanden"
    else
      echo "  - WARNUNG: Kein Timing-Check für Replay-Schutz"
    fi
  else
    echo "KRITISCH: $name hat KEINE Signaturprüfung"
  fi
done

# Auch Non-Webhook Functions die POST akzeptieren
echo "=== Non-Webhook Functions mit POST ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" || "$name" == *"webhook"* ]] && continue
  if grep -q "POST" "$dir/index.ts" 2>/dev/null; then
    echo "INFO: $name akzeptiert POST. Auth-Mechanismus prüfen:"
    grep -n "auth\|token\|Bearer\|jwt\|verify" "$dir/index.ts" 2>/dev/null | head -3 || \
      echo "  WARNUNG: Kein Auth-Mechanismus erkennbar"
  fi
done
```

Oczekiwanie: Wszystkie Functions webhookowe weryfikują sygnatury dostawców (Stripe: stripe-signature + HMAC, GitHub: X-Hub-Signature-256).
Ryzyko: Bez weryfikacji sygnatur każdy może wysyłać sfałszowane zdarzenia (np. fałszywe potwierdzenie płatności).

---

## B2: Klient Supabase prawidłowy (anon vs. service_role)

Sprawdź, czy klient Supabase w Edge Functions jest prawidłowo inicjalizowany.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Shared Client vorhanden?
echo "=== Shared Supabase Client ==="
ls ${FUNCTIONS_DIR}/_shared/supabase*.ts 2>/dev/null || echo "Keine shared Client-Datei"

# Wo wird service_role verwendet?
echo "=== service_role Nutzung ==="
grep -rn "SERVICE_ROLE\|service_role" ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | \
  grep -v "_shared/"

# In welchen Functions wird der Admin/Service-Role Client erstellt?
echo "=== createClient mit service_role ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  if grep -qE "SERVICE_ROLE|createAdminClient|service_role" "$dir/index.ts" 2>/dev/null; then
    echo "$name: nutzt service_role"
    # Wird User-Input direkt in Queries verwendet?
    if grep -qE "payload\.\|body\.\|data\." "$dir/index.ts" 2>/dev/null; then
      if ! grep -qE "safeParse\|z\.\|validate\|schema" "$dir/index.ts" 2>/dev/null; then
        echo "  WARNUNG: Nutzt service_role UND verarbeitet Payload ohne erkennbare Validation"
      fi
    fi
  fi
done
```

Oczekiwanie:
- Współdzielona fabryka klientów w _shared/ (anon vs. admin oddzielnie)
- service_role tylko w Functions webhookowych/integracyjnych (brak kontekstu użytkownika)
- Jeśli service_role + dane wejściowe użytkownika: walidacja danych wejściowych musi istnieć

Ryzyko: service_role + niezwalidowane dane wejściowe = dowolne operacje na bazie bez RLS.

---

## B3: Walidacja danych wejściowych

Sprawdź, czy wszystkie Edge Functions walidują przychodzące dane.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

echo "=== Input Validation ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue

  if grep -qE "zod|safeParse|z\.object|z\.string|validate|schema" "$dir/index.ts" 2>/dev/null; then
    echo "OK: $name hat Schema Validation"
  elif grep -qE "JSON\.parse|req\.json\(\)" "$dir/index.ts" 2>/dev/null; then
    echo "WARNUNG: $name parsed JSON/Body ohne Schema Validation"
  else
    echo "INFO: $name verarbeitet möglicherweise keinen Body"
  fi
done

# Wird zod über npm: importiert (Deno-kompatibel)?
echo "=== Zod Import ==="
grep -rn "from.*zod\|import.*zod" ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | head -5
```

Oczekiwanie: Wszystkie Functions przetwarzające payloady mają walidację schematu (np. zod).
Ryzyko: Bez walidacji nieoczekiwane struktury danych mogą prowadzić do niezdefiniowanych operacji na bazie.

---

## B4: Sekrety nie w kodzie

Sprawdź, czy sekrety są prawidłowo ładowane przez zmienne środowiskowe.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Hardcoded Secrets
echo "=== Hardcoded Secrets ==="
grep -rn "sk_live\|sk_test\|whsec_\|ghsec_\|Bearer ey\|SG\.\|sk-proj\|sk-ant" \
  ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null || echo "Keine hardcoded Secrets gefunden (gut)"

# Secrets korrekt über Deno.env geladen?
echo "=== Deno.env.get Nutzung ==="
grep -rn "Deno.env.get" ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | head -10

# .env.functions Datei vorhanden und sicher?
echo "=== .env.functions ==="
ENV_FUNC=$(find /opt -name ".env.functions" 2>/dev/null | head -1)
if [ -n "$ENV_FUNC" ]; then
  stat -c "%a %U" "$ENV_FUNC"
  # Nicht im Git?
  cd $(dirname "$ENV_FUNC") && git ls-files .env.functions 2>/dev/null
else
  echo "Keine .env.functions gefunden (Secrets möglicherweise über docker-compose)"
fi
```

Oczekiwanie:
- Brak zakodowanych na stałe kluczy API, sekretów webhookowych ani tokenów w kodzie
- Sekrety ładowane przez Deno.env.get()
- .env.functions z uprawnieniami 600, nie w Git

Ryzyko: Zakodowane na stałe sekrety w repozytorium Git eksponowane przy każdym clone.

---

## B5: Timeouty i długo trwające operacje

Sprawdź, czy Edge Functions nie zawierają długo trwających operacji.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Langläufer-Patterns
echo "=== Langläufer-Patterns ==="
grep -rn "openai\|anthropic\|sharp\|ffmpeg\|puppeteer\|playwright\|pdf\|video\|transcode" \
  ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null || echo "Keine Langläufer-Patterns gefunden (gut)"

# Sleep/Timeout Patterns
echo "=== Sleep/Delay Patterns ==="
grep -rn "sleep\|setTimeout\|delay\|await new Promise" \
  ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | head -5

# Externe fetch-Calls ohne Timeout?
echo "=== Fetch ohne AbortSignal ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  FETCHES=$(grep -c "fetch(" "$dir/index.ts" 2>/dev/null || echo 0)
  TIMEOUTS=$(grep -c "AbortSignal\|signal\|timeout" "$dir/index.ts" 2>/dev/null || echo 0)
  if [ "$FETCHES" -gt 0 ] && [ "$TIMEOUTS" -eq 0 ]; then
    echo "WARNUNG: $name hat $FETCHES fetch-Calls ohne Timeout/AbortSignal"
  fi
done
```

Oczekiwanie:
- Brak wnioskowania AI, generowania PDF ani przetwarzania wideo w Edge Functions
- Zewnętrzne wywołania fetch mają timeouty (AbortSignal)
- Długo trwające operacje delegowane do Trigger.dev

Ryzyko: Długo trwające operacje blokują sloty workerów. Kolejne wywołania webhookowe kończą się timeoutem.

---

## B6: Obsługa błędów

Sprawdź, czy Edge Functions bezpiecznie obsługują błędy.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Try/Catch vorhanden?
echo "=== Try/Catch ==="
for dir in ${FUNCTIONS_DIR}/*/; do
  name=$(basename "$dir")
  [[ "$name" == "main" || "$name" == "_shared" ]] && continue
  if ! grep -q "try" "$dir/index.ts" 2>/dev/null; then
    echo "WARNUNG: $name hat kein try/catch"
  else
    echo "OK: $name"
  fi
done

# Error Details in Responses?
echo "=== Error Details an Client geleakt? ==="
grep -rn "error\.stack\|error\.message" ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null | \
  grep "Response" || echo "Keine Error-Detail-Leaks gefunden (gut)"

# Secrets in console.log?
echo "=== Secrets in Logs ==="
grep -rn "console\.log.*KEY\|console\.log.*SECRET\|console\.log.*token\|console\.log.*password" \
  ${FUNCTIONS_DIR}/ --include="*.ts" 2>/dev/null || echo "Keine Secret-Logs gefunden (gut)"
```

Oczekiwanie:
- Wszystkie Functions mają try/catch wokół logiki
- Brak error.stack ani error.message w odpowiedziach do klienta
- Brak sekretów w console.log

Ryzyko: Stack trace w odpowiedziach ujawniają wewnętrzne ścieżki i szczegóły bazy danych. Ułatwia celowane ataki.

---

## C1: Workflow wdrożenia

Sprawdź, czy Edge Functions są prawidłowo wdrożone.

```bash
FUNCTIONS_DIR=$(find /opt -path "*/volumes/functions" -type d 2>/dev/null | head -1)
FUNCTIONS_DIR=${FUNCTIONS_DIR:-"./supabase/functions"}

# Edge Runtime Container läuft?
echo "=== Edge Runtime Container ==="
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null | grep -i "function\|edge"

# Functions im Volume vorhanden?
echo "=== Functions im Volume ==="
ls -la ${FUNCTIONS_DIR}/ 2>/dev/null | head -20

# VERIFY_JWT Einstellung
echo "=== VERIFY_JWT ==="
grep "VERIFY_JWT" /opt/supabase/.env /opt/supabase/docker-compose.yml 2>/dev/null
```

Oczekiwanie:
- Kontener Edge Runtime działa
- Functions istnieją jako pliki w wolumenie
- VERIFY_JWT świadomie skonfigurowany (false dla webhooków, które nie wysyłają JWT)

---

## Podsumowanie

Sporządź teraz podsumowanie w następującym formacie:

```
# Audyt bezpieczeństwa Edge Functions - [DATA]

## Wynik

ZALICZONY:    X z Y kontroli
OSTRZEŻENIE:  X kontroli
KRYTYCZNY:    X kontroli

## Krytyczne ustalenia (natychmiastowe działanie)
- ...

## Ostrzeżenia (rozwiązać w tym tygodniu)
- ...

## Zaliczone
- ...

## Zalecane następne kroki
1. ...
2. ...
3. ...
```

Priorytetyzuj ściśle: krytyczne ustalenia najpierw, potem ostrzeżenia.
Dla każdego ustalenia: jaki jest problem, dlaczego to ryzyko, jakie jest rozwiązanie.
