Skip to content

Commit 5bd7bb4

Browse files
committed
Add a test for Suricata rules
Simplify the rules structure Fix a duplication avid in UI/API Signed-off-by: ziad hany <ziadhany2016@gmail.com>
1 parent 94b57c1 commit 5bd7bb4

20 files changed

Lines changed: 246 additions & 573 deletions

vulnerabilities/api_v2.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,17 +1412,22 @@ class Meta:
14121412

14131413

14141414
class DetectionRuleSerializer(serializers.ModelSerializer):
1415-
advisory_avid = serializers.SlugRelatedField(
1416-
many=True, read_only=True, slug_field="avid", source="related_advisories"
1417-
)
1415+
advisory_avid = serializers.SerializerMethodField()
14181416

14191417
class Meta:
14201418
model = DetectionRule
14211419
fields = ["rule_type", "source_url", "rule_metadata", "rule_text", "advisory_avid"]
14221420

1421+
def get_advisory_avid(self, obj):
1422+
avids = set(advisory.avid for advisory in obj.related_advisories.all())
1423+
return sorted(list(avids))
1424+
14231425

14241426
class DetectionRuleViewSet(viewsets.ReadOnlyModelViewSet):
1425-
queryset = DetectionRule.objects.prefetch_related("related_advisories")
1427+
advisories_prefetch = Prefetch(
1428+
"related_advisories", queryset=AdvisoryV2.objects.only("id", "avid").distinct()
1429+
)
1430+
queryset = DetectionRule.objects.prefetch_related(advisories_prefetch)
14261431
serializer_class = DetectionRuleSerializer
14271432
throttle_classes = [AnonRateThrottle, PermissionBasedUserRateThrottle]
14281433
filter_backends = [filters.DjangoFilterBackend]

vulnerabilities/improvers/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
from vulnerabilities.pipelines.v2_improvers import flag_ghost_packages as flag_ghost_packages_v2
3535
from vulnerabilities.pipelines.v2_improvers import relate_severities
3636
from vulnerabilities.pipelines.v2_improvers import sigma_rules
37-
from vulnerabilities.pipelines.v2_improvers import sigma_rules
3837
from vulnerabilities.pipelines.v2_improvers import suricata_rules
3938
from vulnerabilities.pipelines.v2_improvers import unfurl_version_range as unfurl_version_range_v2
4039
from vulnerabilities.pipelines.v2_improvers import yara_rules
@@ -78,13 +77,11 @@
7877
unfurl_version_range_v2.UnfurlVersionRangePipeline,
7978
compute_advisory_todo.ComputeToDo,
8079
collect_ssvc_trees.CollectSSVCPipeline,
81-
8280
relate_severities.RelateSeveritiesPipeline,
8381
sigma_rules.SigmaHQImproverPipeline,
8482
sigma_rules.SigmaSamuraiMDRImproverPipeline,
8583
sigma_rules.SigmaMbabinskiImproverPipeline,
8684
sigma_rules.P4T12ICKSigmaImproverPipeline,
87-
8885
yara_rules.ProtectionsArtifactsYara,
8986
yara_rules.YaraRulesYara,
9087
yara_rules.XumeiquerForensicsYara,
@@ -116,6 +113,7 @@
116113
yara_rules.Dr4k0niaYaraRules,
117114
yara_rules.Umair9747YaraRules,
118115
clamav_rules.ClamVRulesImproverPipeline,
119-
suricata_rules.SuricataRulesImproverPipeline,
116+
suricata_rules.SudohyakSuricataImproverPipeline,
117+
suricata_rules.OISFSuricataImproverPipeline,
120118
]
121119
)

vulnerabilities/migrations/0104_advisorydetectionrule.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

vulnerabilities/migrations/0105_alter_advisorydetectionrule_advisory.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

vulnerabilities/models.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3689,13 +3689,3 @@ class DetectionRule(models.Model):
36893689
related_name="detection_rules",
36903690
help_text="Advisories associated with this DetectionRule.",
36913691
)
3692-
3693-
3694-
class DetectionRuleTypes(models.TextChoices):
3695-
"""Defines the supported formats for security detection rules."""
3696-
3697-
YARA = "yara", "Yara"
3698-
YARA_X = "yara-x", "Yara-X"
3699-
SIGMA = "sigma", "Sigma"
3700-
CLAMAV = "clamav", "CLAMAV"
3701-
SURICATA = "suricata", "Suricata"

vulnerabilities/pipelines/v2_improvers/clamav_rules.py

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
import requests
2020

2121
from vulnerabilities.models import AdvisoryAlias
22+
from vulnerabilities.models import AdvisoryV2
2223
from vulnerabilities.models import DetectionRule
2324
from vulnerabilities.models import DetectionRuleTypes
2425
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
25-
from vulnerabilities.utils import find_all_cve
26+
from vulnerabilities.utils import find_all_cve_rule
2627

2728

2829
def extract_cvd(cvd_path, output_dir):
@@ -93,13 +94,6 @@ def parse_hdb_file(hdb_path: Path) -> List[dict]:
9394
return signatures
9495

9596

96-
def extract_cve_id(name: str):
97-
"""Normalize underscores and extract the first CVE ID from a string, or None."""
98-
normalized = name.replace("_", "-")
99-
cves = [cve.upper() for cve in find_all_cve(normalized)]
100-
return cves[0] if cves else None
101-
102-
10397
class ClamVRulesImproverPipeline(VulnerableCodeBaseImporterPipelineV2):
10498
"""
10599
Pipeline that downloads ClamAV database (main.cvd), extracts signatures,
@@ -159,36 +153,27 @@ def collect_and_store_advisories(self):
159153
self.extract_cvd_dir / "main.ndb"
160154
):
161155
name = rule_entry.get("name", "")
162-
cve_id = extract_cve_id(name)
163-
found_advisories = set()
164-
165-
if cve_id:
166-
try:
167-
if alias := AdvisoryAlias.objects.get(alias=cve_id):
168-
for adv in alias.advisories.all():
169-
found_advisories.add(adv)
170-
except AdvisoryAlias.DoesNotExist:
171-
self.log(f"Advisory {cve_id} not found.")
172-
173-
for adv in found_advisories:
174-
DetectionRule.objects.update_or_create(
175-
rule_text=str(rule_entry),
176-
rule_type=DetectionRuleTypes.CLAMAV,
177-
advisory=adv,
178-
defaults={
179-
"source_url": self.MAIN_DATABASE_URL,
180-
},
181-
)
182-
183-
if not found_advisories:
184-
DetectionRule.objects.update_or_create(
185-
rule_text=str(rule_entry),
186-
rule_type=DetectionRuleTypes.CLAMAV,
187-
advisory=None,
188-
defaults={
189-
"source_url": self.MAIN_DATABASE_URL,
190-
},
191-
)
156+
cve_ids = find_all_cve_rule(name)
157+
158+
advisories = set()
159+
for cve_id in cve_ids:
160+
alias = AdvisoryAlias.objects.filter(alias=cve_id).first()
161+
if alias:
162+
for adv in alias.advisories.all():
163+
advisories.add(adv)
164+
else:
165+
advs = AdvisoryV2.objects.filter(advisory_id=cve_id)
166+
for adv in advs:
167+
advisories.add(adv)
168+
169+
detection_rule, _ = DetectionRule.objects.get_or_create(
170+
rule_text=str(rule_entry),
171+
rule_type=DetectionRuleTypes.CLAMAV,
172+
source_url=self.MAIN_DATABASE_URL,
173+
)
174+
175+
for adv in advisories:
176+
detection_rule.related_advisories.add(adv)
192177

193178
def clean_downloads(self):
194179
"""Clean up downloaded files."""

0 commit comments

Comments
 (0)