From 3b3e9d8d84ec5dbc0947d4811705b1632b2dabe5 Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Mon, 20 Jul 2026 15:28:26 -0400 Subject: [PATCH 1/4] refactor(backend/eventprocessing): remove unnecessary internal deactivate endpoint --- .../dto/correlation_rule_internal.go | 9 --- .../handler/correlation_rule_internal.go | 65 ------------------- backend/modules/eventprocessing/routes.go | 5 -- 3 files changed, 79 deletions(-) delete mode 100644 backend/modules/eventprocessing/dto/correlation_rule_internal.go delete mode 100644 backend/modules/eventprocessing/handler/correlation_rule_internal.go diff --git a/backend/modules/eventprocessing/dto/correlation_rule_internal.go b/backend/modules/eventprocessing/dto/correlation_rule_internal.go deleted file mode 100644 index 0976adcb4..000000000 --- a/backend/modules/eventprocessing/dto/correlation_rule_internal.go +++ /dev/null @@ -1,9 +0,0 @@ -package dto - -type InternalDeactivateRuleRequest struct { - RuleName string `json:"ruleName" binding:"required"` -} - -type InternalDeactivateRuleResponse struct { - Changed bool `json:"changed"` -} diff --git a/backend/modules/eventprocessing/handler/correlation_rule_internal.go b/backend/modules/eventprocessing/handler/correlation_rule_internal.go deleted file mode 100644 index fb85c06cd..000000000 --- a/backend/modules/eventprocessing/handler/correlation_rule_internal.go +++ /dev/null @@ -1,65 +0,0 @@ -package handler - -import ( - "net/http" - "strings" - - "github.com/gin-gonic/gin" - "github.com/utmstack/utmstack/backend/modules/eventprocessing/dto" -) - -// @Summary Deactivate a correlation rule by name (internal) -// @Tags Correlation Rules -// @Accept json -// @Produce json -// @Param input body dto.InternalDeactivateRuleRequest true "Rule to deactivate" -// @Success 200 {object} dto.InternalDeactivateRuleResponse -// @Failure 400 {object} map[string]string -// @Failure 404 {object} map[string]string -// @Failure 500 {object} map[string]string -// @Router /eventprocessing/internal/correlation-rule/deactivate [put] -func (h *CorrelationRuleHandler) InternalDeactivate(c *gin.Context) { - var req dto.InternalDeactivateRuleRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - ctx := c.Request.Context() - - // RuleName filtering in List is a case-insensitive partial match, so the - // exact (case-insensitive) match is re-applied here to avoid disabling - // unrelated rules whose name merely contains the requested substring. - result, err := h.usecase.List(ctx, dto.CorrelationRuleFilters{RuleName: req.RuleName}) - if err != nil { - writeCorrelationError(c, err) - return - } - - var matches []dto.CorrelationRuleResponse - for _, r := range result.Items { - if strings.EqualFold(r.RuleName, req.RuleName) { - matches = append(matches, r) - } - } - if len(matches) == 0 { - c.JSON(http.StatusNotFound, gin.H{"error": "correlation rule not found"}) - return - } - - // Two or more rules sharing an exact display name is an accepted edge - // case (see design's Open Questions) — disable every exact match. - changed := false - for _, r := range matches { - if !r.RuleActive { - continue - } - if err := h.usecase.SetActive(ctx, r.RelPath, false); err != nil { - writeCorrelationError(c, err) - return - } - changed = true - } - - c.JSON(http.StatusOK, dto.InternalDeactivateRuleResponse{Changed: changed}) -} diff --git a/backend/modules/eventprocessing/routes.go b/backend/modules/eventprocessing/routes.go index 6fcd6b9bb..863464132 100644 --- a/backend/modules/eventprocessing/routes.go +++ b/backend/modules/eventprocessing/routes.go @@ -38,11 +38,6 @@ func RegisterRoutes(api *gin.RouterGroup, m *Module, userAuth gin.HandlerFunc) { cr.GET("/find", read, crh.GetByID) cr.DELETE("", write, crh.Delete) - // Internal-only: rule-flood-guard plugin disables a rule it identified as - // flooding the alerts list, by display name. - icr := g.Group("/internal/correlation-rule", middleware.RequireInternal()) - icr.PUT("/deactivate", crh.InternalDeactivate) - // Filters (file-backed, pipeline: YAML). Identity = relPath query param. f := g.Group("/filters") f.POST("", write, fh.Create) From 175c67e7463c03b9cf2dccc67c8c49d1cd6eb5c6 Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Mon, 20 Jul 2026 15:28:43 -0400 Subject: [PATCH 2/4] fix(backend/eventprocessing): make rule activate-deactivate return an authoritative changed flag --- .../eventprocessing/connectors/usecase.go | 2 +- .../eventprocessing/handler/correlation_rule.go | 6 +++--- .../eventprocessing/usecase/correlation_rule.go | 10 ++++++---- .../eventprocessing/usecase/rule_bootstrap.go | 4 ++-- .../eventprocessing/usecase/rule_store.go | 17 ++++++++++++----- backend/modules/mcp/tools_eventprocessing.go | 5 +++-- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/backend/modules/eventprocessing/connectors/usecase.go b/backend/modules/eventprocessing/connectors/usecase.go index d15b1c410..9c6638ea9 100644 --- a/backend/modules/eventprocessing/connectors/usecase.go +++ b/backend/modules/eventprocessing/connectors/usecase.go @@ -38,7 +38,7 @@ type CorrelationRuleUsecase interface { GetByRelPath(ctx context.Context, relPath string) (*dto.CorrelationRuleResponse, error) List(ctx context.Context, filters dto.CorrelationRuleFilters) (*ListResult[dto.CorrelationRuleResponse], error) Delete(ctx context.Context, relPath string) error - SetActive(ctx context.Context, relPath string, active bool) error + SetActive(ctx context.Context, relPath string, active bool) (bool, error) FindDistinctPropertyValues(ctx context.Context, prop, value string) ([]string, error) } diff --git a/backend/modules/eventprocessing/handler/correlation_rule.go b/backend/modules/eventprocessing/handler/correlation_rule.go index a7e8af93b..c26a3780b 100644 --- a/backend/modules/eventprocessing/handler/correlation_rule.go +++ b/backend/modules/eventprocessing/handler/correlation_rule.go @@ -123,7 +123,7 @@ func (h *CorrelationRuleHandler) Update(c *gin.Context) { // @Produce json // @Param id query int64 true "Correlation rule ID" // @Param active query bool true "true to activate, false to deactivate" -// @Success 204 "No content" +// @Success 200 {object} map[string]bool "changed: true if this call actually flipped the rule's state" // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /correlation-rule/activate-deactivate [put] @@ -140,13 +140,13 @@ func (h *CorrelationRuleHandler) ActivateDeactivate(c *gin.Context) { return } - err = h.usecase.SetActive(c.Request.Context(), relPath, active) + changed, err := h.usecase.SetActive(c.Request.Context(), relPath, active) audit.Record(c, audit_connectors.Event{Action: "correlation_rule.activate"}, audit_domain.CORRELATION_RULE_UPDATE_ATTEMPT, audit_domain.CORRELATION_RULE_UPDATE_SUCCESS, err) if err != nil { writeCorrelationError(c, err) return } - c.Status(http.StatusNoContent) + c.JSON(http.StatusOK, gin.H{"changed": changed}) } // @Summary List correlation rules by filters diff --git a/backend/modules/eventprocessing/usecase/correlation_rule.go b/backend/modules/eventprocessing/usecase/correlation_rule.go index 326b74c92..9ebfee05d 100644 --- a/backend/modules/eventprocessing/usecase/correlation_rule.go +++ b/backend/modules/eventprocessing/usecase/correlation_rule.go @@ -46,7 +46,7 @@ func (u *correlationRuleUsecase) Create(_ context.Context, req dto.CreateCorrela return mapStoreErr(err) } if !req.RuleActive { - _ = u.store.SetEnabled(created.RelPath, false) + _, _ = u.store.SetEnabled(created.RelPath, false) } return nil } @@ -152,7 +152,8 @@ func (u *correlationRuleUsecase) Update(_ context.Context, req dto.UpdateCorrela return mapStoreErr(err) } // Reconcile the active state (the store keeps it in the filename). - return mapStoreErr(u.store.SetEnabled(req.RelPath, req.RuleActive)) + _, err := u.store.SetEnabled(req.RelPath, req.RuleActive) + return mapStoreErr(err) } func (u *correlationRuleUsecase) GetByRelPath(_ context.Context, relPath string) (*dto.CorrelationRuleResponse, error) { @@ -193,8 +194,9 @@ func (u *correlationRuleUsecase) Delete(_ context.Context, relPath string) error return mapStoreErr(u.store.Delete(relPath)) } -func (u *correlationRuleUsecase) SetActive(_ context.Context, relPath string, active bool) error { - return mapStoreErr(u.store.SetEnabled(relPath, active)) +func (u *correlationRuleUsecase) SetActive(_ context.Context, relPath string, active bool) (bool, error) { + changed, err := u.store.SetEnabled(relPath, active) + return changed, mapStoreErr(err) } func (u *correlationRuleUsecase) FindDistinctPropertyValues(_ context.Context, prop, value string) ([]string, error) { diff --git a/backend/modules/eventprocessing/usecase/rule_bootstrap.go b/backend/modules/eventprocessing/usecase/rule_bootstrap.go index 00a6fa09a..aaea58272 100644 --- a/backend/modules/eventprocessing/usecase/rule_bootstrap.go +++ b/backend/modules/eventprocessing/usecase/rule_bootstrap.go @@ -239,7 +239,7 @@ func (b *RuleBootstrap) migrateLegacyRules(ctx context.Context) error { // System rules ship as files; only carry over a disable. if !row.RuleActive { if relPath, ok := systemByName[row.RuleName]; ok { - if err := b.store.SetEnabled(relPath, false); err != nil { + if _, err := b.store.SetEnabled(relPath, false); err != nil { _ = catcher.Error("eventprocessing: reconciling disabled system rule failed", err, map[string]any{"rule": row.RuleName}) failed++ @@ -262,7 +262,7 @@ func (b *RuleBootstrap) migrateLegacyRules(ctx context.Context) error { continue } if !row.RuleActive { - if err := b.store.SetEnabled(created.RelPath, false); err != nil { + if _, err := b.store.SetEnabled(created.RelPath, false); err != nil { _ = catcher.Error("eventprocessing: disabling migrated user rule failed", err, map[string]any{"rule": row.RuleName}) failed++ diff --git a/backend/modules/eventprocessing/usecase/rule_store.go b/backend/modules/eventprocessing/usecase/rule_store.go index 937c1ee25..f9863bd3a 100644 --- a/backend/modules/eventprocessing/usecase/rule_store.go +++ b/backend/modules/eventprocessing/usecase/rule_store.go @@ -345,23 +345,30 @@ func (s *RuleStore) Delete(relPath string) error { // (disabledRules, keyed by ruleIdentity) rather than on the file itself, so it // works identically for system and user rules (disabling is the one mutation // allowed on a system rule) and never touches file content. -func (s *RuleStore) SetEnabled(relPath string, enabled bool) error { +// +// The returned bool is the authoritative "did this call actually flip the +// state" signal: false when the rule was already in the requested state (a +// no-op) or when the call failed, true only when this call performed the +// transition. Callers that need to know whether THEY caused a state change +// (e.g. to decide whether to notify) must use this return value rather than +// re-deriving it from a value read before the call. +func (s *RuleStore) SetEnabled(relPath string, enabled bool) (bool, error) { s.mu.Lock() defer s.mu.Unlock() sr, ok := s.index[relPath] if !ok { - return ErrRuleNotFound + return false, ErrRuleNotFound } if sr.enabled == enabled { - return nil + return false, nil } if err := s.writer.SetRuleDisabled(ruleIdentity(relPath), !enabled); err != nil { - return err + return false, err } sr.enabled = enabled - return nil + return true, nil } // DistinctValues returns the distinct values of a rule property, optionally diff --git a/backend/modules/mcp/tools_eventprocessing.go b/backend/modules/mcp/tools_eventprocessing.go index c99701d0c..76a5cbdba 100644 --- a/backend/modules/mcp/tools_eventprocessing.go +++ b/backend/modules/mcp/tools_eventprocessing.go @@ -247,10 +247,11 @@ func registerEPCorrelationRules(m *Module) { Annotations: &mcp.ToolAnnotations{IdempotentHint: true}, }, Gate{Permission: "eventprocessing.write"}, func(ctx context.Context, _ *authz.Actor, in epRuleSetActiveInput) (any, error) { - if err := uc.SetActive(ctx, in.RelPath, in.Active); err != nil { + changed, err := uc.SetActive(ctx, in.RelPath, in.Active) + if err != nil { return nil, err } - return map[string]any{"rel_path": in.RelPath, "active": in.Active}, nil + return map[string]any{"rel_path": in.RelPath, "active": in.Active, "changed": changed}, nil }) Add(m, &mcp.Tool{ From e8ee91b3a2f1135ca0792021a463963110abd90e Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Mon, 20 Jul 2026 15:28:53 -0400 Subject: [PATCH 3/4] fix(plugins/rule-flood-guard): consume existing endpoints, fix collision and notification-loss bugs, auto-create config --- plugins/rule-flood-guard/README.md | 2 +- plugins/rule-flood-guard/backend.go | 92 +++++++++++++++++++++++++---- plugins/rule-flood-guard/config.go | 43 ++++++++++++++ plugins/rule-flood-guard/guard.go | 9 --- 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/plugins/rule-flood-guard/README.md b/plugins/rule-flood-guard/README.md index edc5eeb37..cbf573cc9 100644 --- a/plugins/rule-flood-guard/README.md +++ b/plugins/rule-flood-guard/README.md @@ -30,6 +30,6 @@ plugins: | `windowHours` | `24` | Time window used to count alerts. | | `intervalSeconds` | `300` | How often the guard checks. | -If the file doesn't exist, the guard just runs with these defaults. +If the file doesn't exist, the plugin creates it with these defaults the first time it starts — it never overwrites a file that's already there. diff --git a/plugins/rule-flood-guard/backend.go b/plugins/rule-flood-guard/backend.go index 74fca91ed..0e990d902 100644 --- a/plugins/rule-flood-guard/backend.go +++ b/plugins/rule-flood-guard/backend.go @@ -7,6 +7,8 @@ import ( "fmt" "io" "net/http" + "net/url" + "strings" "time" "github.com/threatwinds/go-sdk/catcher" @@ -28,26 +30,92 @@ func newBackendClient(baseURL, internalKey string) *backendClient { } } -type deactivateRequest struct { - RuleName string `json:"ruleName"` +type ruleSearchResult struct { + RelPath string `json:"relPath"` + Name string `json:"name"` + RuleActive bool `json:"ruleActive"` } -type deactivateResponse struct { +func (c *backendClient) resolveRule(ctx context.Context, ruleName string) ([]ruleSearchResult, error) { + endpoint := c.baseURL + "/api/v1/eventprocessing/correlation-rule/search-by-filters?ruleName=" + url.QueryEscape(ruleName) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) + if err != nil { + return nil, err + } + req.Header.Set("X-Internal-Key", c.internalKey) + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, err + } + defer func() { _ = resp.Body.Close() }() + + if resp.StatusCode >= 400 { + body, _ := io.ReadAll(resp.Body) + return nil, catcher.Error("search-by-filters call returned error status", nil, map[string]any{ + "status": resp.StatusCode, "body": string(body), "ruleName": ruleName, + }) + } + + var candidates []ruleSearchResult + if err := json.NewDecoder(resp.Body).Decode(&candidates); err != nil { + return nil, err + } + + var matches []ruleSearchResult + for i := range candidates { + if strings.EqualFold(candidates[i].Name, ruleName) { + matches = append(matches, candidates[i]) + } + } + if len(matches) > 1 { + catcher.Warn("rule-flood-guard: ambiguous rule name collision, disabling every exact match", map[string]any{ + "ruleName": ruleName, "matches": len(matches), + }) + } + return matches, nil +} + +type activateDeactivateResponse struct { Changed bool `json:"changed"` } func (c *backendClient) Deactivate(ctx context.Context, ruleName string) (bool, error) { - payload, err := json.Marshal(deactivateRequest{RuleName: ruleName}) + matches, err := c.resolveRule(ctx, ruleName) if err != nil { return false, err } - url := c.baseURL + "/api/v1/eventprocessing/internal/correlation-rule/deactivate" - req, err := http.NewRequestWithContext(ctx, http.MethodPut, url, bytes.NewReader(payload)) + if len(matches) == 0 { + return false, nil + } + + changed := false + for i := range matches { + if !matches[i].RuleActive { + continue + } + ruleChanged, err := c.deactivateOne(ctx, ruleName, matches[i].RelPath) + if err != nil { + return changed, err + } + if ruleChanged { + changed = true + } + } + catcher.Info("rule-flood-guard: exact-match rules processed for deactivation", map[string]any{ + "ruleName": ruleName, "matches": len(matches), "changed": changed, + }) + return changed, nil +} + +func (c *backendClient) deactivateOne(ctx context.Context, ruleName, relPath string) (bool, error) { + endpoint := fmt.Sprintf("%s/api/v1/eventprocessing/correlation-rule/activate-deactivate?relPath=%s&active=false", + c.baseURL, url.QueryEscape(relPath)) + req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint, nil) if err != nil { return false, err } req.Header.Set("X-Internal-Key", c.internalKey) - req.Header.Set("Content-Type", "application/json") resp, err := c.httpClient.Do(req) if err != nil { @@ -57,16 +125,16 @@ func (c *backendClient) Deactivate(ctx context.Context, ruleName string) (bool, if resp.StatusCode >= 400 { body, _ := io.ReadAll(resp.Body) - return false, catcher.Error("deactivate call returned error status", nil, map[string]any{ - "status": resp.StatusCode, "body": string(body), "ruleName": ruleName, + return false, catcher.Error("activate-deactivate call returned error status", nil, map[string]any{ + "status": resp.StatusCode, "body": string(body), "ruleName": ruleName, "relPath": relPath, }) } - var out deactivateResponse - if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { + var result activateDeactivateResponse + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return false, err } - return out.Changed, nil + return result.Changed, nil } type notifyRequest struct { diff --git a/plugins/rule-flood-guard/config.go b/plugins/rule-flood-guard/config.go index 6a4754450..aad594b49 100644 --- a/plugins/rule-flood-guard/config.go +++ b/plugins/rule-flood-guard/config.go @@ -71,6 +71,48 @@ func applyFileConfig(base Config, fc fileConfig) Config { return base } +func writeDefaultConfigIfMissing(path string) { + if _, err := os.Stat(path); err == nil { + return + } else if !os.IsNotExist(err) { + _ = catcher.Error("rule-flood-guard: failed to stat config file, skipping default creation", err, map[string]any{"process": processName, "file": path}) + return + } + + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0o755); err != nil { + _ = catcher.Error("rule-flood-guard: failed to create pipeline dir for default config", err, map[string]any{"process": processName, "dir": dir}) + return + } + + knobs := defaultKnobs() + pf := pluginsFile{Plugins: map[string]fileConfig{ + pluginKey: { + Enabled: &knobs.Enabled, + Threshold: &knobs.Threshold, + WindowHours: &knobs.WindowHours, + IntervalSeconds: &knobs.IntervalSeconds, + }, + }} + data, err := yaml.Marshal(pf) + if err != nil { + _ = catcher.Error("rule-flood-guard: failed to marshal default config", err, map[string]any{"process": processName}) + return + } + + tmp := path + ".tmp" + if err := os.WriteFile(tmp, data, 0o600); err != nil { + _ = catcher.Error("rule-flood-guard: failed to write default config file", err, map[string]any{"process": processName, "file": path}) + return + } + if err := os.Rename(tmp, path); err != nil { + _ = catcher.Error("rule-flood-guard: failed to finalize default config file", err, map[string]any{"process": processName, "file": path}) + return + } + + catcher.Info("rule-flood-guard: created default config file", map[string]any{"process": processName, "file": path}) +} + func loadKnobsFromFile(path string) (Config, error) { knobs := defaultKnobs() @@ -127,6 +169,7 @@ func loadConfig() (Config, string) { } path := filepath.Join(pipelineDir, configFileName) + writeDefaultConfigIfMissing(path) knobs, err := loadKnobsFromFile(path) if err != nil { _ = catcher.Error("rule-flood-guard: failed to read config file, using defaults", err, map[string]any{"process": processName, "file": path}) diff --git a/plugins/rule-flood-guard/guard.go b/plugins/rule-flood-guard/guard.go index dddd24c2f..71c32c650 100644 --- a/plugins/rule-flood-guard/guard.go +++ b/plugins/rule-flood-guard/guard.go @@ -14,8 +14,6 @@ type disableNotifier interface { Notify(ctx context.Context, message string) error } -// getConfig is satisfied by (*configHolder).Get — kept as its own function -// type so guard.go doesn't need to know about configHolder directly. type getConfig func() Config func evaluateOnce(ctx context.Context, search searchFunc, client disableNotifier, getCfg getConfig) { @@ -40,11 +38,8 @@ func evaluateOnce(ctx context.Context, search searchFunc, client disableNotifier _ = catcher.Error("rule-flood-guard: failed to deactivate rule", err, map[string]any{ "ruleName": b.RuleName, "count": b.Count, }) - continue } if !changed { - // Already disabled (manually, or by a previous/overlapping - // cycle) — idempotent no-op, no duplicate notification. continue } @@ -57,10 +52,6 @@ func evaluateOnce(ctx context.Context, search searchFunc, client disableNotifier } } -// runLoop re-reads getCfg() on every cycle (both for the enabled/threshold/ -// window checks inside evaluateOnce and for the tick interval itself via -// time.Timer.Reset below), so a hot-reloaded config file — including a -// changed IntervalSeconds — takes effect without restarting the plugin. func runLoop(ctx context.Context, search searchFunc, client disableNotifier, getCfg getConfig) { timer := time.NewTimer(getCfg().tickInterval()) defer timer.Stop() From 0b5dfbfde35919b7ec6722c283956fdd25456c63 Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Mon, 20 Jul 2026 15:42:32 -0400 Subject: [PATCH 4/4] fix: update go dependencies to latest versions --- backend/go.mod | 4 ++-- backend/go.sum | 8 ++++---- plugins/crowdstrike/go.mod | 2 +- plugins/crowdstrike/go.sum | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/go.mod b/backend/go.mod index b001b6170..e096db513 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -11,7 +11,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.44.1 github.com/coder/websocket v1.8.15 github.com/crewjam/saml v0.5.1 - github.com/crowdstrike/gofalcon v0.21.0 + github.com/crowdstrike/gofalcon v0.21.1 github.com/gin-contrib/cors v1.7.7 github.com/gin-gonic/gin v1.12.0 github.com/go-pdf/fpdf v0.9.0 @@ -131,7 +131,7 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.1 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect - go.mongodb.org/mongo-driver v1.14.0 // indirect + go.mongodb.org/mongo-driver v1.17.7 // indirect go.mongodb.org/mongo-driver/v2 v2.6.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect diff --git a/backend/go.sum b/backend/go.sum index 9332c70b8..3d0c1f23f 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -110,8 +110,8 @@ github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmC github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crewjam/saml v0.5.1 h1:g+mfp0CrLuLRZCK793PgJcZeg5dS/0CDwoeAX2zcwNI= github.com/crewjam/saml v0.5.1/go.mod h1:r0fDkmFe5URDgPrmtH0IYokva6fac3AUdstiPhyEolQ= -github.com/crowdstrike/gofalcon v0.21.0 h1:vMHpMtzidy07VxhQHMRH6uzHsOL3Efk6y829efDdOUQ= -github.com/crowdstrike/gofalcon v0.21.0/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8= +github.com/crowdstrike/gofalcon v0.21.1 h1:+n0tbAPCxsZn8q9Z+ss6c09s2/EGS/tqvz8/uE5rlrM= +github.com/crowdstrike/gofalcon v0.21.1/go.mod h1:G3XfEBnyN68Ew/GFXbdy48k11ghlLRAFSdDURyWUtX4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -389,8 +389,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT0 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.einride.tech/aip v0.83.0 h1:TI21IdeOnLTwZEJ3BxtImIZk6bsN2Q+sd0x99SLiQ+M= go.einride.tech/aip v0.83.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.17.7 h1:a9w+U3Vt67eYzcfq3k/OAv284/uUUkL0uP75VE5rCOU= +go.mongodb.org/mongo-driver v1.17.7/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.mongodb.org/mongo-driver/v2 v2.6.0 h1:b9sJOYrkmt4l8bY43ZenFBcPlhYIjaOfYHLtbB/5qi8= go.mongodb.org/mongo-driver/v2 v2.6.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= diff --git a/plugins/crowdstrike/go.mod b/plugins/crowdstrike/go.mod index 82d71cf45..1f6696116 100644 --- a/plugins/crowdstrike/go.mod +++ b/plugins/crowdstrike/go.mod @@ -3,7 +3,7 @@ module github.com/utmstack/UTMStack/plugins/crowdstrike go 1.25.5 require ( - github.com/crowdstrike/gofalcon v0.21.0 + github.com/crowdstrike/gofalcon v0.21.1 github.com/fsnotify/fsnotify v1.10.1 github.com/google/uuid v1.6.0 github.com/threatwinds/go-sdk v1.1.26 diff --git a/plugins/crowdstrike/go.sum b/plugins/crowdstrike/go.sum index 8eb755fe4..1f867d200 100644 --- a/plugins/crowdstrike/go.sum +++ b/plugins/crowdstrike/go.sum @@ -16,8 +16,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI= github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg= -github.com/crowdstrike/gofalcon v0.21.0 h1:vMHpMtzidy07VxhQHMRH6uzHsOL3Efk6y829efDdOUQ= -github.com/crowdstrike/gofalcon v0.21.0/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8= +github.com/crowdstrike/gofalcon v0.21.1 h1:+n0tbAPCxsZn8q9Z+ss6c09s2/EGS/tqvz8/uE5rlrM= +github.com/crowdstrike/gofalcon v0.21.1/go.mod h1:G3XfEBnyN68Ew/GFXbdy48k11ghlLRAFSdDURyWUtX4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=