Other status timestamps not cleared when confirming Vulnerability
Summary
State transition bug causing discrepancy between severity counts and vulnerabilities over time counts.
Reproduction Steps
- A vulnerability is set to dismissed:
dismissed_attimestamp gets recorded - That vulnerability is set to confirmed:
confirmed_attimestamp is recorded, butdismissed_attimestamp is not cleared (this is the root cause) - The severity counts query simply uses the
stateso since the vulnerability is confirmed now, it's part of that count - However, the vulnerabilities over time query needs to use timestamps to have the state on each date. As part of the query it has:
must_not: [ { range: { resolved_at: { lte: date_end_of_day } } }, { range: { dismissed_at: { lte: date_end_of_day } } } ] - Since the
dismissed_atwas not cleared, it's filtered out and not counted - This causes the difference in counts for the two queries
Root Cause Analysis
This also happens when we resolve instead of dismiss. This does not happen when we set back to Needs triage instead of Confirm.
The ConfirmService does not reset resolved_at and dismissed_at, while the RevertToDetectedService resets (set to nil) resolved_at, dismissed_at, and confirmed_at.
Expected Behavior
When confirming a vulnerability, the ConfirmService should reset (set to nil) the following timestamps:
resolved_atdismissed_at
Implementation plan:
-
Write model-layer callbacks to reset the values according to state change (In this case if the state is set to confirmed, reset
resolved_atanddismissed_at) -
Write a backfill migration to fix existing data, followed by a ES reindex
- For all confirmed state vulnerabilities, update
resolved_atanddismissed_attonil
- For all confirmed state vulnerabilities, update
Edited by Subashis Chakraborty