Add vulnerability email de-duplication integration#103
Open
leonfullxr wants to merge 3 commits into
Open
Conversation
The Vulnerability Detection module emits one alert per (package, CVE) pair. A single package often carries dozens of CVEs, so one scan produces a burst of near-identical alerts for the same package on the same agent, which the stock email integration turns into hundreds of near-identical messages. This integration collapses the burst: the first alert for a given (agent, package, status) sends one email, and every subsequent CVE for that same key inside the suppression window is counted but not mailed. Non-vulnerability alerts pass through unchanged. State is kept in a SQLite store in WAL mode, with the check-and-write done in a single BEGIN IMMEDIATE transaction so the ~1000 concurrent integratord processes of a burst serialize correctly without lost updates or lock errors. Suppressed alerts exit on one indexed lookup and never open an SMTP connection. The suppression window is anchored at the first notification rather than the last alert seen, so a steady drip of CVEs cannot postpone the window indefinitely and silence a package. Cleanup is an explicit prune mode driven by a command wodle, keeping maintenance off the alert hot path.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Wazuh integration (integrations/vulnerability_email_dedup/) that acts as a drop-in custom-email replacement to suppress duplicate Vulnerability Detection emails by de-duplicating on (agent_id, package, status) within a fixed time window, while still passing non-vulnerability alerts through unchanged.
Changes:
- Introduces a SQLite/WAL-backed de-duplication store to suppress duplicate vulnerability emails during bursts.
- Adds a
prunemaintenance mode intended to be run via a scheduled Wazuhcommandwodle. - Provides installation/configuration/testing documentation and a standard Wazuh shell wrapper.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| integrations/vulnerability_email_dedup/README.md | Documents the integration behavior, configuration, ossec.conf wiring, and testing/maintenance steps. |
| integrations/vulnerability_email_dedup/custom-email.py | Implements per-alert de-duplication logic with SQLite WAL and a prune maintenance entry point. |
| integrations/vulnerability_email_dedup/custom-email | Provides the standard Wazuh wrapper to invoke the Python script via the embedded interpreter. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fall back to stderr logging when LOG_PATH is not writable, so a logging problem cannot stop the integration from sending mail. - Exit non-zero on prune failure and on email send failure, so failures are visible to the scheduler / integrator instead of appearing successful. - Clarify (docstring + README) that the package version is read from the triggering alert for the email body and is not persisted.
- Strip CR/LF from email header values (the subject is built from alert-derived package/agent names) to prevent header injection and send-time crashes. - Close the SQLite connection if a PRAGMA/DDL fails during open_db, so a failed init does not leak the handle. - Add an explicit no-args usage check for a clearer log message (the IndexError was already caught by the existing handler; this only improves diagnostics).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
integrations/vulnerability_email_dedup/, a drop-in replacement for acustom-emailintegration that suppresses duplicate vulnerability notifications.The Vulnerability Detection module emits one alert per (package, CVE) pair. A single package often carries dozens of CVEs, so one scan produces a burst of near-identical alerts for the same package on the same agent. Routed to email through the stock integration, that burst becomes hundreds of near-identical messages.
This integration sends one email per affected package per agent instead of one per CVE. Every subsequent CVE for the same key inside the suppression window is recorded and counted, but not mailed. Non-vulnerability alerts pass through unchanged.
Design notes
wazuh-integratordruns the script once per alert as a separate process, so a 1000-alert burst is 1000 short-lived processes rather than one process handling 1000 items. Correctness under the burst comes from the storage layer, not from concurrency inside the script.BEGIN IMMEDIATEtransaction, so concurrent processes for the same package serialize on the write lock and exactly one wins.smtplibis imported lazily so the suppression path does not pay the import cost.prunemode driven by acommandwodle rather than opportunistic work on the alert hot path. The table is bounded by distinct(agent, package, status)combinations, not by alert volume, so this is housekeeping rather than growth control.Files
custom-email.py- integration logic, Python standard library only.custom-email- standard Wazuh shell wrapper for the embedded interpreter.README.md- installation, configuration table,ossec.confblocks for both the integration and the prune wodle, testing steps, troubleshooting, provenance.Testing
Verified end to end against a local SMTP sink on Python 3.11:
cve_count.(agent, package, status)combinations at 64-way concurrency: 300 emails sent, one per distinct key, an 85% reduction.SUM(cve_count)equalled 2,000, confirming no lost updates. No lock errors, ~665 alerts/sec.prunemode runs and reports cleanly.Not yet exercised against a live vulnerability scan on a production manager; the
ossec.confwiring in the README is the documented path for that.