mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-04 09:58:22 +08:00
fix(security): block SSRF via custom AI model URL
Apply security.ValidateURL() to custom_api_url in PUT /api/models before storing — blocks private IPs, cloud metadata endpoints, and localhost. Replace plain http.Client in mcp/config.go with security.SafeHTTPClient() for defense-in-depth (DialContext blocks private IPs, CheckRedirect validates targets). Add SSRF warning to WithHTTPClient() docs.
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"nofx/crypto"
|
||||
"nofx/logger"
|
||||
"nofx/manager"
|
||||
"nofx/security"
|
||||
"nofx/market"
|
||||
"nofx/provider/alpaca"
|
||||
"nofx/provider/coinank/coinank_api"
|
||||
@@ -1770,6 +1771,15 @@ func (s *Server) handleUpdateModelConfigs(c *gin.Context) {
|
||||
// Update each model's configuration and track traders that need reload
|
||||
tradersToReload := make(map[string]bool)
|
||||
for modelID, modelData := range req.Models {
|
||||
// SSRF protection: validate custom_api_url before storing
|
||||
if modelData.CustomAPIURL != "" {
|
||||
cleanURL := strings.TrimSuffix(modelData.CustomAPIURL, "#")
|
||||
if err := security.ValidateURL(cleanURL); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Invalid custom_api_url for model %s: %s", modelID, err.Error())})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Find traders using this AI model BEFORE updating
|
||||
traders, _ := s.store.Trader().ListByAIModelID(userID, modelID)
|
||||
for _, t := range traders {
|
||||
|
||||
Reference in New Issue
Block a user