fix: round 10 critical fixes - WebSocket race, rate limiting, XSS protection, Caddyfile, and input validation
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -16,6 +17,9 @@ import (
|
||||
"github.com/yourname/cyrene-ai/gateway/internal/store"
|
||||
)
|
||||
|
||||
// usernameRegex 用户名格式校验:仅允许字母、数字、下划线,长度 3-32
|
||||
var usernameRegex = regexp.MustCompile(`^[a-zA-Z0-9_]{3,32}$`)
|
||||
|
||||
// AuthHandler 认证处理器
|
||||
type AuthHandler struct {
|
||||
cfg *config.Config
|
||||
@@ -49,6 +53,12 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 用户名格式校验:仅允许字母、数字、下划线,长度 3-32
|
||||
if !usernameRegex.MatchString(req.Username) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "用户名格式无效:仅允许字母、数字和下划线,长度 3-32 位"})
|
||||
return
|
||||
}
|
||||
|
||||
// MVP阶段:验证码简单校验 (开发环境接受 "000000")
|
||||
if req.VerifyCode != "000000" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "验证码错误 (开发阶段请使用 000000)"})
|
||||
@@ -118,6 +128,12 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 用户名格式校验:仅允许字母、数字、下划线,长度 3-32
|
||||
if !usernameRegex.MatchString(req.Username) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "用户名格式无效"})
|
||||
return
|
||||
}
|
||||
|
||||
var userID string
|
||||
|
||||
// 尝试从 users 表查询用户
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"html"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -77,8 +78,8 @@ func (h *KnowledgeHandler) CreateKB(c *gin.Context) {
|
||||
kb := &store.KnowledgeBase{
|
||||
ID: store.GenerateUUID(),
|
||||
UserID: userID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
Name: html.EscapeString(req.Name),
|
||||
Description: html.EscapeString(req.Description),
|
||||
}
|
||||
|
||||
if err := h.store.CreateKB(kb); err != nil {
|
||||
@@ -175,7 +176,7 @@ func (h *KnowledgeHandler) UpdateKB(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.store.UpdateKB(kbID, req.Name, req.Description); err != nil {
|
||||
if err := h.store.UpdateKB(kbID, html.EscapeString(req.Name), html.EscapeString(req.Description)); err != nil {
|
||||
log.Printf("[KnowledgeHandler] 更新知识库失败: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "更新知识库失败", "errorType": "db_error"})
|
||||
return
|
||||
@@ -315,8 +316,8 @@ func (h *KnowledgeHandler) AddDocument(c *gin.Context) {
|
||||
ID: store.GenerateUUID(),
|
||||
KBID: kbID,
|
||||
UserID: userID,
|
||||
Title: req.Title,
|
||||
SourceType: req.SourceType,
|
||||
Title: html.EscapeString(req.Title),
|
||||
SourceType: html.EscapeString(req.SourceType),
|
||||
SourceRef: sourceRef,
|
||||
ContentType: contentType,
|
||||
RawContent: content,
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -144,11 +145,11 @@ func (h *MemoryHandler) Add(c *gin.Context) {
|
||||
userID = req.UserID
|
||||
}
|
||||
|
||||
// 转发到 Memory-Service
|
||||
// 转发到 Memory-Service(对用户输入进行 HTML 转义防 XSS)
|
||||
memReq := map[string]interface{}{
|
||||
"user_id": userID,
|
||||
"content": req.Content,
|
||||
"category": req.Category,
|
||||
"content": html.EscapeString(req.Content),
|
||||
"category": html.EscapeString(req.Category),
|
||||
"priority": req.Priority,
|
||||
}
|
||||
reqBody, _ := json.Marshal(memReq)
|
||||
|
||||
@@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"html"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -113,8 +114,8 @@ func (h *ReminderHandler) Create(c *gin.Context) {
|
||||
reminder := &store.Reminder{
|
||||
ID: generateID(),
|
||||
UserID: userID,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
Title: html.EscapeString(req.Title),
|
||||
Description: html.EscapeString(req.Description),
|
||||
RemindAt: remindAt,
|
||||
Status: "pending",
|
||||
RepeatType: repeatType,
|
||||
|
||||
Reference in New Issue
Block a user