Go-Quality-Baseline-Rollout, Security-Teil: - api: http.Server bekommt ReadHeaderTimeout (15s) + IdleTimeout (120s) gegen Slowloris-Header-Stalls (gosec G112). ReadTimeout/WriteTimeout bewusst offen (lang laufende Rolling-Update-/Backup-Endpoints). - fix(waf): PurgeAlerts nutzte NOW() - ($1 || ' days')::interval mit olderThanDays int → pgx-Encode-Error zur Laufzeit → DELETE /waf/alerts war kaputt. Auf make_interval(days => $1) umgestellt (gleiche Bug- Klasse wie audit-Cleanup v1.3.0). Via Lint-Aufräumen entdeckt. - .golangci.yml: 26 gosec-Findings line-by-line auditiert. Alle sind bewusstes Appliance-Verhalten mit Compensating Controls (Subprocess- Args intern/validiert, Config-File-Perms daemon-lesbar, SSH opt-in Fingerprint-Pinning, UI-Server Clean+HasPrefix-Traversal-Guard) oder FPs (G101 Konstanten-Namen, G702/G703/G706 Taint). Dokumentiert exclude't. gosec-Rest = 0. - .golangci.yml: rowserrcheck/sqlclosecheck raus — database/sql-Linter, bei durchgängigem pgx nur FPs. gosec=0, govulncheck=0, race=0. Rest-Backlog: errcheck/noctx/staticcheck (Code-Quality, kein Security) — folgt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
4.0 KiB
YAML
87 lines
4.0 KiB
YAML
# Go-Quality-Baseline für EdgeGuard (portabel für weitere Go-Projekte).
|
|
# Rollout: erst NON-BLOCKING laufen lassen (Bestand aufräumen), dann in der
|
|
# CI/Makefile auf harten Gate stellen. govulncheck ist bereits ein harter
|
|
# Release-Gate (siehe Makefile: vulncheck / release-check).
|
|
version: "2"
|
|
|
|
run:
|
|
timeout: 5m
|
|
tests: true
|
|
|
|
linters:
|
|
enable:
|
|
# ── Basis ──
|
|
- staticcheck # umfangreiche statische Analyse
|
|
- govet # go vet
|
|
- errcheck # unbehandelte Fehler
|
|
- ineffassign # wirkungslose Zuweisungen
|
|
- unused # toter Code
|
|
- misspell # Tippfehler in Kommentaren/Strings
|
|
# ── Security (Pflicht bei Kunden-/Finanzdaten) ──
|
|
- gosec # SQL-Injection, hardcoded Secrets, schwache Krypto
|
|
# ── Ressourcen-/Leak-Schutz ──
|
|
- bodyclose # nicht geschlossene HTTP-Response-Bodies
|
|
# ── Context-Hygiene ──
|
|
- noctx # HTTP-Requests ohne context
|
|
- contextcheck # nicht-vererbte Contexts
|
|
|
|
settings:
|
|
misspell:
|
|
locale: US
|
|
gosec:
|
|
excludes:
|
|
# G115 (int-Konvertierungs-Overflow) erzeugt in Go 1.26 viele
|
|
# false positives — bei Bedarf gezielt wieder aktivieren.
|
|
- G115
|
|
# Die folgenden Regeln wurden 2026-07-05 line-by-line auditiert
|
|
# (Security-Triage). Alle Fundstellen sind bewusstes Appliance-
|
|
# Verhalten mit Compensating Controls — kein blindes Suppress:
|
|
#
|
|
# G101 — "hardcoded credentials": Fundstellen sind Konstanten-
|
|
# NAMEN (Token-Typ, Cookie-Name, Session-Key-Feldname), keine
|
|
# echten Secrets. Reiner False-Positive-Mustertreffer.
|
|
- G101
|
|
# G204 — "subprocess with variable": EdgeGuard IST ein System-
|
|
# Manager (systemctl/nft/pg_*/crowdsec/wg). Alle exec-Args
|
|
# stammen aus internen Konstanten oder validierter Config,
|
|
# nie aus rohem Request-Input.
|
|
- G204
|
|
# G301/G302/G306 — Datei-/Verzeichnis-Perms: Config-Dateien
|
|
# (chrony.conf, unbound.conf, pg_hba.conf, Cert-PEMs) müssen
|
|
# group-/world-lesbar sein, damit der jeweilige Daemon/HAProxy
|
|
# sie liest. ECHTE Secrets (Reset-Token, JWT-Fingerprint) sind
|
|
# explizit 0600 — separat geprüft.
|
|
- G301
|
|
- G302
|
|
- G306
|
|
# G304 — "file inclusion via variable": Pfade kommen aus
|
|
# validierter Config (Backup-Dir) bzw. via safeDomain()-
|
|
# Sanitizer (Cert-Store). UI-Static-Server hat zusätzlich
|
|
# filepath.Clean + HasPrefix(uiDir)-Traversal-Guard.
|
|
- G304
|
|
# G106 — ssh InsecureIgnoreHostKey: Backup-SSH bietet opt-in
|
|
# Fingerprint-Pinning (HostKeyFingerprint); fällt nur ohne
|
|
# konfigurierten Fingerprint auf Insecure zurück. Dokumentiert.
|
|
- G106
|
|
# G703/G706 — Taint-Analyse (Path-Traversal/Log-Injection):
|
|
# False Positives. Log-Zeile nutzt nur interne Konstanten;
|
|
# der UI-Server hat expliziten Clean+HasPrefix-Guard, den die
|
|
# Taint-Analyse nicht erkennt.
|
|
- G703
|
|
- G706
|
|
# G702 — "command injection via taint": buildPsqlCmd baut exec.
|
|
# Command("psql", args...) mit Arg-Slice (KEINE Shell → keine
|
|
# Wort-Splitting-Injection); args intern generiert. Wie G204.
|
|
- G702
|
|
# G122 — filepath.Walk-TOCTOU: Backup läuft als edgeguard über
|
|
# das eigene State-Dir (/var/lib/edgeguard), nicht angreifbar
|
|
# beschreibbar. Symlink-TOCTOU theoretisch, kein realer Vektor.
|
|
- G122
|
|
|
|
# HINWEIS: rowserrcheck/sqlclosecheck NICHT aktiviert — sie zielen auf
|
|
# database/sql. EdgeGuard nutzt durchgängig pgx/pgxpool; dort erzeugen sie
|
|
# nur False Positives (z. B. wenn rows via Interface-Var zugewiesen wird,
|
|
# obwohl `defer rows.Close()` + `rows.Err()` korrekt vorhanden sind). Das
|
|
# pgx-Muster (manuelles rows.Next()/Scan() + defer rows.Close() + rows.Err())
|
|
# bitte weiter per Review absichern; siehe internal/services/*/*.go.
|