Ech0 allows PUT /api/echo/like/:id unauthenticated: anonymous callers to modify any echo's fav_count
Date: 2026-05
Affected: go/github.com/lin-snow/Ech0
Attack vector: other
Category: vulnerability-disclosure
Severity: Medium
CWE: CWE-770
CWE-862
CVSS: 6.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L)

## Summary `PUT /api/echo/like/:id` at `internal/router/echo.go:12` is registered on `PublicRouterGroup` with no authentication and no rate limit. Anonymous callers increment the `fav_count` counter on any echo (including private echoes) by UUID, repeat the request without deduplication, and trigger a database write plus a four-key cache invalidation on every call. Alice harvests echo UUIDs from the public `GET /api/echo/page` response, inflates fav counts at will, and spams writes to amplify load on the DB and cache layers. ## Details Route registration at `internal/router/echo.go:12`: ```go appRouterGroup.PublicRouterGroup.PUT("/echo/like/:id", h.EchoHandler.LikeEcho()) ``` `PublicRouterGroup` is `r.Group("/api")` without the JWT middleware that `AuthRouterGroup` applies. The handler passes through to `EchoService.LikeEcho`, which calls `EchoRepository.LikeEcho` at `internal/repository/echo/echo.go:270`: ```go func (echoRepository *EchoRepository) LikeEcho(ctx context.Context, id string) error { var exists bool if err := echoRepository.getDB(ctx).Model(&model.Echo{}). Select("count(*) > 0").Where("id = ?", id).Find(&exists).Error; err != nil { return err } if !exists { return errors.New(commonModel.ECHO_NOT_FOUND) } if err := echoRepository.getDB(ctx).Model(&model.Echo{}). Where("id = ?", id). UpdateColumn("fav_count", gorm.Expr("fav_count + ?", 1)).Error; err != nil { return err } return


Mitigations:

Architectural layers (MAESTRO):