Add agent security skills for Codex and Claude Code
Same skills in .agents/skills (Codex) and .claude/skills (Claude Code): codeguard, security-review, dependency-vetting, pre-release-gate, authz-idor-audit, threat-model-light. Source: cj/claude-skills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
431f9ff059
commit
67476ea59b
68 changed files with 6600 additions and 0 deletions
68
.agents/skills/security-review/references/asvs-light.md
Normal file
68
.agents/skills/security-review/references/asvs-light.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# ASVS-light – Checkliste für eigene Apps
|
||||
|
||||
Angelehnt an OWASP ASVS, reduziert auf das, was bei kleinen selbst gebauten Apps (FastAPI,
|
||||
Express, React/Next) regelmäßig schiefgeht. Jeder Punkt ist prüfbar. Spalte „Beleg“ sagt,
|
||||
womit man ihn nachweist.
|
||||
|
||||
Prioritäten: **K** = Kritisch (No-Go, wenn offen), **H** = Hoch, **M** = Mittel.
|
||||
|
||||
## 1. Authentifizierung
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| A1 | K | Jede Route außer einer expliziten Public-Liste verlangt Login | Test „jede Route verlangt Auth“ (Routen aus OpenAPI/Router, Leerlauf-Sperre) |
|
||||
| A2 | K | Identität kommt aus geprüfter Quelle (Session, JWT mit Signaturprüfung, Proxy-Header nur mit Shared Secret) | Spoofing-Test: gefälschter Header ohne Secret → 401 |
|
||||
| A3 | K | App-Port ist nicht am Reverse-Proxy vorbei erreichbar (Compose: kein `ports:` oder nur `127.0.0.1:`) | `docker compose config`, `ss -tlnp`, Zugriff von anderem Host |
|
||||
| A4 | H | Session-Cookies: `HttpOnly`, `Secure`, `SameSite=Lax/Strict` | Test auf `Set-Cookie` |
|
||||
| A5 | H | Login/Token-Endpunkte haben Rate-Limit | Konfiguration + Test |
|
||||
| A6 | M | Logout invalidiert die Session serverseitig | Test |
|
||||
|
||||
## 2. Autorisierung
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| B1 | K | Objektzugriff wird pro Objekt geprüft (kein IDOR): Nutzer B kann Objekt von A weder lesen noch ändern noch löschen | IDOR-Tests mit zwei Nutzern |
|
||||
| B2 | K | Listen-Endpunkte liefern nur erlaubte Objekte | Test: Liste von B enthält nichts von A |
|
||||
| B3 | H | Rollenmatrix ist dokumentiert und als Tests abgebildet | Skill `authz-idor-audit` |
|
||||
| B4 | H | Rechte werden serverseitig geprüft, nicht nur im UI versteckt | Test direkt gegen API |
|
||||
| B5 | M | Admin-Funktionen auf eigenen Routen mit eigener Prüfung | Code-Review |
|
||||
|
||||
## 3. Eingaben
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| C1 | K | SQL ausschließlich parametrisiert / ORM, keine String-Verkettung | Semgrep-Regeln, Ruff S608 |
|
||||
| C2 | H | Alle Request-Bodies laufen durch Schemas mit „unbekannte Felder verboten“ (Pydantic `extra="forbid"`, zod `.strict()`) | Mass-Assignment-Test (`role`, `owner`, `leader` im Body → 422/400) |
|
||||
| C3 | H | Ungültige Eingaben → 4xx, nie 500 | Test ungültige Eingabe, Fuzzing (`make fuzz`) |
|
||||
| C4 | H | Kein `eval`/`exec`, kein `shell=True`, kein unsicheres Deserialisieren (`pickle`, `yaml.load`) | Semgrep, Bandit |
|
||||
| C5 | M | Datei-Uploads: Typ/Größe begrenzt, Pfad nicht vom Client bestimmt | Test |
|
||||
|
||||
## 4. Frontend
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| D1 | H | Kein `dangerouslySetInnerHTML`/`innerHTML` mit nicht vertrauenswürdigen Daten | ESLint `react/no-danger`, Semgrep |
|
||||
| D2 | H | Keine Tokens/Secrets in `localStorage`/`sessionStorage` | Semgrep, Playwright-Test auf Web Storage |
|
||||
| D3 | M | Security-Header gesetzt (CSP, `X-Content-Type-Options`, `frame-ancestors`) | ZAP-Baseline (`make zap`) |
|
||||
| D4 | M | Keine Secrets im Frontend-Bundle (`NEXT_PUBLIC_*`, `VITE_*` prüfen) | gitleaks auf Build-Output |
|
||||
|
||||
## 5. Konfiguration
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| E1 | K | Keine Secrets im Repo oder in der Git-Historie | gitleaks (Pre-Commit + CI) |
|
||||
| E2 | K | CORS: kein `*`, kein `origin: true` zusammen mit Credentials | CORS-Test, Semgrep |
|
||||
| E3 | H | Debug-Modus aus, API-Docs in Prod aus oder geschützt | Prod-Konfigurationstest |
|
||||
| E4 | H | Fehlerantworten ohne Stacktrace/Exception-Text | Test auf generische 500er |
|
||||
| E5 | H | TLS-Prüfung nie abgeschaltet (`verify=False`, `rejectUnauthorized:false`, `NODE_TLS_REJECT_UNAUTHORIZED=0`) | Semgrep |
|
||||
| E6 | M | Container läuft nicht als root, Image ohne High/Critical | `make container` (Trivy, hadolint) |
|
||||
|
||||
## 6. Abhängigkeiten
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| F1 | K | Keine High/Critical-Lücken ohne dokumentierte Ausnahme | `make audit` |
|
||||
| F2 | H | Jede neue Dependency vorher geprüft (existiert, nicht typosquat, gepflegt) | Skill `dependency-vetting`, `make vet-deps` |
|
||||
| F3 | M | Lockfile im Repo (`package-lock.json`, `requirements*.txt` gepinnt) | Repo |
|
||||
|
||||
## 7. Datenschutz
|
||||
| ID | Prio | Punkt | Beleg |
|
||||
|----|------|-------|-------|
|
||||
| G1 | H | Gesundheitsdaten (z. B. Abwesenheitsgrund „krank“) nur speichern, wenn nötig; sonst neutrale Abwesenheit | Datenmodell |
|
||||
| G2 | H | Logs ohne personenbezogene Daten, Tokens, Passwörter | Code-Review, Log-Stichprobe |
|
||||
| G3 | M | Testdaten synthetisch, keine echten Mitarbeiter-/Kundendaten in Tests, Fixtures, Seeds | Review |
|
||||
| G4 | M | Löschkonzept: wer löscht wann welche Personendaten | Doku |
|
||||
Loading…
Add table
Add a link
Reference in a new issue