Ech0 comment model's Email field returned on public /api/comments endpoints
Date: 2026-05
Affected: go/github.com/lin-snow/Ech0
Attack vector: info-disclosure
Category: vulnerability-disclosure
Severity: Medium
CWE: CWE-200
CWE-359
CVSS: 5.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

## Summary The `Comment` model serializes its `Email` field through the public comment-listing API. `internal/model/comment/comment.go:33` uses `json:"email"`, while adjacent PII fields (`IPHash`, `UserAgent`) correctly use `json:"-"`. The public endpoints `GET /api/comments?echo_id=X` and `GET /api/comments/public?limit=N` both live on `PublicRouterGroup` with no authentication. Alice retrieves every guest commenter's email address on the instance with a few unauthenticated HTTP calls. ## Details The Comment model at `internal/model/comment/comment.go:33`: ```go type Comment struct { // ... Email string `gorm:"size:255;not null;index" json:"email"` IPHash string `gorm:"size:128;index" json:"-"` UserAgent string `gorm:"size:512" json:"-"` // ... } ``` The `json:"-"` on `IPHash` and `UserAgent` shows the developer's intent: hide server-side PII from API responses. The `Email` field missed the same tag. GORM materializes the full struct and the Gin handler returns it verbatim. Routes at `internal/router/comment.go:20` and comment public-feed route: ```go appRouterGroup.PublicRouterGroup.GET("/comments", middleware.NoCache(), h.CommentHandler.ListCommentsByEchoID()) appRouterGroup.PublicRouterGroup.GET("/comments/public", middleware.NoCache(), h.CommentHandler.ListPublicComments()) ``` Both handlers call `ListPublicByEchoID` (service at `internal/service/comment/comment.go:329`) or `ListPublicComments` (serv


Mitigations:

Architectural layers (MAESTRO):