mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [ ] QA'd all new/changed functionality manually
75 lines
2 KiB
Go
75 lines
2 KiB
Go
package webhooks
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/fleetdm/fleet/v4/server"
|
|
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
|
)
|
|
|
|
// TriggerVulnerabilitiesWebhook performs the webhook requests for vulnerabilities.
|
|
func TriggerVulnerabilitiesWebhook(
|
|
ctx context.Context,
|
|
ds fleet.Datastore,
|
|
logger *slog.Logger,
|
|
args VulnArgs,
|
|
mapper VulnMapper,
|
|
) error {
|
|
vulnConfig := args.AppConfig.WebhookSettings.VulnerabilitiesWebhook
|
|
|
|
if !vulnConfig.Enable {
|
|
return nil
|
|
}
|
|
|
|
logger.DebugContext(ctx, "vulnerability webhook triggered", "recent_vulns", len(args.Vulnerablities))
|
|
|
|
serverURL, err := url.Parse(args.AppConfig.ServerSettings.ServerURL)
|
|
if err != nil {
|
|
return ctxerr.Wrap(ctx, err, "invalid server url")
|
|
}
|
|
|
|
targetURL := vulnConfig.DestinationURL
|
|
batchSize := vulnConfig.HostBatchSize
|
|
|
|
cveGrouped := make(map[string][]uint)
|
|
for _, v := range args.Vulnerablities {
|
|
cveGrouped[v.GetCVE()] = append(cveGrouped[v.GetCVE()], v.Affected())
|
|
}
|
|
|
|
for cve, sIDs := range cveGrouped {
|
|
hosts, err := ds.HostVulnSummariesBySoftwareIDs(ctx, sIDs)
|
|
if err != nil {
|
|
return ctxerr.Wrap(ctx, err, "get hosts by software ids")
|
|
}
|
|
|
|
for len(hosts) > 0 {
|
|
limit := len(hosts)
|
|
if batchSize > 0 && len(hosts) > batchSize {
|
|
limit = batchSize
|
|
}
|
|
payload := mapper.GetPayload(serverURL, hosts[:limit], cve, args.Meta[cve])
|
|
if err := sendVulnerabilityHostBatch(ctx, targetURL, payload, args.Time, logger); err != nil {
|
|
return ctxerr.Wrap(ctx, err, "send vulnerability host batch")
|
|
}
|
|
hosts = hosts[limit:]
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func sendVulnerabilityHostBatch(ctx context.Context, targetURL string, vuln WebhookPayload, now time.Time, logger *slog.Logger) error {
|
|
payload := map[string]interface{}{
|
|
"timestamp": now,
|
|
"vulnerability": vuln,
|
|
}
|
|
|
|
if err := server.PostJSONWithTimeout(ctx, targetURL, &payload, logger); err != nil {
|
|
return ctxerr.Wrapf(ctx, err, "posting to %s", targetURL)
|
|
}
|
|
return nil
|
|
}
|