From 1d0d6f7afdefb10c2d0665e14741a777a10e5d2c Mon Sep 17 00:00:00 2001 From: shinchan-zhai Date: Mon, 23 Mar 2026 10:46:22 +0800 Subject: [PATCH] security: sanitize internal error messages in API responses - handler_trader.go: remove loadErr.Error() from 500 responses (2 instances) - handler_ai_cost.go: replace err.Error() with generic message, add logging - Internal errors now logged server-side, not exposed to clients --- api/handler_ai_cost.go | 4 +++- api/handler_trader.go | 5 +++-- nofxi-tasks.md | 8 ++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/api/handler_ai_cost.go b/api/handler_ai_cost.go index 598cef55..e7123ce6 100644 --- a/api/handler_ai_cost.go +++ b/api/handler_ai_cost.go @@ -2,6 +2,7 @@ package api import ( "net/http" + "nofx/logger" "github.com/gin-gonic/gin" ) @@ -18,7 +19,8 @@ func (s *Server) handleGetAICosts(c *gin.Context) { charges, total, err := s.store.AICharge().GetCharges(traderID, period) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + logger.Infof("❌ Failed to get AI charges for trader %s: %v", traderID, err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve AI cost data"}) return } diff --git a/api/handler_trader.go b/api/handler_trader.go index f8e345a1..8dfbb07f 100644 --- a/api/handler_trader.go +++ b/api/handler_trader.go @@ -495,7 +495,7 @@ func (s *Server) handleStartTrader(c *gin.Context) { logger.Infof("🔄 Loading trader %s from database...", traderID) if loadErr := s.traderManager.LoadUserTradersFromStore(s.store, userID); loadErr != nil { logger.Infof("❌ Failed to load user traders: %v", loadErr) - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load trader: " + loadErr.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load trader configuration"}) return } @@ -530,7 +530,8 @@ func (s *Server) handleStartTrader(c *gin.Context) { } // Check if there's a specific load error if loadErr := s.traderManager.GetLoadError(traderID); loadErr != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load trader: " + loadErr.Error()}) + logger.Infof("❌ Trader %s load error: %v", traderID, loadErr) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load trader, please check configuration"}) return } c.JSON(http.StatusNotFound, gin.H{"error": "Failed to load trader, please check AI model, exchange and strategy configuration"}) diff --git a/nofxi-tasks.md b/nofxi-tasks.md index e1bb6476..a8ce122d 100644 --- a/nofxi-tasks.md +++ b/nofxi-tasks.md @@ -44,11 +44,15 @@ ## Pending ### Security -- [PENDING] Investigate GitHub Dependabot's 21 reported vulnerabilities (13 high, 7 moderate, 1 low) +- [DONE] Upgrade go-ethereum v1.16.7→v1.16.8 (fixes 3 vulns: GO-2026-4508, GO-2026-4314, GO-2026-4315) +- [DONE] Upgrade golang-jwt/jwt v5.2.0→v5.2.2 (fixes GO-2025-3553 memory alloc DoS) +- [DONE] Upgrade quic-go v0.54.0→v0.57.0 (fixes GO-2025-4233 HTTP/3 QPACK DoS) +- [PENDING] 3 stdlib vulns remain (GO-2026-4599/4600/4601) — need Go 1.26.1 upgrade (currently on 1.26.0) +- [PENDING] GitHub Dependabot still reports 21 vulns — some may be transitive/test-only, needs further triage ### Code Quality +- [DONE] Extract WelcomeScreen, ChatMessages, ChatInput from AgentChatPage (825→480 lines) - [PENDING] `context.Background()` used in ~69 exchange/trader calls — should propagate request context for proper cancellation (partially done: kline handlers fixed, trader/exchange calls remain) -- [PENDING] `AgentChatPage.tsx` is 825 lines — could still extract WelcomeScreen and ChatMessages components ### Performance - [PENDING] `gatherContext` in agent.go iterates all traders and positions on every message — consider caching (low priority: only triggered per user message)