Skip to content

Do not treat EPSS score as advisory #2472

Open

Description

@keshav-space

Currently, we treat EPSS as an Advisory. Since we receive EPSS scores daily we're creating millions of EPSS advisories (we currently have around 17 million), which is not the right approach. Instead we should create dedicated model to track EPSS scores.

Activity

  1. keshav-space commented on Oct 14, 2026

    @keshav-space
    MemberAuthor

    ^ @Samk1710 issue is all yours

  2. Samk1710 commented on Oct 16, 2026

    @Samk1710
    Contributor

    A standalone EPSSScore model decoupled from AdvisoryV2

    class EPSSScore(models.Model):
        cve = models.CharField(max_length=20, db_index=True)
        date = models.DateField(db_index=True)
        score = models.FloatField()
        percentile = models.FloatField()
    
        class Meta:
            unique_together = (("cve", "date"),)
            indexes = [
                models.Index(fields=["cve", "-date"]),
            ]

    Instead of an Advisory Importer we can have a Pipeline that:

    1. Download and bulk insert in this model from https://epss.cyentia.com/epss_scores-current.csv.gz.
    2. Runs a prune step deleting records older than the epss_retention_cutoff_days say 30/60/90 days.
    3. Then we can update the related consumer code like UI, API and risk scoring.

    For example:
    When viewing an advisory page (e.g., GHSA-1234 with alias CVE-2026-11111):

    1. Extract CVE alias: The view gets CVE-2026-11111 from advisory.aliases.
    2. Direct query :
      latest = EPSSScore.objects.filter(cve=cve).order_by("-date").first()
      history = EPSSScore.objects.filter(cve=cve).order_by("-date")[:30] 
      

    Why 30-90 days retention is good :

    • The Exploit Prediction Scoring System (EPSS) is a data-driven machine-learning model that estimates the probability that a published CVE will be exploited in the wild in the next 30 days. ---- Defined in https://www.first.org/epss/
    • Beyond 90 days, EPSS predictions are operationally stale as they are expired probabilities. It is of little/no sense in vulnerability triage
    • Storing them indefinitely is also of little use as mentioned above and is also a nightmare for our DB.

    A standalone model will be fast and efficient with pruning.

    Also storing the scores only when changed will be slower during ingestion(as read-before-write comparisons for 250k CVEs daily is involved) and the EPSS History will have to gap fill across missing dates. Pruning after epss_retention_cutoff_days is better for storage and i/o .

    @pombredanne @keshav-space @ziadhany kindly share your thoughts and feedback on this when time !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions