Mock 地址安全加固:空间 ID → 16 位随机 mock_token
- 问题:/mock/{自增空间ID} 可枚举且服务绑定所有网卡,局域网可猜他人空间
- workspaces 新增 mock_token(UNIQUE,随机 8 字节 hex;老库自动 ALTER + 回填)
- /mock/{token}/path:解析失败统一 404(不暴露存在性);限流 key 沿用 token
- /api/me 与发布响应返回 token 形态 base;弹窗 URL 改用 token
- 验证:token URL 正常随机生成;旧数字 ID 与任意伪造 token 均 404
This commit is contained in:
1 parent
d9ccccd280
commit
0edd3e674a
9 files changed
+87
-17
No files matched your search
@@ -2,7 +2,6 @@ package mocksrv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -25,6 +24,7 @@ type Endpoint struct {
|
||||
type storeAPI interface {
|
||||
ReplaceMockEndpoints(workspaceID int64, list []Endpoint) error
|
||||
FindMockEndpoint(workspaceID int64, method, path string) (*Endpoint, bool, error)
|
||||
ResolveMockToken(token string) (int64, bool, error)
|
||||
}
|
||||
|
||||
/* ---------------- 限流:20 QPS / 60 QPM(按 IP + 空间,滑动窗口) ---------------- */
|
||||
@@ -121,7 +121,16 @@ func (s *Server) handle(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
wsID, _ := strconv.ParseInt(wsid, 10, 64)
|
||||
// wsid 实为 mock_token:不可枚举、不暴露空间归属;解析失败统一 404
|
||||
wsID, ok, err := s.store.ResolveMockToken(wsid)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "mock 存储读取失败"})
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Mock 地址无效或已失效"})
|
||||
return
|
||||
}
|
||||
ep, found, err := s.store.FindMockEndpoint(wsID, method, path)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "mock 存储读取失败"})
|
||||
|
||||
Reference in new issue
Block a user