harden(api): Slowloris-Timeout + gosec-Security-Audit + waf-Purge-Bugfix — v1.3.2

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>
This commit is contained in:
Debian
2026-07-05 23:36:37 +02:00
parent 02096c8ad8
commit cdbb62ee1a
5 changed files with 69 additions and 10 deletions

View File

@@ -179,9 +179,14 @@ func (r *Repo) ListAlerts(ctx context.Context, domainID *int64, limit int) ([]Wa
}
// PurgeAlerts removes alerts older than the given number of days.
//
// make_interval(days => $1) nimmt $1 als int — sauber typisiert. Der
// frühere ($1 || ' days')::interval-Ansatz erzwang $1 als text; pgx
// bekam aber einen int und scheiterte mit einem Encode-Fehler zur
// Laufzeit (gleiche Klasse wie der audit-Cleanup-Bug, v1.3.0).
func (r *Repo) PurgeAlerts(ctx context.Context, olderThanDays int) error {
_, err := r.Pool.Exec(ctx,
`DELETE FROM waf_alerts WHERE created_at < NOW() - ($1 || ' days')::interval`,
`DELETE FROM waf_alerts WHERE created_at < NOW() - make_interval(days => $1)`,
olderThanDays,
)
return err