Files
AetherForge/server/internal/api/recon_canary_hub.go
AetherForge 49c24e611c
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add recon form fingerprint library and SSRF canary mode.
Score crawl inputs by SSRF-prone field names and register ping-back canaries for operator paste confirmation.
2026-06-07 12:23:11 -07:00

39 lines
1.3 KiB
Go

package api
import ("sync"; "time"; "crypto-miner-server/internal/recon")
type ReconCanaryHub struct { mu sync.RWMutex; byID map[string]*recon.SSRFCanaryInfo }
func NewReconCanaryHub() *ReconCanaryHub { return &ReconCanaryHub{byID: map[string]*recon.SSRFCanaryInfo{}} }
func (h *ReconCanaryHub) Register(id string, info *recon.SSRFCanaryInfo) {
if h == nil || info == nil { return }
h.mu.Lock(); defer h.mu.Unlock(); cp := *info; h.byID[id] = &cp
}
func (h *ReconCanaryHub) Get(id string) *recon.SSRFCanaryInfo {
if h == nil { return nil }
h.mu.RLock(); defer h.mu.RUnlock()
if x := h.byID[id]; x != nil { cp := *x; return &cp }
return nil
}
func (h *ReconCanaryHub) MarkHit(id string) bool {
if h == nil { return false }
h.mu.Lock(); defer h.mu.Unlock()
x, ok := h.byID[id]; if !ok { return false }
if x.Status == "confirmed" { return true }
now := time.Now().UTC(); x.Status = "confirmed"; x.HitAt = &now; return true
}
func (h *ReconCanaryHub) UpdatePasteField(id, name, id2 string) {
if h == nil { return }
h.mu.Lock(); defer h.mu.Unlock()
if x := h.byID[id]; x != nil { x.PasteFieldName, x.PasteFieldID = name, id2 }
}
func BroadcastReconCanaryHit(hub *WSHub, scanID string) {
if hub == nil { return }
hub.broadcastDashboard(Message{Type: "recon_canary_hit", Payload: mustMarshal(map[string]interface{}{"scan_id": scanID, "status": "confirmed"})})
}