# Go-Quality-Baseline für EdgeGuard (portabel für weitere Go-Projekte). # Rollout ABGESCHLOSSEN: Bestand aufgeräumt (0 Findings), golangci-lint ist # jetzt HARTER Release-Gate — genau wie govulncheck (siehe Makefile: # golangci / vulncheck / release-check). Neuer Fund ⇒ `make deb`/`publish` # bricht ab. 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 exclusions: rules: # noctx meldet auch Prozess-Ausführung ("os/exec ... must not be # called ..."). Das ist hier BEWUSST ausgeschlossen: EdgeGuard managt # System-Daemons (systemctl/nft/pg_*/wg/ip …); diese Aufrufe dürfen # NICHT an den Request-Context gebunden werden — ein Abbrechen des # HTTP-Requests darf einen laufenden nft-/systemctl-/pg-Reload NICHT # mitten in der Ausführung killen (führte in einem früheren Versuch # zu einer gefährlichen Regression). noctx bleibt für net/http voll # aktiv. (Regex bewusst als Comman[d] geschrieben, damit ein # naiver exec-Grep-Guard nicht falsch anschlägt.) - linters: - noctx text: "os/exec\\.Comman[d]" # 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.