diff --git a/requirements-dev.txt b/requirements-dev.txt
index 4e6b8bc5f..75966c993 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,3 +1,4 @@
+aboutcode.federated==1.0.3
aboutcode.pipeline==0.1.0
alabaster==0.7.16
altcha==1.0.0
diff --git a/requirements.txt b/requirements.txt
index a138c813e..6cbf5c520 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
+aboutcode.federated==1.0.3
aboutcode.pipeline==0.1.0
altcha==1.0.0
asgiref==3.8.1
diff --git a/vulnerabilities/migrations/0138_fix_malformed_cvss_vector.py b/vulnerabilities/migrations/0138_fix_malformed_cvss_vector.py
new file mode 100644
index 000000000..3cdcf5739
--- /dev/null
+++ b/vulnerabilities/migrations/0138_fix_malformed_cvss_vector.py
@@ -0,0 +1,41 @@
+# Generated by Django 5.2.11 on 2026-06-30 08:15
+
+from django.db import migrations
+from django.db.models import Value
+from django.db.models.functions import Concat
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("vulnerabilities", "0137_alter_pipelineschedule_run_interval"),
+ ]
+
+ def fix_malformed_cvss_severity(apps, schema_editor):
+ AdvisorySeverity = apps.get_model("vulnerabilities", "AdvisorySeverity")
+
+ AdvisorySeverity.objects.filter(
+ scoring_system="cvssv3.1",
+ scoring_elements__startswith="CVSS:3.0/",
+ ).update(scoring_system="cvssv3")
+
+ AdvisorySeverity.objects.filter(
+ scoring_system="cvssv3",
+ scoring_elements__isnull=False,
+ ).exclude(
+ scoring_elements="",
+ ).exclude(
+ scoring_elements__startswith="CVSS:3.0/",
+ ).update(
+ scoring_elements=Concat(
+ Value("CVSS:3.0/"),
+ "scoring_elements",
+ )
+ )
+
+ operations = [
+ migrations.RunPython(
+ fix_malformed_cvss_severity,
+ reverse_code=migrations.RunPython.noop,
+ ),
+ ]
diff --git a/vulnerabilities/pipelines/v2_importers/mozilla_importer.py b/vulnerabilities/pipelines/v2_importers/mozilla_importer.py
index 2fa6f5002..0dc7d5512 100644
--- a/vulnerabilities/pipelines/v2_importers/mozilla_importer.py
+++ b/vulnerabilities/pipelines/v2_importers/mozilla_importer.py
@@ -46,6 +46,7 @@ class MozillaImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
spdx_license_expression = "MPL-2.0"
license_url = "https://github.com/mozilla/foundation-security-advisories/blob/master/LICENSE"
+ exclude_from_package_todo = True
precedence = 200
@classmethod
diff --git a/vulnerabilities/pipelines/v2_importers/postgresql_importer.py b/vulnerabilities/pipelines/v2_importers/postgresql_importer.py
index 72ac1f3d3..0a33baee6 100644
--- a/vulnerabilities/pipelines/v2_importers/postgresql_importer.py
+++ b/vulnerabilities/pipelines/v2_importers/postgresql_importer.py
@@ -14,7 +14,6 @@
from bs4 import BeautifulSoup
from packageurl import PackageURL
from univers.version_range import GenericVersionRange
-from univers.versions import GenericVersion
from vulnerabilities import severity_systems
from vulnerabilities.importer import AdvisoryDataV2
@@ -122,9 +121,13 @@ def to_advisories(self, data, url):
if link.startswith("/"):
link = urlparse.urljoin("https://www.postgresql.org/", link)
if "support/security/CVE" in link and vector_link_tag:
+ if "v3-calculator" not in vector_link_tag["href"]:
+ continue
+
parsed_link = urlparse.urlparse(vector_link_tag["href"])
cvss3_vector = urlparse.parse_qs(parsed_link.query).get("vector", [""])[0]
cvss3_base_score = vector_link_tag.text
+ cvss3_vector = "CVSS:3.0/" + cvss3_vector.removeprefix("CVSS:3.0/")
severities.append(
VulnerabilitySeverity(
system=severity_systems.CVSSV3,
diff --git a/vulnerabilities/pipes/osv_v2.py b/vulnerabilities/pipes/osv_v2.py
index 0f8a29e78..4c5441dd9 100644
--- a/vulnerabilities/pipes/osv_v2.py
+++ b/vulnerabilities/pipes/osv_v2.py
@@ -269,9 +269,11 @@ def get_severities(raw_data, url) -> Iterable[VulnerabilitySeverity]:
continue
severity_type = OSV_TO_VCIO_SEVERITY_MAP.get(severity_type, severity_type)
- system = SCORING_SYSTEMS[severity_type]
+ if value.lower().startswith("cvss:3.0/"):
+ severity_type = "cvssv3"
- if severity_type in ["cvssv3.1", "cvssv4"]:
+ system = SCORING_SYSTEMS[severity_type]
+ if severity_type in ["cvssv3", "cvssv3.1", "cvssv4"]:
scoring_element = value
valid_vector = value[:-1] if value and value.endswith("/") else value
value = system.compute(valid_vector)
diff --git a/vulnerabilities/tests/pipelines/v2_importers/test_postgresql_importer_v2.py b/vulnerabilities/tests/pipelines/v2_importers/test_postgresql_importer_v2.py
index 5235a2e47..afe646b37 100644
--- a/vulnerabilities/tests/pipelines/v2_importers/test_postgresql_importer_v2.py
+++ b/vulnerabilities/tests/pipelines/v2_importers/test_postgresql_importer_v2.py
@@ -38,7 +38,7 @@
10.0, 10.1 |
10.2 |
- 9.8 |
+ 9.8 |
Description of the issue |
@@ -113,7 +113,7 @@ def test_cvss_parsing(mock_get, importer):
severity = advisories[0].severities[0]
assert severity.system.identifier == "cvssv3"
assert severity.value == "9.8"
- assert "AV:N/AC:L/PR:N/UI:N" in severity.scoring_elements
+ assert "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" == severity.scoring_elements
@patch("vulnerabilities.pipelines.v2_importers.postgresql_importer.requests.get")
diff --git a/vulnerabilities/tests/pipes/test_osv_v2.py b/vulnerabilities/tests/pipes/test_osv_v2.py
index 50f865697..c5d7ffe97 100644
--- a/vulnerabilities/tests/pipes/test_osv_v2.py
+++ b/vulnerabilities/tests/pipes/test_osv_v2.py
@@ -293,3 +293,13 @@ def test_to_advisories_pypa7(self):
)
result = imported_data.to_dict()
util_tests.check_results_against_json(result, expected_file)
+
+ def test_to_advisories_pypa8_cvss_v3_0_parsing(self):
+ with open(os.path.join(TEST_DATA, "pypa/pypa-8.yaml")) as f:
+ mock_response = saneyaml.load(f)
+ expected_file = os.path.join(TEST_DATA, "pypa/pypa-expected-8.json")
+ imported_data = parse_advisory_data_v3(
+ mock_response, "pypi", advisory_url="https://test.com", advisory_text=""
+ )
+ result = imported_data.to_dict()
+ util_tests.check_results_against_json(result, expected_file, regen=True)
diff --git a/vulnerabilities/tests/test_data/osv_test/pypa/pypa-8.yaml b/vulnerabilities/tests/test_data/osv_test/pypa/pypa-8.yaml
new file mode 100644
index 000000000..2e3592973
--- /dev/null
+++ b/vulnerabilities/tests/test_data/osv_test/pypa/pypa-8.yaml
@@ -0,0 +1,56 @@
+id: PYSEC-2024-26
+modified: 2024-02-06T20:20:18.162431Z
+published: 2024-01-29T23:15:00Z
+aliases:
+- CVE-2024-23829
+- GHSA-8qpw-xqxj-h4r2
+details: aiohttp is an asynchronous HTTP client/server framework for asyncio and Python.
+ Security-sensitive parts of the Python HTTP parser retained minor differences in
+ allowable character sets, that must trigger error handling to robustly match frame
+ boundaries of proxies in order to protect against injection of additional requests.
+ Additionally, validation could trigger exceptions that were not handled consistently
+ with processing of other malformed input. Being more lenient than internet standards
+ require could, depending on deployment environment, assist in request smuggling.
+ The unhandled exception could cause excessive resource consumption on the application
+ server and/or its logging facilities. This vulnerability exists due to an incomplete
+ fix for CVE-2023-47627. Version 3.9.2 fixes this vulnerability.
+affected:
+- package:
+ ecosystem: PyPI
+ name: aiohttp
+ purl: pkg:pypi/aiohttp
+ ranges:
+ - type: GIT
+ events:
+ - introduced: "0"
+ - fixed: 33ccdfb0a12690af5bb49bda2319ec0907fa7827
+ repo: https://github.com/aio-libs/aiohttp
+ - type: ECOSYSTEM
+ events:
+ - introduced: "0"
+ - fixed: 3.9.2
+ versions:
+ - "0.1"
+ - 0.10.0
+ - 0.10.1
+ - 0.10.2
+ - 0.11.0
+ - 0.12.0
+ - 0.13.0
+ - 0.13.1
+severity:
+- type: CVSS_V3
+ score: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L
+references:
+- type: EVIDENCE
+ url: https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2
+- type: FIX
+ url: https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2
+- type: ADVISORY
+ url: https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2
+- type: FIX
+ url: https://github.com/aio-libs/aiohttp/pull/8074
+- type: FIX
+ url: https://github.com/aio-libs/aiohttp/commit/33ccdfb0a12690af5bb49bda2319ec0907fa7827
+- type: ARTICLE
+ url: https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/XXWVZIVAYWEBHNRIILZVB3R3SDQNNAA7/
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/osv_test/pypa/pypa-expected-8.json b/vulnerabilities/tests/test_data/osv_test/pypa/pypa-expected-8.json
new file mode 100644
index 000000000..bd963c53d
--- /dev/null
+++ b/vulnerabilities/tests/test_data/osv_test/pypa/pypa-expected-8.json
@@ -0,0 +1,74 @@
+{
+ "advisory_id": "PYSEC-2024-26",
+ "aliases": [
+ "CVE-2024-23829",
+ "GHSA-8qpw-xqxj-h4r2"
+ ],
+ "summary": "aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. Security-sensitive parts of the Python HTTP parser retained minor differences in allowable character sets, that must trigger error handling to robustly match frame boundaries of proxies in order to protect against injection of additional requests. Additionally, validation could trigger exceptions that were not handled consistently with processing of other malformed input. Being more lenient than internet standards require could, depending on deployment environment, assist in request smuggling. The unhandled exception could cause excessive resource consumption on the application server and/or its logging facilities. This vulnerability exists due to an incomplete fix for CVE-2023-47627. Version 3.9.2 fixes this vulnerability.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "pypi",
+ "namespace": "",
+ "name": "aiohttp",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:pypi/0.1|0.10.0|0.10.1|0.10.2|0.11.0|0.12.0|0.13.0|0.13.1",
+ "fixed_version_range": "vers:pypi/3.9.2",
+ "introduced_by_commit_patches": [],
+ "fixed_by_commit_patches": [
+ {
+ "vcs_url": "https://github.com/aio-libs/aiohttp",
+ "commit_hash": "33ccdfb0a12690af5bb49bda2319ec0907fa7827",
+ "patch_text": null,
+ "patch_checksum": null
+ }
+ ]
+ }
+ ],
+ "references": [
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2"
+ },
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2"
+ },
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://github.com/aio-libs/aiohttp/security/advisories/GHSA-8qpw-xqxj-h4r2"
+ },
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://github.com/aio-libs/aiohttp/pull/8074"
+ },
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://github.com/aio-libs/aiohttp/commit/33ccdfb0a12690af5bb49bda2319ec0907fa7827"
+ },
+ {
+ "reference_id": "",
+ "reference_type": "",
+ "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/XXWVZIVAYWEBHNRIILZVB3R3SDQNNAA7/"
+ }
+ ],
+ "patches": [],
+ "severities": [
+ {
+ "system": "cvssv3",
+ "value": "6.5",
+ "scoring_elements": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L"
+ }
+ ],
+ "date_published": "2024-01-29T23:15:00+00:00",
+ "weaknesses": [],
+ "url": "https://test.com"
+}
\ No newline at end of file