feat: enhance security with IP banning, ownership checks, and SSRF protection
All checks were successful
Build Backend / build (push) Successful in 1m56s
Build Backend / build-docker (push) Successful in 1m15s

Add comprehensive security improvements across the application:

- **IP-based login protection**: Implement IP ban system tracking login failures, auto-banning after threshold exceeded
- **Ownership verification**: Add userID parameter to Delete/Update operations for posts and comments to prevent unauthorized modifications
- **SSRF protection**: Add URL and resolved host validation for image URLs in chat and OpenAI client
- **SQL injection prevention**: Add EscapeLikeWildcard utility to escape special characters in LIKE queries
- **HTTP security**: Configure server timeouts and add security headers middleware
- **Rate limiting**: Refactor to support configurable duration and per-endpoint rate limits for auth routes
- **Error handling**: Standardize error responses using HandleError and proper error types
This commit is contained in:
lafay
2026-04-30 12:26:25 +08:00
parent 67a5660952
commit b2b55ea52d
24 changed files with 517 additions and 80 deletions

View File

@@ -8,6 +8,7 @@ import (
"strings"
"time"
apperrors "with_you/internal/errors"
"with_you/internal/cache"
"with_you/internal/dto"
"with_you/internal/model"
@@ -128,7 +129,16 @@ func (s *VoteService) reviewVotePostAsync(postID, userID, title, content string,
}
var authorID uint
fmt.Sscanf(userID, "%d", &authorID)
if _, err := fmt.Sscanf(userID, "%d", &authorID); err != nil {
log.Printf("[WARN] Invalid userID format in vote moderation: %q, err: %v", userID, err)
if err := s.updateModerationStatusWithRetry(postID, model.PostStatusPublished, "", "system"); err != nil {
log.Printf("[WARN] Failed to publish vote post %s after invalid userID: %v", postID, err)
} else {
cache.InvalidatePostDetail(s.cache, postID)
cache.InvalidatePostList(s.cache)
}
return
}
result := &hook.ModerationResult{}
s.hookManager.TriggerWithMetadata(context.Background(), hook.HookPostPreModerate, authorID, &hook.PostModerateHookData{
@@ -333,7 +343,7 @@ func (s *VoteService) UpdateVoteOption(ctx context.Context, postID, optionID, us
// 验证用户是否为帖子作者
if post.UserID != userID {
return errors.New("只有帖子作者可以更新投票选项")
return apperrors.ErrForbidden
}
// 调用voteRepo.UpdateOption