diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py
index 72e4ea4b3..edc4e4f0f 100644
--- a/vulnerabilities/importers/__init__.py
+++ b/vulnerabilities/importers/__init__.py
@@ -58,6 +58,7 @@
from vulnerabilities.pipelines.v2_importers import nginx_importer as nginx_importer_v2
from vulnerabilities.pipelines.v2_importers import npm_importer as npm_importer_v2
from vulnerabilities.pipelines.v2_importers import nvd_importer as nvd_importer_v2
+from vulnerabilities.pipelines.v2_importers import openssl_importer as openssl_importer_v2
from vulnerabilities.pipelines.v2_importers import oss_fuzz as oss_fuzz_v2
from vulnerabilities.pipelines.v2_importers import postgresql_importer as postgresql_importer_v2
from vulnerabilities.pipelines.v2_importers import (
@@ -119,6 +120,7 @@
ruby.RubyImporter,
apache_kafka.ApacheKafkaImporter,
openssl.OpensslImporter,
+ openssl_importer_v2.OpenSSLImporterPipeline,
redhat.RedhatImporter,
archlinux.ArchlinuxImporter,
ubuntu.UbuntuImporter,
diff --git a/vulnerabilities/migrations/0111_alter_advisoryseverity_scoring_system_and_more.py b/vulnerabilities/migrations/0111_alter_advisoryseverity_scoring_system_and_more.py
new file mode 100644
index 000000000..bac0c91b6
--- /dev/null
+++ b/vulnerabilities/migrations/0111_alter_advisoryseverity_scoring_system_and_more.py
@@ -0,0 +1,61 @@
+# Generated by Django 4.2.25 on 2026-01-19 06:22
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("vulnerabilities", "0110_pipelineschedule_is_run_once"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="advisoryseverity",
+ name="scoring_system",
+ field=models.CharField(
+ choices=[
+ ("cvssv2", "CVSSv2 Base Score"),
+ ("cvssv3", "CVSSv3 Base Score"),
+ ("cvssv3.1", "CVSSv3.1 Base Score"),
+ ("cvssv4", "CVSSv4 Base Score"),
+ ("rhbs", "RedHat Bugzilla severity"),
+ ("rhas", "RedHat Aggregate severity"),
+ ("archlinux", "Archlinux Vulnerability Group Severity"),
+ ("cvssv3.1_qr", "CVSSv3.1 Qualitative Severity Rating"),
+ ("generic_textual", "Generic textual severity rating"),
+ ("apache_httpd", "Apache Httpd Severity"),
+ ("apache_tomcat", "Apache Tomcat Severity"),
+ ("epss", "Exploit Prediction Scoring System"),
+ ("ssvc", "Stakeholder-Specific Vulnerability Categorization"),
+ ("openssl", "OpenSSL Severity"),
+ ],
+ help_text="Identifier for the scoring system used. Available choices are: cvssv2: CVSSv2 Base Score,\ncvssv3: CVSSv3 Base Score,\ncvssv3.1: CVSSv3.1 Base Score,\ncvssv4: CVSSv4 Base Score,\nrhbs: RedHat Bugzilla severity,\nrhas: RedHat Aggregate severity,\narchlinux: Archlinux Vulnerability Group Severity,\ncvssv3.1_qr: CVSSv3.1 Qualitative Severity Rating,\ngeneric_textual: Generic textual severity rating,\napache_httpd: Apache Httpd Severity,\napache_tomcat: Apache Tomcat Severity,\nepss: Exploit Prediction Scoring System,\nssvc: Stakeholder-Specific Vulnerability Categorization,\nopenssl: OpenSSL Severity ",
+ max_length=50,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="vulnerabilityseverity",
+ name="scoring_system",
+ field=models.CharField(
+ choices=[
+ ("cvssv2", "CVSSv2 Base Score"),
+ ("cvssv3", "CVSSv3 Base Score"),
+ ("cvssv3.1", "CVSSv3.1 Base Score"),
+ ("cvssv4", "CVSSv4 Base Score"),
+ ("rhbs", "RedHat Bugzilla severity"),
+ ("rhas", "RedHat Aggregate severity"),
+ ("archlinux", "Archlinux Vulnerability Group Severity"),
+ ("cvssv3.1_qr", "CVSSv3.1 Qualitative Severity Rating"),
+ ("generic_textual", "Generic textual severity rating"),
+ ("apache_httpd", "Apache Httpd Severity"),
+ ("apache_tomcat", "Apache Tomcat Severity"),
+ ("epss", "Exploit Prediction Scoring System"),
+ ("ssvc", "Stakeholder-Specific Vulnerability Categorization"),
+ ("openssl", "OpenSSL Severity"),
+ ],
+ help_text="Identifier for the scoring system used. Available choices are: cvssv2: CVSSv2 Base Score,\ncvssv3: CVSSv3 Base Score,\ncvssv3.1: CVSSv3.1 Base Score,\ncvssv4: CVSSv4 Base Score,\nrhbs: RedHat Bugzilla severity,\nrhas: RedHat Aggregate severity,\narchlinux: Archlinux Vulnerability Group Severity,\ncvssv3.1_qr: CVSSv3.1 Qualitative Severity Rating,\ngeneric_textual: Generic textual severity rating,\napache_httpd: Apache Httpd Severity,\napache_tomcat: Apache Tomcat Severity,\nepss: Exploit Prediction Scoring System,\nssvc: Stakeholder-Specific Vulnerability Categorization,\nopenssl: OpenSSL Severity ",
+ max_length=50,
+ ),
+ ),
+ ]
diff --git a/vulnerabilities/pipelines/v2_importers/openssl_importer.py b/vulnerabilities/pipelines/v2_importers/openssl_importer.py
new file mode 100644
index 000000000..c05aca7be
--- /dev/null
+++ b/vulnerabilities/pipelines/v2_importers/openssl_importer.py
@@ -0,0 +1,181 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+
+import logging
+from pathlib import Path
+from traceback import format_exc as traceback_format_exc
+from typing import Iterable
+
+from dateutil.parser import parse
+from fetchcode.vcs import fetch_via_vcs
+from packageurl import PackageURL
+from univers.version_range import OpensslVersionRange
+
+from vulnerabilities import severity_systems
+from vulnerabilities.importer import AdvisoryData
+from vulnerabilities.importer import AffectedPackageV2
+from vulnerabilities.importer import PatchData
+from vulnerabilities.importer import VulnerabilitySeverity
+from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
+from vulnerabilities.pipes import openssl
+from vulnerabilities.utils import build_description
+from vulnerabilities.utils import create_weaknesses_list
+from vulnerabilities.utils import get_item
+from vulnerabilities.utils import load_json
+
+
+class OpenSSLImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
+ """Import OpenSSL Advisories"""
+
+ pipeline_id = "openssl_importer_v2"
+ spdx_license_expression = "Apache-2.0"
+ importer_name = "OpenSSL Importer V2"
+
+ license_url = "https://github.com/openssl/openssl/blob/master/LICENSE.txt"
+ repo_url = "git+https://github.com/openssl/release-metadata/"
+
+ @classmethod
+ def steps(cls):
+ return (
+ cls.clone,
+ cls.collect_and_store_advisories,
+ cls.clean_downloads,
+ )
+
+ def clone(self):
+ self.log(f"Cloning `{self.repo_url}`")
+ self.vcs_response = fetch_via_vcs(self.repo_url)
+ self.advisory_path = Path(self.vcs_response.dest_dir)
+
+ def advisories_count(self):
+ vuln_directory = self.advisory_path / "secjson"
+ return sum(1 for _ in vuln_directory.glob("CVE-*.json"))
+
+ def collect_advisories(self) -> Iterable[AdvisoryData]:
+ vuln_directory = self.advisory_path / "secjson"
+
+ for advisory in vuln_directory.glob("CVE-*.json"):
+ yield self.to_advisory_data(advisory)
+
+ def to_advisory_data(self, file: Path) -> Iterable[AdvisoryData]:
+ # TODO: Collect the advisory credits, see https://github.com/aboutcode-org/vulnerablecode/issues/2121
+
+ affected_packages = []
+ severities = []
+ references = []
+ patches = []
+ fix_commits = {}
+ cwe_string = None
+
+ data = load_json(file)
+ advisory_text = file.read_text()
+ advisory = get_item(data, "containers", "cna")
+ description = get_item(advisory, "descriptions", 0, "value")
+ title = advisory.get("title")
+ date_published = parse(get_item(advisory, "datePublic"))
+ cve = get_item(data, "cveMetadata", "cveId")
+ severity_score = get_item(advisory, "metrics", 0, "other", "content", "text")
+
+ for reference in get_item(advisory, "references") or []:
+ ref_name = reference.get("name")
+ ref_url = reference.get("url")
+ if not ref_url:
+ continue
+
+ tag = get_item(reference, "tags", 0) or ""
+ tag = tag.lower()
+ references.append(openssl.get_reference(ref_name, tag, ref_url))
+
+ if tag != "patch":
+ continue
+
+ if not ref_name:
+ patches.append(PatchData(patch_url=ref_url))
+ continue
+
+ fix_commits[ref_name.split()[0]] = ref_url
+
+ for affected in get_item(advisory, "affected", 0, "versions") or []:
+ if affected.get("status") != "affected":
+ continue
+ fixed_by_commit_patches = []
+ affected_constraints = None
+ fixed_version = None
+
+ try:
+ affected_constraints, fixed_version = openssl.parse_affected_fixed(affected)
+ except Exception as e:
+ self.log(
+ f"Failed to parse OpenSSL version for: {cve} with error {e!r}:\n{traceback_format_exc()}",
+ level=logging.ERROR,
+ )
+ continue
+
+ fixed_version_range = (
+ OpensslVersionRange.from_versions([fixed_version]) if fixed_version else None
+ )
+
+ affected_version_range = (
+ OpensslVersionRange(constraints=affected_constraints)
+ if affected_constraints
+ else None
+ )
+
+ if fixed_version and (commit_url := fix_commits.get(fixed_version)):
+ if patch := openssl.get_commit_patch(
+ url=commit_url,
+ logger=self.log,
+ ):
+ fixed_by_commit_patches.append(patch)
+
+ affected_packages.append(
+ AffectedPackageV2(
+ package=PackageURL(type="openssl", name="openssl"),
+ affected_version_range=affected_version_range,
+ fixed_version_range=fixed_version_range,
+ fixed_by_commit_patches=fixed_by_commit_patches,
+ )
+ )
+
+ if severity_score:
+ severities.append(
+ VulnerabilitySeverity(
+ system=severity_systems.OPENSSL,
+ value=severity_score,
+ url=f"https://openssl-library.org/news/secjson/{cve.lower()}.json",
+ )
+ )
+
+ if "problemTypes" in advisory:
+ problem_type = get_item(advisory, "problemTypes", 0, "descriptions", 0)
+ cwe_string = problem_type.get("cweId")
+
+ weaknesses = create_weaknesses_list([cwe_string]) if cwe_string else []
+
+ return AdvisoryData(
+ advisory_id=cve,
+ aliases=[],
+ summary=build_description(summary=title, description=description),
+ date_published=date_published,
+ affected_packages=affected_packages,
+ references_v2=references,
+ severities=severities,
+ weaknesses=weaknesses,
+ patches=patches,
+ url=f"https://github.com/openssl/release-metadata/blob/main/secjson/{cve}.json",
+ original_advisory_text=advisory_text,
+ )
+
+ def clean_downloads(self):
+ if self.vcs_response:
+ self.log(f"Removing cloned repository")
+ self.vcs_response.delete()
+
+ def on_failure(self):
+ self.clean_downloads()
diff --git a/vulnerabilities/pipes/openssl.py b/vulnerabilities/pipes/openssl.py
new file mode 100644
index 000000000..b240f416c
--- /dev/null
+++ b/vulnerabilities/pipes/openssl.py
@@ -0,0 +1,101 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+
+from urllib.parse import parse_qs
+from urllib.parse import urlparse
+
+from univers.version_constraint import VersionConstraint
+from univers.versions import OpensslVersion
+
+from vulnerabilities.importer import PackageCommitPatchData
+from vulnerabilities.importer import ReferenceV2
+from vulnerabilities.models import AdvisoryReference
+from vulnerabilities.utils import get_item
+
+
+def parse_affected_fixed(affected):
+ impact_lower = affected.get("version")
+ affected_constraint = []
+ fixed_version = None
+
+ if not impact_lower:
+ return affected_constraint, fixed_version
+
+ if impact_upper := affected.get("lessThan"):
+ fixed_version = impact_upper
+ affected_constraint.append(
+ VersionConstraint(
+ comparator="<",
+ version=OpensslVersion(string=impact_upper),
+ )
+ )
+ elif impact_upper := affected.get("lessThanOrEqual"):
+ affected_constraint.append(
+ VersionConstraint(
+ comparator="<=",
+ version=OpensslVersion(string=impact_upper),
+ )
+ )
+
+ lower_comp = "=" if not affected_constraint else ">="
+ affected_constraint.append(
+ VersionConstraint(
+ comparator=lower_comp,
+ version=OpensslVersion(string=impact_lower),
+ )
+ )
+
+ return affected_constraint, fixed_version
+
+
+def get_commit_patch(url, logger):
+ """Return PackageCommitPatchData from OpenSSL commit url."""
+
+ vcs_url = "https://github.com/openssl/openssl/"
+ hash = None
+
+ if url.startswith("https://github.openssl.org/"):
+ # unknow vcs url, these are instead stored as references.
+ return
+
+ if url.startswith("https://github.com/"):
+ vcs_url, hash = url.split("/commit/")
+ elif url.startswith("https://git.openssl.org/"):
+ parsed = urlparse(url)
+ params = parse_qs(parsed.query, separator=";")
+ if "h" in params:
+ # git.openssl.org has moved to github.com/openssl/openssl
+ hash = get_item(params, "h", 0)
+
+ if not hash:
+ logger(f"Unsupported commit url {url}")
+ return
+
+ return PackageCommitPatchData(
+ vcs_url=vcs_url,
+ commit_hash=hash[:40],
+ )
+
+
+def get_reference(reference_name, tag, reference_url):
+ name = reference_name.lower() if reference_name else ""
+
+ ref_type = (
+ AdvisoryReference.COMMIT
+ if "commit" in name or tag == "patch"
+ else AdvisoryReference.ADVISORY
+ if "advisory" in name
+ else AdvisoryReference.OTHER
+ )
+
+ return ReferenceV2(
+ reference_id=reference_name or tag,
+ reference_type=ref_type,
+ url=reference_url,
+ )
diff --git a/vulnerabilities/severity_systems.py b/vulnerabilities/severity_systems.py
index 17008a219..fbb611ae4 100644
--- a/vulnerabilities/severity_systems.py
+++ b/vulnerabilities/severity_systems.py
@@ -8,7 +8,6 @@
#
import dataclasses
-from datetime import datetime
from cvss import CVSS2
from cvss import CVSS3
@@ -185,6 +184,18 @@ def get(self, scoring_elements: str) -> dict:
"Low",
]
+OPENSSL = ScoringSystem(
+ identifier="openssl",
+ name="OpenSSL Severity",
+ url="https://openssl-library.org/policies/general/security-policy/",
+)
+OPENSSL.choices = [
+ "Critical",
+ "High",
+ "Moderate",
+ "Low",
+]
+
@dataclasses.dataclass(order=True)
class EPSSScoringSystem(ScoringSystem):
@@ -227,5 +238,6 @@ def get(self, scoring_elements: str):
APACHE_TOMCAT,
EPSS,
SSVC,
+ OPENSSL,
)
}
diff --git a/vulnerabilities/tests/pipelines/v2_importers/test_openssl_importer.py b/vulnerabilities/tests/pipelines/v2_importers/test_openssl_importer.py
new file mode 100644
index 000000000..1535f1fe7
--- /dev/null
+++ b/vulnerabilities/tests/pipelines/v2_importers/test_openssl_importer.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+
+
+from pathlib import Path
+from unittest.mock import patch
+
+from django.test import TestCase
+
+from vulnerabilities.models import AdvisoryV2
+from vulnerabilities.pipelines.v2_importers.openssl_importer import OpenSSLImporterPipeline
+from vulnerabilities.tests import util_tests
+from vulnerabilities.tests.pipelines import TestLogger
+
+TEST_DATA = Path(__file__).parent.parent.parent / "test_data" / "openssl" / "release_metadata"
+
+
+class TestOpenSSLImporterPipeline(TestCase):
+ def setUp(self):
+ self.logger = TestLogger()
+
+ @patch("vulnerabilities.pipelines.v2_importers.openssl_importer.OpenSSLImporterPipeline.clone")
+ def test_redhat_advisories_v2(self, mock_clone):
+ mock_clone.__name__ = "clone"
+ pipeline = OpenSSLImporterPipeline()
+ pipeline.advisory_path = TEST_DATA
+ pipeline.vcs_response = None
+ pipeline.log = self.logger.write
+ pipeline.execute()
+
+ expected_file = TEST_DATA / "openssl_advisoryv2-expected.json"
+ result = [adv.to_advisory_data().to_dict() for adv in AdvisoryV2.objects.all()]
+ util_tests.check_results_against_json(result, expected_file)
diff --git a/vulnerabilities/tests/pipes/test_openssl.py b/vulnerabilities/tests/pipes/test_openssl.py
new file mode 100644
index 000000000..b0b7a1955
--- /dev/null
+++ b/vulnerabilities/tests/pipes/test_openssl.py
@@ -0,0 +1,87 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+
+
+from unittest import TestCase
+
+from vulnerabilities.importer import ReferenceV2
+from vulnerabilities.models import AdvisoryReference
+from vulnerabilities.pipes.openssl import get_commit_patch
+from vulnerabilities.pipes.openssl import get_reference
+from vulnerabilities.pipes.openssl import parse_affected_fixed
+from vulnerabilities.tests.pipelines import TestLogger
+
+
+class TestPipeOpenSSL(TestCase):
+ def setUp(self):
+ self.logger = TestLogger()
+
+ def test_vulnerability_pipes_openssl_get_reference(self):
+ refrence_name = "OpenSSL Advisory"
+ tag = "vendor-advisory"
+ refrence_url = "https://www.openssl.org/news/secadv/20221213.txt"
+ result = get_reference(
+ reference_name=refrence_name,
+ tag=tag,
+ reference_url=refrence_url,
+ )
+ expected = ReferenceV2(
+ reference_id=refrence_name,
+ reference_type=AdvisoryReference.ADVISORY,
+ url=refrence_url,
+ )
+
+ self.assertEqual(result, expected)
+
+ def test_vulnerability_pipes_openssl_get_commit_patch(self):
+ url = "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=cca1cd9a3447dd067503e4a85ebd1679ee78a48e"
+ result_patch = get_commit_patch(url=url, logger=self.logger.write)
+ expected_vcs = "https://github.com/openssl/openssl/"
+ expected_hash = "cca1cd9a3447dd067503e4a85ebd1679ee78a48e"
+
+ self.assertEqual(result_patch.vcs_url, expected_vcs)
+ self.assertEqual(result_patch.commit_hash, expected_hash)
+
+ def test_vulnerability_pipes_openssl_get_commit_patch_unsupported(self):
+ url = "https://someunsupported.url/commit/93l232slfsll3l23l2"
+ get_commit_patch(url=url, logger=self.logger.write)
+
+ self.assertIn("Unsupported commit url", self.logger.getvalue())
+
+ def test_vulnerability_pipes_openssl_parse_affected_fixed_lessthan(self):
+ affected = {
+ "lessThan": "0.9.7a",
+ "status": "affected",
+ "version": "0.9.7",
+ "versionType": "custom",
+ }
+
+ result_affected, result_fixed = parse_affected_fixed(affected)
+ result_affected = [str(const) for const in result_affected]
+ expected_affected = [">=0.9.7", "<0.9.7a"]
+ expected_fixed = "0.9.7a"
+
+ self.assertCountEqual(result_affected, expected_affected)
+ self.assertEqual(result_fixed, expected_fixed)
+
+ def test_vulnerability_pipes_openssl_parse_affected_fixed_lessthanorequal(self):
+ affected = {
+ "lessThanOrEqual": "3.0.7",
+ "status": "affected",
+ "version": "3.0.0",
+ "versionType": "semver",
+ }
+
+ result_affected, result_fixed = parse_affected_fixed(affected)
+ result_affected = [str(const) for const in result_affected]
+ expected_affected = [">=3.0.0", "<=3.0.7"]
+ expected_fixed = None
+
+ self.assertCountEqual(result_affected, expected_affected)
+ self.assertEqual(result_fixed, expected_fixed)
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/openssl_advisoryv2-expected.json b/vulnerabilities/tests/test_data/openssl/release_metadata/openssl_advisoryv2-expected.json
new file mode 100644
index 000000000..8f4fda057
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/openssl_advisoryv2-expected.json
@@ -0,0 +1,376 @@
+[
+ {
+ "advisory_id": "CVE-2002-0655",
+ "aliases": [],
+ "summary": "Inproper handling of ASCII representations of integers on 64 bit platforms allowed remote attackers to cause a denial of service or possibly execute arbitrary code.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=0.9.6|<0.9.6e",
+ "fixed_version_range": "vers:openssl/0.9.6e",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "OpenSSL Advisory",
+ "reference_type": "advisory",
+ "url": "https://www.openssl.org/news/secadv/20020730.txt"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "unknown",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2002-07-30T00:00:00+00:00",
+ "weaknesses": [],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2002-0655.json"
+ },
+ {
+ "advisory_id": "CVE-2006-2937",
+ "aliases": [],
+ "summary": "During the parsing of certain invalid ASN.1 structures an error condition is mishandled. This can result in an infinite loop which consumes system memory.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=0.9.7|<0.9.7l",
+ "fixed_version_range": "vers:openssl/0.9.7l",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ },
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=0.9.8|<0.9.8d",
+ "fixed_version_range": "vers:openssl/0.9.8d",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "OpenSSL Advisory",
+ "reference_type": "advisory",
+ "url": "https://www.openssl.org/news/secadv/20060928.txt"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "unknown",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2006-09-28T00:00:00+00:00",
+ "weaknesses": [],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2006-2937.json"
+ },
+ {
+ "advisory_id": "CVE-2010-0433",
+ "aliases": [],
+ "summary": "A missing return value check flaw was discovered in OpenSSL, that could possibly cause OpenSSL to call a Kerberos library function with invalid arguments, resulting in a NULL pointer dereference crash in the MIT Kerberos library. In certain configurations, a remote attacker could use this flaw to crash a TLS/SSL server using OpenSSL by requesting Kerberos cipher suites during the TLS handshake.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=0.9.8|<0.9.8n",
+ "fixed_version_range": "vers:openssl/0.9.8n",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/openssl/openssl/",
+ "commit_hash": "cca1cd9a3447dd067503e4a85ebd1679ee78a48e",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "0.9.8n git commit",
+ "reference_type": "commit",
+ "url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=cca1cd9a3447dd067503e4a85ebd1679ee78a48e"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "unknown",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2010-01-19T00:00:00+00:00",
+ "weaknesses": [],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2010-0433.json"
+ },
+ {
+ "advisory_id": "CVE-2015-0206",
+ "aliases": [],
+ "summary": "A memory leak can occur in the dtls1_buffer_record function under certain conditions. In particular this could occur if an attacker sent repeated DTLS records with the same sequence number but for the next epoch. The memory leak could be exploited by an attacker in a Denial of Service attack through memory exhaustion.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=1.0.1|<1.0.1k",
+ "fixed_version_range": "vers:openssl/1.0.1k",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ },
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=1.0.0|<1.0.0p",
+ "fixed_version_range": "vers:openssl/1.0.0p",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "OpenSSL Advisory",
+ "reference_type": "advisory",
+ "url": "https://www.openssl.org/news/secadv/20150108.txt"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "Moderate",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2015-01-08T00:00:00+00:00",
+ "weaknesses": [],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2015-0206.json"
+ },
+ {
+ "advisory_id": "CVE-2022-3996",
+ "aliases": [],
+ "summary": "X.509 Policy Constraints Double Locking\nIf an X.509 certificate contains a malformed policy constraint and\npolicy processing is enabled, then a write lock will be taken twice\nrecursively. On some operating systems (most widely: Windows) this\nresults in a denial of service when the affected process hangs. Policy\nprocessing being enabled on a publicly facing server is not considered\nto be a common setup.\n\nPolicy processing is enabled by passing the `-policy`\nargument to the command line utilities or by calling the\n`X509_VERIFY_PARAM_set1_policies()` function.\n\nUpdate (31 March 2023): The description of the policy processing enablement\nwas corrected based on CVE-2023-0466.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=3.0.0|<=3.0.7",
+ "fixed_version_range": null,
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": []
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "OpenSSL Advisory",
+ "reference_type": "advisory",
+ "url": "https://www.openssl.org/news/secadv/20221213.txt"
+ },
+ {
+ "reference_id": "patch",
+ "reference_type": "commit",
+ "url": "https://github.com/openssl/openssl/commit/7725e7bfe6f2ce8146b6552b44e0d226be7638e7"
+ }
+ ],
+ "patches": [
+ {
+ "patch_url": "https://github.com/openssl/openssl/commit/7725e7bfe6f2ce8146b6552b44e0d226be7638e7",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "Low",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2022-12-13T07:00:00+00:00",
+ "weaknesses": [
+ 667
+ ],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2022-3996.json"
+ },
+ {
+ "advisory_id": "CVE-2025-9231",
+ "aliases": [],
+ "summary": "Timing side-channel in SM2 algorithm on 64 bit ARM\nIssue summary: A timing side-channel which could potentially allow remote\nrecovery of the private key exists in the SM2 algorithm implementation on 64 bit\nARM platforms.\n\nImpact summary: A timing side-channel in SM2 signature computations on 64 bit\nARM platforms could allow recovering the private key by an attacker..\n\nWhile remote key recovery over a network was not attempted by the reporter,\ntiming measurements revealed a timing signal which may allow such an attack.\n\nOpenSSL does not directly support certificates with SM2 keys in TLS, and so\nthis CVE is not relevant in most TLS contexts. However, given that it is\npossible to add support for such certificates via a custom provider, coupled\nwith the fact that in such a custom provider context the private key may be\nrecoverable via remote timing measurements, we consider this to be a Moderate\nseverity issue.\n\nThe FIPS modules in 3.5, 3.4, 3.3, 3.2, 3.1 and 3.0 are not affected by this\nissue, as SM2 is not an approved algorithm.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=3.5.0|<3.5.4",
+ "fixed_version_range": "vers:openssl/3.5.4",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/openssl/openssl",
+ "commit_hash": "fc47a2ec078912b3e914fab5734535e76c4820c2",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ },
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=3.4.0|<3.4.3",
+ "fixed_version_range": "vers:openssl/3.4.3",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/openssl/openssl",
+ "commit_hash": "eed5adc9f969d77c94f213767acbb41ff923b6f4",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ },
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=3.3.0|<3.3.5",
+ "fixed_version_range": "vers:openssl/3.3.5",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/openssl/openssl",
+ "commit_hash": "567f64386e43683888212226824b6a179885a0fe",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ },
+ {
+ "package": {
+ "type": "openssl",
+ "namespace": "",
+ "name": "openssl",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:openssl/>=3.2.0|<3.2.6",
+ "fixed_version_range": "vers:openssl/3.2.6",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/openssl/openssl",
+ "commit_hash": "cba616c26ac8e7b37de5e77762e505ba5ca51698",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ }
+ ],
+ "references_v2": [
+ {
+ "reference_id": "3.2.6 git commit",
+ "reference_type": "commit",
+ "url": "https://github.com/openssl/openssl/commit/cba616c26ac8e7b37de5e77762e505ba5ca51698"
+ },
+ {
+ "reference_id": "3.3.5 git commit",
+ "reference_type": "commit",
+ "url": "https://github.com/openssl/openssl/commit/567f64386e43683888212226824b6a179885a0fe"
+ },
+ {
+ "reference_id": "3.4.3 git commit",
+ "reference_type": "commit",
+ "url": "https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4"
+ },
+ {
+ "reference_id": "3.5.4 git commit",
+ "reference_type": "commit",
+ "url": "https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2"
+ },
+ {
+ "reference_id": "OpenSSL Advisory",
+ "reference_type": "advisory",
+ "url": "https://openssl-library.org/news/secadv/20250930.txt"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "openssl",
+ "value": "Moderate",
+ "scoring_elements": ""
+ }
+ ],
+ "date_published": "2025-09-30T14:00:00+00:00",
+ "weaknesses": [
+ 385
+ ],
+ "url": "https://github.com/openssl/release-metadata/blob/main/secjson/CVE-2025-9231.json"
+ }
+]
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2002-0655.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2002-0655.json
new file mode 100644
index 000000000..3b9b6ff8b
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2002-0655.json
@@ -0,0 +1,69 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThan": "0.9.6e",
+ "status": "affected",
+ "version": "0.9.6",
+ "versionType": "custom"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "finder",
+ "value": "OpenSSL Group (A.L. Digital)"
+ }
+ ],
+ "datePublic": "2002-07-30T00:00:00Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "value": "Inproper handling of ASCII representations of integers on 64 bit platforms allowed remote attackers to cause a denial of service or possibly execute arbitrary code."
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "unknown"
+ },
+ "type": "https://www.openssl.org/policies/secpolicy.html#"
+ }
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "OpenSSL Advisory",
+ "tags": [
+ "vendor-advisory"
+ ],
+ "url": "https://www.openssl.org/news/secadv/20020730.txt"
+ }
+ ],
+ "x_generator": {
+ "importer": "vulnxml2json5.py 2022-11-04 07:19:07.063650"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "cveId": "CVE-2002-0655",
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.0"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2006-2937.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2006-2937.json
new file mode 100644
index 000000000..a4923e7bc
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2006-2937.json
@@ -0,0 +1,75 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThan": "0.9.7l",
+ "status": "affected",
+ "version": "0.9.7",
+ "versionType": "custom"
+ },
+ {
+ "lessThan": "0.9.8d",
+ "status": "affected",
+ "version": "0.9.8",
+ "versionType": "custom"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "finder",
+ "value": "openssl"
+ }
+ ],
+ "datePublic": "2006-09-28T00:00:00Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "value": "During the parsing of certain invalid ASN.1 structures an error condition is mishandled. This can result in an infinite loop which consumes system memory. "
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "unknown"
+ },
+ "type": "https://www.openssl.org/policies/secpolicy.html#"
+ }
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "OpenSSL Advisory",
+ "tags": [
+ "vendor-advisory"
+ ],
+ "url": "https://www.openssl.org/news/secadv/20060928.txt"
+ }
+ ],
+ "x_generator": {
+ "importer": "vulnxml2json5.py 2022-11-04 07:19:07.065322"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "cveId": "CVE-2006-2937",
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.0"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2010-0433.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2010-0433.json
new file mode 100644
index 000000000..b7b3cc3f4
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2010-0433.json
@@ -0,0 +1,69 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThan": "0.9.8n",
+ "status": "affected",
+ "version": "0.9.8",
+ "versionType": "custom"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "finder",
+ "value": "Todd Rinaldo, Tomas Hoger (Red Hat)"
+ }
+ ],
+ "datePublic": "2010-01-19T00:00:00Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "value": "A missing return value check flaw was discovered in OpenSSL, that could possibly cause OpenSSL to call a Kerberos library function with invalid arguments, resulting in a NULL pointer dereference crash in the MIT Kerberos library. In certain configurations, a remote attacker could use this flaw to crash a TLS/SSL server using OpenSSL by requesting Kerberos cipher suites during the TLS handshake. "
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "unknown"
+ },
+ "type": "https://www.openssl.org/policies/secpolicy.html#"
+ }
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "0.9.8n git commit",
+ "tags": [
+ "patch"
+ ],
+ "url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=cca1cd9a3447dd067503e4a85ebd1679ee78a48e"
+ }
+ ],
+ "x_generator": {
+ "importer": "vulnxml2json5.py 2022-11-04 07:19:07.067354"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "cveId": "CVE-2010-0433",
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.0"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2015-0206.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2015-0206.json
new file mode 100644
index 000000000..72b1fd9ba
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2015-0206.json
@@ -0,0 +1,75 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThan": "1.0.1k",
+ "status": "affected",
+ "version": "1.0.1",
+ "versionType": "custom"
+ },
+ {
+ "lessThan": "1.0.0p",
+ "status": "affected",
+ "version": "1.0.0",
+ "versionType": "custom"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "finder",
+ "value": "Chris Mueller"
+ }
+ ],
+ "datePublic": "2015-01-08T00:00:00Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "value": "A memory leak can occur in the dtls1_buffer_record function under certain conditions. In particular this could occur if an attacker sent repeated DTLS records with the same sequence number but for the next epoch. The memory leak could be exploited by an attacker in a Denial of Service attack through memory exhaustion."
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "Moderate"
+ },
+ "type": "https://www.openssl.org/policies/secpolicy.html#moderate"
+ }
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "OpenSSL Advisory",
+ "tags": [
+ "vendor-advisory"
+ ],
+ "url": "https://www.openssl.org/news/secadv/20150108.txt"
+ }
+ ],
+ "x_generator": {
+ "importer": "vulnxml2json5.py 2022-11-04 07:19:07.058515"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "b3476cb9-2e3d-41a6-98d0-0f47421a65b6",
+ "cveId": "CVE-2015-0206",
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.0"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2022-3996.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2022-3996.json
new file mode 100644
index 000000000..60e1e79aa
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2022-3996.json
@@ -0,0 +1,107 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThanOrEqual": "3.0.7",
+ "status": "affected",
+ "version": "3.0.0",
+ "versionType": "semver"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "finder",
+ "user": "00000000-0000-4000-9000-000000000000",
+ "value": "Polar Bear"
+ },
+ {
+ "lang": "en",
+ "type": "remediation developer",
+ "user": "00000000-0000-4000-9000-000000000000",
+ "value": "Paul Dale"
+ }
+ ],
+ "datePublic": "2022-12-13T07:00:00.000Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "supportingMedia": [
+ {
+ "base64": false,
+ "type": "text/html",
+ "value": "If an X.509 certificate contains a malformed policy constraint and
policy processing is enabled, then a write lock will be taken twice
recursively. On some operating systems (most widely: Windows) this
results in a denial of service when the affected process hangs. Policy
processing being enabled on a publicly facing server is not considered
to be a common setup.
Policy processing is enabled by passing the `-policy`
argument to the command line utilities or by calling the
`X509_VERIFY_PARAM_set1_policies()` function.
Update (31 March 2023): The description of the policy processing enablement
was corrected based on CVE-2023-0466."
+ }
+ ],
+ "value": "If an X.509 certificate contains a malformed policy constraint and\npolicy processing is enabled, then a write lock will be taken twice\nrecursively. On some operating systems (most widely: Windows) this\nresults in a denial of service when the affected process hangs. Policy\nprocessing being enabled on a publicly facing server is not considered\nto be a common setup.\n\nPolicy processing is enabled by passing the `-policy`\nargument to the command line utilities or by calling the\n`X509_VERIFY_PARAM_set1_policies()` function.\n\nUpdate (31 March 2023): The description of the policy processing enablement\nwas corrected based on CVE-2023-0466."
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "Low"
+ },
+ "type": "https://www.openssl.org/policies/secpolicy.html#low"
+ }
+ }
+ ],
+ "problemTypes": [
+ {
+ "descriptions": [
+ {
+ "cweId": "CWE-667",
+ "description": "CWE-667 Improper Locking",
+ "lang": "en",
+ "type": "CWE"
+ }
+ ]
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "3a12439a-ef3a-4c79-92e6-6081a721f1e5",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "OpenSSL Advisory",
+ "tags": [
+ "vendor-advisory"
+ ],
+ "url": "https://www.openssl.org/news/secadv/20221213.txt"
+ },
+ {
+ "tags": [
+ "patch"
+ ],
+ "url": "https://github.com/openssl/openssl/commit/7725e7bfe6f2ce8146b6552b44e0d226be7638e7"
+ }
+ ],
+ "source": {
+ "discovery": "UNKNOWN"
+ },
+ "title": "X.509 Policy Constraints Double Locking",
+ "x_generator": {
+ "engine": "Vulnogram 0.1.0-dev"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "3a12439a-ef3a-4c79-92e6-6081a721f1e5",
+ "cveId": "CVE-2022-3996",
+ "requesterUserId": "00000000-0000-4000-9000-000000000000",
+ "serial": 1,
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.0"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2025-9231.json b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2025-9231.json
new file mode 100644
index 000000000..d3373f834
--- /dev/null
+++ b/vulnerabilities/tests/test_data/openssl/release_metadata/secjson/CVE-2025-9231.json
@@ -0,0 +1,150 @@
+{
+ "containers": {
+ "cna": {
+ "affected": [
+ {
+ "defaultStatus": "unaffected",
+ "product": "OpenSSL",
+ "vendor": "OpenSSL",
+ "versions": [
+ {
+ "lessThan": "3.5.4",
+ "status": "affected",
+ "version": "3.5.0",
+ "versionType": "semver"
+ },
+ {
+ "lessThan": "3.4.3",
+ "status": "affected",
+ "version": "3.4.0",
+ "versionType": "semver"
+ },
+ {
+ "lessThan": "3.3.5",
+ "status": "affected",
+ "version": "3.3.0",
+ "versionType": "semver"
+ },
+ {
+ "lessThan": "3.2.6",
+ "status": "affected",
+ "version": "3.2.0",
+ "versionType": "semver"
+ }
+ ]
+ }
+ ],
+ "credits": [
+ {
+ "lang": "en",
+ "type": "reporter",
+ "value": "Stanislav Fort (Aisle Research)"
+ },
+ {
+ "lang": "en",
+ "type": "remediation developer",
+ "value": "Stanislav Fort (Aisle Research)"
+ },
+ {
+ "lang": "en",
+ "type": "remediation developer",
+ "value": "Tomas Mraz"
+ }
+ ],
+ "datePublic": "2025-09-30T14:00:00.000Z",
+ "descriptions": [
+ {
+ "lang": "en",
+ "supportingMedia": [
+ {
+ "base64": false,
+ "type": "text/html",
+ "value": "Issue summary: A timing side-channel which could potentially allow remote
recovery of the private key exists in the SM2 algorithm implementation on 64 bit
ARM platforms.
Impact summary: A timing side-channel in SM2 signature computations on 64 bit
ARM platforms could allow recovering the private key by an attacker..
While remote key recovery over a network was not attempted by the reporter,
timing measurements revealed a timing signal which may allow such an attack.
OpenSSL does not directly support certificates with SM2 keys in TLS, and so
this CVE is not relevant in most TLS contexts. However, given that it is
possible to add support for such certificates via a custom provider, coupled
with the fact that in such a custom provider context the private key may be
recoverable via remote timing measurements, we consider this to be a Moderate
severity issue.
The FIPS modules in 3.5, 3.4, 3.3, 3.2, 3.1 and 3.0 are not affected by this
issue, as SM2 is not an approved algorithm."
+ }
+ ],
+ "value": "Issue summary: A timing side-channel which could potentially allow remote\nrecovery of the private key exists in the SM2 algorithm implementation on 64 bit\nARM platforms.\n\nImpact summary: A timing side-channel in SM2 signature computations on 64 bit\nARM platforms could allow recovering the private key by an attacker..\n\nWhile remote key recovery over a network was not attempted by the reporter,\ntiming measurements revealed a timing signal which may allow such an attack.\n\nOpenSSL does not directly support certificates with SM2 keys in TLS, and so\nthis CVE is not relevant in most TLS contexts. However, given that it is\npossible to add support for such certificates via a custom provider, coupled\nwith the fact that in such a custom provider context the private key may be\nrecoverable via remote timing measurements, we consider this to be a Moderate\nseverity issue.\n\nThe FIPS modules in 3.5, 3.4, 3.3, 3.2, 3.1 and 3.0 are not affected by this\nissue, as SM2 is not an approved algorithm."
+ }
+ ],
+ "metrics": [
+ {
+ "format": "other",
+ "other": {
+ "content": {
+ "text": "Moderate"
+ },
+ "type": "https://openssl-library.org/policies/general/security-policy/"
+ }
+ }
+ ],
+ "problemTypes": [
+ {
+ "descriptions": [
+ {
+ "cweId": "CWE-385",
+ "description": "CWE-385 Covert Timing Channel",
+ "lang": "en",
+ "type": "CWE"
+ }
+ ]
+ }
+ ],
+ "providerMetadata": {
+ "orgId": "00000000-0000-4000-9000-000000000000",
+ "shortName": "openssl"
+ },
+ "references": [
+ {
+ "name": "OpenSSL Advisory",
+ "tags": [
+ "vendor-advisory"
+ ],
+ "url": "https://openssl-library.org/news/secadv/20250930.txt"
+ },
+ {
+ "name": "3.5.4 git commit",
+ "tags": [
+ "patch"
+ ],
+ "url": "https://github.com/openssl/openssl/commit/fc47a2ec078912b3e914fab5734535e76c4820c2"
+ },
+ {
+ "name": "3.4.3 git commit",
+ "tags": [
+ "patch"
+ ],
+ "url": "https://github.com/openssl/openssl/commit/eed5adc9f969d77c94f213767acbb41ff923b6f4"
+ },
+ {
+ "name": "3.3.5 git commit",
+ "tags": [
+ "patch"
+ ],
+ "url": "https://github.com/openssl/openssl/commit/567f64386e43683888212226824b6a179885a0fe"
+ },
+ {
+ "name": "3.2.6 git commit",
+ "tags": [
+ "patch"
+ ],
+ "url": "https://github.com/openssl/openssl/commit/cba616c26ac8e7b37de5e77762e505ba5ca51698"
+ }
+ ],
+ "source": {
+ "discovery": "UNKNOWN"
+ },
+ "title": "Timing side-channel in SM2 algorithm on 64 bit ARM",
+ "x_generator": {
+ "engine": "Vulnogram 0.2.0"
+ }
+ }
+ },
+ "cveMetadata": {
+ "assignerOrgId": "00000000-0000-4000-9000-000000000000",
+ "cveId": "CVE-2025-9231",
+ "requesterUserId": "00000000-0000-4000-9000-000000000000",
+ "serial": 1,
+ "state": "PUBLISHED"
+ },
+ "dataType": "CVE_RECORD",
+ "dataVersion": "5.1"
+}
\ No newline at end of file
diff --git a/vulnerabilities/utils.py b/vulnerabilities/utils.py
index 999244498..81da99ff5 100644
--- a/vulnerabilities/utils.py
+++ b/vulnerabilities/utils.py
@@ -206,28 +206,38 @@ def __get__(self, owner_self, owner_cls):
return self.fget(owner_cls)
-def get_item(dictionary: dict, *attributes):
+def get_item(entity: Union[dict, list], *attributes):
"""
- Return `item` by going through all the `attributes` present in the `dictionary`
+ Return `item` by going through all the `attributes` present in the `dictionary/list`
- Do a DFS for the `item` in the `dictionary` by traversing the `attributes`
+ Do a DFS for the `item` in the `dictionary/list` by traversing the `attributes`
and return None if can not traverse through the `attributes`
For example:
+ >>> assert get_item({'a': {'b': {'c': 'd'}}}, 'a', 'b', 'c') == 'd'
+ >>> assert get_item({'a': [{'b': {'c': 'd'}}]}, 'a', 0, 'b') == {'c': 'd'}
+ >>> assert get_item(['b', ['c', ['d']]], 1, 1, 0) == 'd'
>>> get_item({'a': {'b': {'c': 'd'}}}, 'a', 'b', 'c')
'd'
>>> assert(get_item({'a': {'b': {'c': 'd'}}}, 'a', 'b', 'e')) == None
"""
for attribute in attributes:
- if not dictionary:
+ if not entity:
return
- if not isinstance(dictionary, dict):
- logger.error("dictionary must be of type `dict`")
+ if not isinstance(entity, (dict, list)):
+ logger.error(f"Entity must be of type `dict` or `list` not {type(entity)}")
return
- if attribute not in dictionary:
- logger.error(f"Missing attribute {attribute} in {dictionary}")
+ if isinstance(entity, dict) and attribute not in entity:
+ logger.error(f"Missing attribute {attribute} in {entity}")
return
- dictionary = dictionary[attribute]
- return dictionary
+ if isinstance(entity, list) and not isinstance(attribute, int):
+ logger.error(f"List indices must be integers not {type(attribute)}")
+ return
+ if isinstance(entity, list) and len(entity) <= attribute:
+ logger.error(f"Index {attribute} out of range for {entity}")
+ return
+
+ entity = entity[attribute]
+ return entity
class GitHubTokenError(Exception):