Complete implementation: e2e tests, gofmt, hardening
- Add test/e2e: 11 end-to-end tests covering full login/logout, token renewal, admin account management, credential-never-in-response, unauthorised access, JWT alg confusion and alg:none attacks, revoked token rejection, system account token issuance, wrong-password vs unknown-user indistinguishability - Apply gofmt to all source files (formatting only, no logic changes) - Update .golangci.yaml for golangci-lint v2 (version field required, gosimple merged into staticcheck, formatters section separated) - Update PROGRESS.md to reflect Phase 5 completion Security: All 97 tests pass with go test -race ./... (zero race conditions). Adversarial JWT tests (alg confusion, alg:none) confirm the ValidateToken alg-first check is effective against both attack classes. Credential fields (PasswordHash, TOTPSecret*, PGPassword) confirmed absent from all API responses via both unit and e2e tests. go vet ./... clean. golangci-lint v2.6.2 incompatible with go1.26 runtime; go vet used as linter until toolchain is updated.
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
// for the MCIAS authentication server.
|
||||
//
|
||||
// Security design:
|
||||
// - All endpoints use HTTPS (enforced at the listener level in cmd/mciassrv).
|
||||
// - Authentication state is carried via JWT; no cookies or server-side sessions.
|
||||
// - Credential fields (password hash, TOTP secret, Postgres password) are
|
||||
// never included in any API response.
|
||||
// - All JSON parsing uses strict decoders that reject unknown fields.
|
||||
// - All endpoints use HTTPS (enforced at the listener level in cmd/mciassrv).
|
||||
// - Authentication state is carried via JWT; no cookies or server-side sessions.
|
||||
// - Credential fields (password hash, TOTP secret, Postgres password) are
|
||||
// never included in any API response.
|
||||
// - All JSON parsing uses strict decoders that reject unknown fields.
|
||||
package server
|
||||
|
||||
import (
|
||||
@@ -610,7 +610,7 @@ func (s *Server) handleSetRoles(w http.ResponseWriter, r *http.Request) {
|
||||
// ---- TOTP endpoints ----
|
||||
|
||||
type totpEnrollResponse struct {
|
||||
Secret string `json:"secret"` // base32-encoded
|
||||
Secret string `json:"secret"` // base32-encoded
|
||||
OTPAuthURI string `json:"otpauth_uri"`
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@ func (s *Server) handleTOTPEnroll(w http.ResponseWriter, r *http.Request) {
|
||||
// Security: return the secret for display to the user. It is only shown
|
||||
// once; subsequent reads are not possible (only the encrypted form is stored).
|
||||
writeJSON(w, http.StatusOK, totpEnrollResponse{
|
||||
Secret: b32Secret,
|
||||
Secret: b32Secret,
|
||||
OTPAuthURI: otpURI,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user