v1.13.0
Summary
This release is a large security-hardening and robustness pass across the auth,
2FA, crypto, database, and middleware layers. It tightens cryptographic
defaults, makes Redis/DB state changes atomic, bounds and hardens the random/
crypto helpers, reworks the Sentry integration, and threads context.Context
through handlers. It also refreshes dependencies and the agent-facing docs.
Full Changelog: v1.12.4...v1.13.0
Highlights
- Stronger crypto defaults: minimum 32-character HMAC secrets and overflow-safe
Argon2 memory configuration. - Brute-force protection for 2FA backup codes and password-recovery attempts.
- Atomic Redis/DB operations across login/logout, email verification, email
update, password reset, and 2FA flows. - Hardened random-number and validation utilities (
SecureRandomNumber,
ValidateEmail,ValidatePath,FileExist). - Reworked Sentry logrus hook with request-context propagation and panic
recovery. - Handlers now accept
context.Context, honoring client cancellation and
deadlines end-to-end.
Breaking changes & upgrade notes
- Handlers now take
context.Contextas their first argument. Controllers
passc.Request.Context(). Update any direct calls tohandler.*,
service.SendEmail, andservice.IsTokenAllowedto pass a context.
dcf5083 - Minimum 32-character HMAC secrets are enforced. Deployments using shorter
ACCESS_KEY/REFRESH_KEYvalues must lengthen them. 10a17fb SERVE_JWT_AS_RESPONSE_BODYnow defaults to disabled. Set it explicitly if
your clients expect tokens in the response body. 42ba45a- Generic auth errors in production. In prod, auth failures return generic
messages and verification status is exposed only to the account owner.
e030018, 1cb8298, a33ab7b
Security & hardening
- 10a17fb enforce minimum 32-character secrets for HMAC signing
- 37a2208 load JWT private/public key files when required (asymmetric algos)
- 42ba45a default
SERVE_JWT_AS_RESPONSE_BODYto disabled - a10c24f guard
HASHPASSMEMORYagainst uint32 overflow - 1cb8298 constant-time login path for unknown email addresses
- e030018 return generic auth errors in production
- a33ab7b reveal email verification status only to the account owner
- 87c4843 nil-safe
resp.Messagecheck in controllers - e5b8a3a guard
structs.Mapagainst non-struct data
Authentication & 2FA
- 064dcdc add a 2FA recovery-attempt limiter
- b76f862 limit 2FA backup-code brute-force attempts
- 2210307 widen the 2FA recovery-key charset for more entropy
- 63ba198 clear in-memory 2FA state on deactivate
- d33e016 unify the 2FA backup-code response shape
- 2e683a4 skip blacklisting already-expired tokens
Data integrity (atomic operations)
- 3142ddc store verification/recovery codes in Redis atomically with TTL
- 321d201 set logout blacklist key and TTL atomically
- c11ef48 consume the verification code atomically
- cbbb1f6 update email within a single transaction
- dad5c89 atomic password reset + 2FA update
- 43ad32f atomic 2FA + password update in
PasswordUpdate - 1ae6acb handle empty
HGETresult inPasswordRecover - 74c3792 drop redundant
EXISTScheck inPasswordRecover - d82b9cc send recovery email asynchronously in production
Crypto & utility library
- 6c9738f compute random numbers with
big.Int.Exp - 9333052 fix
SecureRandomNumberendpoints and bound edge cases - e9d648f guard
SecureRandomNumberagainst uint64 overflow - a2bfb03 bound the
SecureRandomNumberretry loop - d1b8e89 bound the
ValidateEmailMX lookup with a timeout - e2f5ac6 document that
ValidateEmailskips the RFC 5321 implicit-MX fallback - 38ccfae prevent an out-of-range panic
- 7460350
FileExistreturns true only on a successful stat - 53c100d resolve symlinks in
ValidatePath - ae4f9a1 support colon-containing values in the email HTML model
- efca1c5 fix the
StrArrHTMLModelexample separator in docs
Middleware, renderer & firewall
- 9f9e595 rework the Sentry logrus hook to reliably capture events
- dcf5083 thread request context into logs for Sentry
- 09f42a2 isolate firewall state per instance
- 16f62b7 match firewall wildcard as an exact entry
- 50587f8 apply the status code to HTML responses
- 91e9abb honor media range and q-value during content negotiation
Database
- 73ccb5a use the mysql driver to build the DSN
- 3a808ae use libpq keyword/value DSN format
- ea6eb03
CloseAllDBaborts on the first error - 8ed885c drop shared
err/sqlDBglobals - 98ab74c nil-guard the db/redis client getters
Examples
- c93b78f split public/auth route groups in the router example
- 5b9b24d atomic user-delete cascade (example2)
- 0473fd0 batch-load posts/hobbies in
GetUsers(example2) - 02b419d validate
userIDinGetUser(example) - 4cefe43 nil-guard db/redis/mongo getters in the examples
Observability (Sentry)
- 9f9e595 reworked Sentry logrus hook
- dcf5083 request-context propagation into Sentry logs
- 2779b9f more Sentry test coverage
- 1af2d85 automatic recovery from panic
- b7b765a CI: run the Sentry test with an actual DSN
Dependencies
- 3033429 bump
golang.org/x/crypto0.52.0 → 0.53.0 (#397) - ca2615b bump
go.mongodb.org/mongo-driver/v22.6.0 → 2.6.1 (#399) - 3db4b37 bump
go.mongodb.org/mongo-driver/v22.6.1 → 2.7.0 (#403) - 0c1f2f2 bump
codecov/codecov-action6 → 7 (#398) - a33115b bump
actions/checkout6 → 7 (#402)