mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-07 04:50:57 +08:00
security+reliability: remove public decrypt endpoint, add panic recovery for goroutines
Security: - Remove /api/crypto/decrypt from public routes. The endpoint allowed anyone to decrypt ciphertext without authentication. Internal callers (exchange/model handlers) use the service directly and are behind auth. Reliability: - Add safe.Go / safe.GoNamed panic recovery wrapper (safe/go.go). Previously 31 goroutines had zero recover() calls — a single panic in any trader goroutine would crash the entire process. - Apply safe.GoNamed to all trader launch paths: - StartAll, RestoreRunning, LoadSingleTrader auto-start - API handler start/restart endpoints - Panics are now logged with full stack traces instead of crashing.
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"nofx/logger"
|
||||
"nofx/safe"
|
||||
"nofx/store"
|
||||
"nofx/trader"
|
||||
"nofx/trader/aster"
|
||||
@@ -418,12 +419,12 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
|
||||
// If trader was running before, restart it with new config
|
||||
if wasRunning {
|
||||
if reloadedTrader, getErr := s.traderManager.GetTrader(traderID); getErr == nil {
|
||||
go func() {
|
||||
safe.GoNamed("trader-restart-"+traderID, func() {
|
||||
logger.Infof("▶️ Restarting trader %s with new config...", traderID)
|
||||
if runErr := reloadedTrader.Run(); runErr != nil {
|
||||
logger.Infof("❌ Trader %s runtime error: %v", traderID, runErr)
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,12 +538,12 @@ func (s *Server) handleStartTrader(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Start trader
|
||||
go func() {
|
||||
safe.GoNamed("trader-start-"+traderID, func() {
|
||||
logger.Infof("▶️ Starting trader %s (%s)", traderID, trader.GetName())
|
||||
if err := trader.Run(); err != nil {
|
||||
logger.Infof("❌ Trader %s runtime error: %v", trader.GetName(), err)
|
||||
}
|
||||
}()
|
||||
})
|
||||
|
||||
// Update running status in database
|
||||
err = s.store.Trader().UpdateStatus(userID, traderID, true)
|
||||
|
||||
@@ -126,10 +126,11 @@ func (s *Server) setupRoutes() {
|
||||
api.POST("/wallet/validate", s.handleWalletValidate)
|
||||
api.POST("/wallet/generate", s.handleWalletGenerate)
|
||||
|
||||
// Crypto related endpoints (no authentication required, not exposed to bot)
|
||||
// Crypto public key & config (needed by frontend before login for transport encryption)
|
||||
api.GET("/crypto/config", s.cryptoHandler.HandleGetCryptoConfig)
|
||||
api.GET("/crypto/public-key", s.cryptoHandler.HandleGetPublicKey)
|
||||
api.POST("/crypto/decrypt", s.cryptoHandler.HandleDecryptSensitiveData)
|
||||
// NOTE: /crypto/decrypt moved behind auth — the public endpoint was a security risk
|
||||
// (allowed anyone to decrypt captured ciphertext without authentication)
|
||||
|
||||
// Public competition data (no authentication required)
|
||||
s.route(api, "GET", "/traders", "Public trader list", s.handlePublicTraderList)
|
||||
|
||||
Reference in New Issue
Block a user