---
name: pentest-security
description: Uruchamia pełny zestaw testów penetracyjnych Finora v2 — broken access control, SQL injection, rate limit bypass, XSS, ekspozycja danych, user enumeration, CSRF, misconfiguration. Użyj po naprawach bezpieczeństwa aby zweryfikować że luki zostały zamknięte.
argument-hint: "[all|access|sqli|ratelimit|xss|leaks|enum|csrf|misc]"
arguments: [scope]
disable-model-invocation: true
allowed-tools: Read Grep Glob Bash(./.claude/skills/pentest-security/*) Bash(docker compose *) Bash(docker exec *) Bash(docker logs *) Bash(curl *) Bash(python3 *) Bash(git log *) Bash(git status *)
---

# Pentest Security Suite

Pełny zestaw testów penetracyjnych aplikacji Finora v2. Powtarzalne testy do uruchamiania po każdej naprawie security, by zweryfikować że żadna luka nie wróciła.

Zakres: `$scope` (default: `all`). Dozwolone: `all`, `access`, `sqli`, `ratelimit`, `xss`, `leaks`, `enum`, `csrf`, `misc`.

## Wymagania wstępne

- Aplikacja uruchomiona: `./finora.sh up` lub `docker compose up -d`
- Backend dostępny na `http://localhost:5000`
- Frontend dostępny na `http://localhost:3000`
- Baza `finora-db` osiągalna przez `docker exec`
- Konto `admin@finora.local` / `Admin@Finora2024!` istnieje (seed)

## Uruchomienie

```bash
./.claude/skills/pentest-security/run.sh $scope
```

Skrypt zwraca raport w stdout oraz exit code:
- `0` — wszystkie testy przeszły (brak krytycznych podatności)
- `1` — wykryto co najmniej jedną krytyczną podatność (CVSS >= 7.0)
- `2` — błąd środowiska (aplikacja nie działa, brak postgres, etc.)

Wynik dodatkowo zapisywany do `monitoring/agent-logs/pentest-${CLAUDE_SESSION_ID}.md` jeśli zmienna jest ustawiona, w przeciwnym razie do `monitoring/agent-logs/pentest-latest.md`.

## Co testuje (8 kategorii, ~30 testów)

### 1. Broken Access Control (`access`) — OWASP A01
- Czy endpointy domenowe wymagają X-User-Id (powinny 401 bez auth)
- X-User-Id spoofing — czy można podszyć się pod admina samym GUID-em
- X-User-Email fallback — czy istnieje druga droga obejścia w `GetCurrentUser`
- Random GUID w X-User-Id — czy endpoint odrzuca nieistniejących userów
- Privilege escalation — czy spoofed admin może utworzyć nowego admina
- IDOR — czy można odczytać/zmienić/usunąć dane innego usera

### 2. SQL Injection (`sqli`) — OWASP A03
- Login email field, check-email, X-User-Id header, query params, POST body
- Verifikacja, że tabela `Banki` nadal istnieje po próbach DROP
- Sprawdzenie czy `ExecuteSqlRaw` przyjmuje user input

### 3. Rate Limiting Bypass (`ratelimit`)
- Per-email vs per-IP — 30 prób z 30 emailami z tego samego IP
- Account lockout DoS — czy 5 błędnych prób blokuje admina z prawidłowym hasłem
- Brak rate limit na innych endpointach (check-email, reset-request, set-password)
- In-memory state — czy restart kontenera resetuje liczniki

### 4. XSS i Input Validation (`xss`) — OWASP A03
- Stored XSS w nazwach (banki, etc.) — backend powinien sanityzować lub frontend escapować
- Payload encoding — `<script>`, `javascript:`, `<img onerror>`, template literals
- React `dangerouslySetInnerHTML` z user input
- CSP header backend i frontend (nginx)
- Brak limitów długości pól (100KB nazwa banku)

### 5. Ekspozycja Wrażliwych Danych (`leaks`) — OWASP A02
- `passwordHash` w odpowiedziach (`/api/admin/uzytkownicy`, `/api/auth/reset-request`)
- `/metrics` publicznie ujawnia kwoty (`finora_total_assets_pln`)
- Verbose error messages
- Source maps `assets/*.js.map` w produkcji
- Prometheus/Grafana publicznie dostępne
- Plain-text password w `change-password` (sprawdza kod źródłowy)

### 6. User Enumeration & Timing (`enum`)
- `/check-email` jawnie zwraca `exists: true/false` + `type: admin/user`
- Timing attack na login (różnica bcrypt verify vs no-user)
- Login response — różnica między bad password a invalid user

### 7. CSRF i Sesja (`csrf`)
- Czy mutating endpoints (`POST /api/banki`) wymagają CSRF token
- Czy `token: poc_token_*` z login jest weryfikowany
- Czy `ValidateCsrfToken`/`CheckCsrfToken` są wywoływane w endpointach

### 8. Misconfiguration (`misc`) — OWASP A05
- Security headers backend (CSP, X-Frame-Options, HSTS, etc.)
- Security headers frontend nginx
- HTTPS / TLS / HSTS
- Server fingerprinting (`Server: Kestrel`, `Server: nginx/1.27`)
- Docker non-root users
- Hardcoded admin password w kodzie
- CORS — czy odrzuca evil.com, null, file://
- HTTP methods — TRACE, OPTIONS
- Permissions na `secrets/*.txt`
- **EKSPLOIT `set-password`** — czy można nadpisać hasło admina bez auth

## Wynik

Skrypt drukuje strukturę:

```
═══ TEST X: Nazwa ═══
─── X.Y: Opis ───
  [PASS] ... lub [FAIL] ... lub [INFO] ...
```

Na końcu podsumowanie:
```
═══ SUMMARY ═══
PASSED: N
FAILED: M  (z czego CRITICAL: K)
EXIT CODE: 0/1/2
```

## Po uruchomieniu

Jako agent po wykonaniu skill:

1. Pokaż użytkownikowi pełny wynik (exit code + summary).
2. Porównaj z poprzednim raportem jeśli istnieje (`monitoring/agent-logs/pentest-latest.md`).
3. Dla każdego FAIL podaj plik i linię w kodzie do naprawy.
4. Nie próbuj automatycznie naprawiać — sygnalizuj tylko status. Naprawy idą przez `/finora-safe-change`.

## Co skill ZAKŁADA, nie weryfikuje

- Czy bcrypt workFactor jest wystarczający (tylko sprawdza że jest >=10)
- Czy konfiguracja Cloudflare WAF jest poprawna (testy są lokalne)
- Czy TLS jest dobrze skonfigurowany (testy idą po HTTP do localhost)
- Czy backupy/dane historyczne nie zawierają wrażliwych danych
- Czy logi nie wyciekają sekretów (manualna inspekcja `docker logs`)

## Bezpieczeństwo skillu

- Skill **tworzy testowe dane** (banki, użytkowników z prefiksem `pentest_`). Po wykonaniu robi cleanup.
- Skill **resetuje hasło admina** podczas testu `set-password`. Po teście przywraca `Admin@Finora2024!` jeśli zmienił.
- Skill **NIE wykonuje testów destruktywnych** na produkcji — sprawdza `ASPNETCORE_ENVIRONMENT` i przerywa jeśli `Production` bez explicit `--force-prod`.
