fix(security): x/crypto v0.52 + x/net v0.55 (6 CVEs) + govulncheck-Release-Gate — v1.3.1
govulncheck ab sofort fest im Release-Prozess. Baseline-Scan fand 6 aktiv aufgerufene Vulns (SSH-Backup-Pfad internal/services/backup/remote): - 5× golang.org/x/crypto (SSH DoS/Deadlock/Panic: GO-2026-5013/5017/5018/5019/5020) → x/crypto v0.51.0 => v0.52.0 - 1× golang.org/x/net (GO-2026-5026) → v0.53.0 => v0.55.0 Re-Scan danach: "No vulnerabilities found." Go-Quality-Baseline (Makefile + .golangci.yml, portabel): - release-check läuft autom. vor jedem deb/publish: vet → golangci-lint (Rollout: non-blocking) → govulncheck (HARTER Gate) → build → test -race. - make vulncheck / make test-race als eigene Targets. - .golangci.yml: staticcheck/govet/errcheck/ineffassign/unused/misspell + gosec/bodyclose/rowserrcheck/sqlclosecheck/noctx/contextcheck. - go test -race: aktuell 0 Races (Gate sicher). Doku in CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
42
.golangci.yml
Normal file
42
.golangci.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
# 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
|
||||
- rowserrcheck # fehlendes rows.Err() (database/sql-Muster)
|
||||
- sqlclosecheck # fehlendes rows/stmt.Close()
|
||||
# ── 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
|
||||
|
||||
# HINWEIS: rowserrcheck/sqlclosecheck zielen auf database/sql. EdgeGuard nutzt
|
||||
# pgx/pgxpool — dort greifen sie nur teilweise. Das pgx-Muster (manuelles
|
||||
# rows.Next()/Scan() + defer rows.Close() + rows.Err()) bitte weiter per Review
|
||||
# absichern; siehe internal/services/*/*.go.
|
||||
16
CLAUDE.md
16
CLAUDE.md
@@ -131,8 +131,11 @@ HAProxy terminiert TLS auf `:443`, routet per Host-Header an Backends und fällt
|
||||
```bash
|
||||
make build # Host-Architektur (amd64)
|
||||
make test # go test ./...
|
||||
make lint # golangci-lint
|
||||
make deb # amd64 + arm64 .deb
|
||||
make test-race # go test -race ./... (Race-Detector)
|
||||
make lint # go vet + golangci-lint
|
||||
make vulncheck # govulncheck ./... (Go-Vuln-DB-Scan)
|
||||
make release-check # Go-Quality-Baseline (läuft autom. vor jedem deb/publish)
|
||||
make deb # amd64 + arm64 .deb (führt release-check aus)
|
||||
make publish # deb + Upload Gitea Package Registry
|
||||
make install-local # direkt auf Dev-Server installieren (kein .deb)
|
||||
|
||||
@@ -140,6 +143,15 @@ make install-local # direkt auf Dev-Server installieren (kein .deb)
|
||||
cd management-ui && bun install && bun run build
|
||||
```
|
||||
|
||||
### Go-Quality-Baseline (PFLICHT vor jedem Release)
|
||||
`make deb`/`make publish` führen automatisch `release-check` aus — Reihenfolge:
|
||||
**`go vet` → `golangci-lint run` → `govulncheck ./...` → `go build` → `go test -race`**.
|
||||
|
||||
- **`govulncheck` ist ein HARTER Gate** — Build bricht ab, wenn der Code eine bekannte CVE tatsächlich aufruft. Tool wird bei Bedarf autom. installiert. Zusätzlich sinnvoll: wöchentlicher CI-Cron (CVEs tauchen auch ohne Code-Änderung auf).
|
||||
- **`golangci-lint`** (`.golangci.yml`: staticcheck, govet, errcheck, ineffassign, unused, misspell, **gosec**, **bodyclose**, rowserrcheck, sqlclosecheck, noctx, contextcheck) läuft im **Rollout noch NON-BLOCKING** (Bestand aufräumen), danach auf harten Gate stellen.
|
||||
- **`go test -race`** — Race-Detector; findet Nebenläufigkeits-Bugs (Scheduler/Worker), die normale Tests durchlassen.
|
||||
- Portabel als „Go-Quality-Baseline" für weitere Go-Projekte gedacht.
|
||||
|
||||
---
|
||||
|
||||
## Dev-Server Quickstart
|
||||
|
||||
34
Makefile
34
Makefile
@@ -10,7 +10,7 @@ LDFLAGS := -s -w -X main.version=$(VERSION)
|
||||
GOFLAGS := -trimpath -mod=readonly
|
||||
export CGO_ENABLED ?= 0
|
||||
|
||||
.PHONY: all help build test lint tidy clean ui \
|
||||
.PHONY: all help build test test-race lint vulncheck release-check tidy clean ui \
|
||||
build-linux-amd64 build-linux-arm64 \
|
||||
deb deb-amd64 deb-arm64 \
|
||||
publish publish-amd64 publish-arm64
|
||||
@@ -61,9 +61,35 @@ build-linux-arm64:
|
||||
test:
|
||||
$(GO) test $(GOFLAGS) ./...
|
||||
|
||||
test-race:
|
||||
CGO_ENABLED=1 $(GO) test $(GOFLAGS) -race ./...
|
||||
|
||||
lint:
|
||||
$(GO) vet ./...
|
||||
@command -v staticcheck >/dev/null && staticcheck ./... || echo "staticcheck not installed, skipping"
|
||||
@command -v golangci-lint >/dev/null 2>&1 && golangci-lint run \
|
||||
|| echo "golangci-lint nicht installiert (go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest) — übersprungen"
|
||||
|
||||
GOBIN := $(shell $(GO) env GOPATH)/bin
|
||||
|
||||
# govulncheck — Go-Vuln-DB-Scan. HARTER Release-Gate: bricht ab, wenn der
|
||||
# Code eine bekannte Vulnerability tatsächlich aufruft. Tool wird bei Bedarf
|
||||
# automatisch installiert.
|
||||
vulncheck:
|
||||
@command -v govulncheck >/dev/null 2>&1 || GOFLAGS= $(GO) install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
@PATH="$(GOBIN):$$PATH" govulncheck ./...
|
||||
|
||||
# Go-Quality-Baseline — läuft automatisch vor jedem Release (deb/publish).
|
||||
# Reihenfolge: vet → golangci-lint (Rollout: NON-BLOCKING) → govulncheck (GATE)
|
||||
# → build → test -race. govulncheck bricht bei jedem Fund ab; der Linter ist
|
||||
# in der Rollout-Phase noch non-blocking (Bestand aufräumen, dann auf Gate).
|
||||
release-check:
|
||||
$(GO) vet ./...
|
||||
@command -v golangci-lint >/dev/null 2>&1 && (golangci-lint run || echo " ⚠ golangci-lint-Findings (non-blocking, Rollout-Phase)") \
|
||||
|| echo " golangci-lint nicht installiert — übersprungen (Rollout-Phase)"
|
||||
@$(MAKE) --no-print-directory vulncheck
|
||||
$(GO) build ./...
|
||||
CGO_ENABLED=1 $(GO) test $(GOFLAGS) -race ./...
|
||||
@echo " ✓ Go-Quality-Baseline bestanden (vet, govulncheck, build, test -race)"
|
||||
|
||||
tidy:
|
||||
$(GO) mod tidy
|
||||
@@ -74,10 +100,10 @@ ui:
|
||||
if [ -x "$$(command -v bun)" ]; then bun install --silent && bun run build; \
|
||||
else npm install --silent && npm run build; fi
|
||||
|
||||
deb-amd64: build-linux-amd64 ui
|
||||
deb-amd64: release-check build-linux-amd64 ui
|
||||
@./scripts/apt-repo/build-package.sh amd64 $(VERSION)
|
||||
|
||||
deb-arm64: build-linux-arm64 ui
|
||||
deb-arm64: release-check build-linux-arm64 ui
|
||||
@./scripts/apt-repo/build-package.sh arm64 $(VERSION)
|
||||
|
||||
deb: deb-amd64 deb-arm64
|
||||
|
||||
6
go.mod
6
go.mod
@@ -16,7 +16,7 @@ require (
|
||||
github.com/pquerna/otp v1.5.0
|
||||
github.com/pressly/goose/v3 v3.27.1
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
golang.org/x/crypto v0.51.0
|
||||
golang.org/x/crypto v0.52.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
)
|
||||
|
||||
@@ -79,9 +79,9 @@ require (
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/net v0.55.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.44.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@@ -186,18 +186,18 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
|
||||
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
|
||||
Reference in New Issue
Block a user