Skip to content

Commit e0018cc

Browse files
committed
add UnresolvedVulnerabilityCountRule
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 5ee2cea commit e0018cc

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

policy/rules.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99

1010
from django.apps import apps
11+
from django.db.models import Exists
12+
from django.db.models import OuterRef
1113

1214
# VulnerabilityAnalysis states that indicate a vulnerability has been triaged and addressed.
1315
TERMINAL_VULNERABILITY_STATES = ["resolved", "resolved_with_pedigree", "not_affected"]
@@ -132,11 +134,47 @@ def count_violations(self, product, threshold, parameters):
132134
return count if count > threshold else 0
133135

134136

137+
class UnresolvedVulnerabilityCountRule(BaseRule):
138+
rule_type = "unresolved_vulnerability_count"
139+
label = "Unresolved Vulnerability Count"
140+
severity = "warning"
141+
description = (
142+
"Counts individual package-vulnerability links in the product that have not been "
143+
"addressed via a VulnerabilityAnalysis with a terminal state "
144+
"(resolved, resolved_with_pedigree, or not_affected)."
145+
)
146+
147+
def count_violations(self, product, threshold, parameters):
148+
PackageAffectedByVulnerability = apps.get_model(
149+
"component_catalog", "packageaffectedbyvulnerability"
150+
)
151+
VulnerabilityAnalysis = apps.get_model("vulnerabilities", "vulnerabilityanalysis")
152+
153+
terminal_analysis = VulnerabilityAnalysis.objects.filter(
154+
product=product,
155+
state__in=TERMINAL_VULNERABILITY_STATES,
156+
package=OuterRef("package"),
157+
vulnerability=OuterRef("vulnerability"),
158+
)
159+
160+
count = (
161+
PackageAffectedByVulnerability.objects.filter(
162+
package__productpackages__product=product,
163+
)
164+
.annotate(has_terminal_analysis=Exists(terminal_analysis))
165+
.filter(has_terminal_analysis=False)
166+
.distinct()
167+
.count()
168+
)
169+
return count if count > threshold else 0
170+
171+
135172
RULE_REGISTRY = {
136173
UsagePolicyErrorRule.rule_type: UsagePolicyErrorRule(),
137174
UsagePolicyWarningRule.rule_type: UsagePolicyWarningRule(),
138175
LicensePolicyErrorRule.rule_type: LicensePolicyErrorRule(),
139176
LicensePolicyWarningRule.rule_type: LicensePolicyWarningRule(),
140177
LicenseCoverageGapRule.rule_type: LicenseCoverageGapRule(),
141178
VulnerabilityDetectedRule.rule_type: VulnerabilityDetectedRule(),
179+
UnresolvedVulnerabilityCountRule.rule_type: UnresolvedVulnerabilityCountRule(),
142180
}

0 commit comments

Comments
 (0)