Security & quality patch
Fixed
- Rebuilt against go1.25.9, clearing 17 stdlib CVEs reachable via the API, TLS, and URL-parsing paths (most notably GO-2026-4870 TLS KeyUpdate DoS, GO-2025-4012 cookie memory exhaustion, GO-2025-4009 PEM quadratic complexity, GO-2025-4007 x509 name-constraint quadratic).
- Repaired
.golangci.yml— removedgosimple(absorbed intostaticcheckin lint v2) and droppedcontinue-on-erroron the lint job. The lint CI gate had been silently failing since the v2 upgrade. - qBittorrent client no longer panics on session-expiry retry when
http.NewRequestWithContextfails — the error is now propagated instead of callingDoon a nil request. - API handlers that take
{id}in the URL path now return HTTP 400 for non-numeric IDs instead of silently acting on ID 0. NewparseIDhelper ininternal/api/helpers.goconsolidates the pattern. - Library-scan importer no longer dereferences nil pointers when a book or author lookup fails; lookup errors are logged and the file falls through to the unmatched-import path.
- History-blocklist handler logs corrupt JSON
datacolumns instead of silently returning a zero-value event to the client. - SQL UPDATE in
downloads.UpdateStatusno longer interpolates a column name viafmt.Sprintf. Three explicit statements, one per known status, with the column name as a fixed literal. - Primary HTTP server now sets
ReadHeaderTimeout/ReadTimeout/WriteTimeout/IdleTimeoutinstead of running with the defaults (which are effectively unlimited). Mitigates slow-loris and resource-exhaustion attacks on the public API surface.
Added
- Startup warning logged when
BINDERY_API_KEYis unset, making it obvious that/api/v1/*is unauthenticated. - Helm chart
deployment.yamlnow sets a hardened pod+containersecurityContext:runAsNonRoot: true,runAsUser: 65532,readOnlyRootFilesystem: true,allowPrivilegeEscalation: false,capabilities.drop: [ALL],seccompProfile.RuntimeDefault, plus a writableemptyDirmounted at/tmp. - CI workflow now auto-creates a GitHub Release with notes extracted from the matching CHANGELOG section on every
v*tag push. Title is derived from the first###subheading. Idempotent — updates notes if a release already exists.
Changed
- Dockerfile base image pinned to
golang:1.25.9-alpine(wasgolang:1.25-alpine) and runtime switched togcr.io/distroless/static-debian12:nonrootwithUSER nonroot. go.modbumped togo 1.25.9.- Internal DB queries using
sql.ErrNoRowscomparison now useerrors.Isfor wrap-safety.
Frontend
- Fixed four missing
resetdependencies inuseEffecthooks on Authors / Books / History / Wanted pages (react-hooks/exhaustive-deps). - Extracted
usePaginationhook into its own file (web/src/components/usePagination.ts) soPagination.tsxis a pure component module (fixes react-refresh/only-export-components).