diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py
index 3f429f669..f4fd3f461 100644
--- a/vulnerabilities/importers/__init__.py
+++ b/vulnerabilities/importers/__init__.py
@@ -37,6 +37,7 @@
from vulnerabilities.pipelines import alpine_linux_importer
from vulnerabilities.pipelines import github_importer
from vulnerabilities.pipelines import gitlab_importer
+from vulnerabilities.pipelines import isc_importer
from vulnerabilities.pipelines import nginx_importer
from vulnerabilities.pipelines import npm_importer
from vulnerabilities.pipelines import nvd_importer
@@ -44,6 +45,7 @@
from vulnerabilities.pipelines import pysec_importer
IMPORTERS_REGISTRY = [
+ isc_importer.ISCImporterPipeline,
openssl.OpensslImporter,
redhat.RedhatImporter,
debian.DebianImporter,
diff --git a/vulnerabilities/pipelines/isc_importer.py b/vulnerabilities/pipelines/isc_importer.py
new file mode 100644
index 000000000..85ee5a0e9
--- /dev/null
+++ b/vulnerabilities/pipelines/isc_importer.py
@@ -0,0 +1,195 @@
+#
+# 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
+import re
+from datetime import timezone
+from typing import Iterable
+
+import requests
+from bs4 import BeautifulSoup
+from dateutil import parser as dateparser
+from packageurl import PackageURL
+from univers.version_range import GenericVersionRange
+
+from vulnerabilities.importer import AdvisoryData
+from vulnerabilities.importer import AffectedPackage
+from vulnerabilities.importer import Reference
+from vulnerabilities.importer import VulnerabilitySeverity
+from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline
+from vulnerabilities.severity_systems import CVSSV31
+from vulnerabilities.utils import get_item
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+class ISCImporterPipeline(VulnerableCodeBaseImporterPipeline):
+ """Collect Advisories from ISC"""
+
+ pipeline_id = "isc_importer"
+ spdx_license_expression = "ISC"
+ license_url = "https://opensource.org/license/isc-license-txt"
+ root_url = "https://kb.isc.org/docs/aa-00913"
+ importer_name = "ISC Importer"
+
+ def __init__(self):
+ super().__init__()
+ self.headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
+ }
+
+ @classmethod
+ def steps(cls):
+ return (
+ cls.collect_and_store_advisories,
+ cls.import_new_advisories,
+ )
+
+ # num of advisories
+ def advisories_count(self) -> int:
+ return len(fetch_advisory_data(self.root_url, self.headers))
+
+ # parse the response data
+ def collect_advisories(self) -> Iterable[AdvisoryData]:
+ advisory_links = fetch_advisory_links(self.root_url, self.headers)
+
+ for link in advisory_links:
+ advisory_data = fetch_advisory_data(link, self.headers)
+ yield to_advisory_data(advisory_data)
+
+
+def fetch_advisory_links(url, headers):
+ """Fetches the advisory links listed on the URL,returns a list"""
+ reponse = requests.get(url, headers=headers)
+ r_content = reponse.content
+
+ soup = BeautifulSoup(r_content, "html.parser")
+
+ hyperlink_wrapper = soup.find("h4")
+ table = hyperlink_wrapper.find_next_sibling("table")
+ advisory_links = []
+ # Extract the link from the 3rd
in each row
+ for row in table.find_all("tr"): # Iterate through all rows
+ cells = row.find_all("td") # Find all elements in the row
+ if len(cells) >= 3: # Ensure there are at least 3 elements
+ third_td = cells[2] # Get the 3rd element
+ link = third_td.find("a") # Find the tag inside the 3rd
+ if link["href"].startswith("https") == False:
+ advisory_links.append("https://kb.isc.org" + link["href"])
+ else:
+ advisory_links.append(link["href"])
+
+ return advisory_links
+
+
+def fetch_advisory_data(advisory_link, headers):
+ """Fetches advisory data,returns a dict"""
+ reponse = requests.get(advisory_link, headers=headers)
+ r_content = reponse.content
+
+ soup = BeautifulSoup(r_content, "html.parser")
+
+ soup = soup.find(id="articleContent")
+
+ # Extract CVE Link
+ cve_link = soup.find("a")["href"]
+ cve = soup.find("a").text
+
+ # Extract Posting Date
+ posting_date_tag = soup.find("strong", text=re.compile(r"Posting date:"))
+ posting_date = posting_date_tag.parent.text.replace("Posting date:", "").strip()
+
+ # Extract Versions Affected
+ versions_affected = []
+ for li in soup.find_all("li", text=re.compile(r"\d+\.\d+\.\d+")):
+ version_range = li.text.strip()
+ if "->" in version_range:
+ start, end = version_range.split("->")
+ versions_affected.append([start.strip(), end.strip()])
+
+ # Extract Severity
+ severity_tag = soup.find("strong", text=re.compile(r"Severity:"))
+ severity = severity_tag.parent.text.replace("Severity:", "").strip()
+
+ # Extract Description
+ description_tag = soup.find("strong", text=re.compile(r"Description:"))
+ description = description_tag.find_next("p").text.strip()
+
+ # Extract CVSS Score
+ cvss_score_tag = soup.find("strong", text=re.compile(r"CVSS Score:"))
+ cvss_score = cvss_score_tag.parent.text.replace("CVSS Score:", "").strip()
+
+ # Extract Fixed Versions (from Solution area)
+ fixed_versions = []
+ solution_area = soup.find("strong", text=re.compile(r"Solution:"))
+ for li in solution_area.find_next("ul").find_all("li"):
+ fixed_versions.append(li.text.strip())
+
+ return {
+ "cve_link": cve_link,
+ "cve": cve,
+ "date_published": posting_date,
+ "severity": severity,
+ "Affected": versions_affected,
+ "Fixed": fixed_versions,
+ "Score": cvss_score,
+ "Description": description,
+ }
+
+
+def to_advisory_data(raw_data) -> AdvisoryData:
+ """Parses extracted data to Advisory Data"""
+ # alias
+ alias = get_item(raw_data, "cve")
+
+ # fixed versions
+ fixed_versions = get_item(raw_data, "Fixed")
+
+ # affected packages
+ affected_packages = []
+ affected_versions_list = get_item(raw_data, "Affected") # list of list of affected versions
+ for affected_versions, fixed_version in zip(affected_versions_list, fixed_versions):
+ affected_packages.append(
+ AffectedPackage(
+ package=PackageURL(type="isc", name="BIND"),
+ affected_version_range=GenericVersionRange(affected_versions),
+ fixed_version=fixed_version,
+ )
+ )
+
+ # score
+ score = get_item(raw_data, "Score")
+ severity = VulnerabilitySeverity(
+ system=CVSSV31, value=score, scoring_elements="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
+ )
+ # Reference
+ references = []
+ references.append(
+ Reference(
+ severities=[severity],
+ reference_id=alias,
+ url=get_item(raw_data, "cve_link"),
+ )
+ )
+
+ # description
+ description = get_item(raw_data, "Description")
+
+ # date published
+ date_published = get_item(raw_data, "date_published")
+ date_published = dateparser.parse(date_published, yearfirst=True).replace(tzinfo=timezone.utc)
+
+ return AdvisoryData(
+ aliases=alias,
+ summary=description,
+ affected_packages=affected_packages,
+ references=references,
+ url=f"https://kb.isc.org/v1/docs/{get_item(raw_data,'cve').lower()}",
+ date_published=date_published,
+ )
diff --git a/vulnerabilities/tests/pipelines/test_isc_importer_pipeline.py b/vulnerabilities/tests/pipelines/test_isc_importer_pipeline.py
new file mode 100644
index 000000000..cd77d112c
--- /dev/null
+++ b/vulnerabilities/tests/pipelines/test_isc_importer_pipeline.py
@@ -0,0 +1,92 @@
+#
+# 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 import mock
+from unittest.mock import patch
+
+from vulnerabilities.pipelines import isc_importer
+
+TEST_DATA = Path(__file__).parent.parent / "test_data" / "isc" / "isc_expected.json"
+HTML_DATA = Path(__file__).parent.parent / "test_data" / "isc" / "isc_test.html"
+LINKS_DATA = Path(__file__).parent.parent / "test_data" / "isc" / "isc_links.html"
+
+headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
+}
+
+
+def test_fetch_advisory_links():
+ """Test fetching advisory links from ISC security advisories page."""
+ with open(LINKS_DATA) as f:
+ mock_html_content = f.read()
+
+ with mock.patch("requests.get") as mock_get:
+ mock_get.return_value.content = mock_html_content.encode()
+ links = isc_importer.fetch_advisory_links("https://kb.isc.org/docs/aa-00913", headers)
+
+ assert "https://kb.isc.org/v1/docs/cve-2024-12705" in links
+
+
+def test_fetch_advisory_data():
+ """Test fetching and parsing advisory data from an ISC advisory page."""
+ with open(HTML_DATA) as f:
+ mock_html_content = f.read()
+
+ with mock.patch("requests.get") as mock_get:
+ mock_get.return_value.content = mock_html_content.encode()
+ advisory_data = isc_importer.fetch_advisory_data(
+ "https://kb.isc.org/docs/cve-2024-12705", headers
+ )
+
+ assert advisory_data["cve"] == "CVE-2024-12705"
+ assert advisory_data["Score"] == "7.5"
+ assert advisory_data["severity"] == "High"
+ assert "Clients using DNS-over-HTTPS" in advisory_data["Description"]
+ assert set(advisory_data["Fixed"]) == {"9.18.33", "9.20.5", "9.21.4"}
+ assert len(advisory_data["Affected"]) == 4
+
+
+@mock.patch("requests.get")
+def test_isc_importer_pipeline_collect_advisories(mock_get):
+ """Test the `collect_advisories` method in `ISCImporterPipeline`."""
+ with open(HTML_DATA) as f:
+ mock_html_content = f.read()
+
+ mock_get.return_value.content = mock_html_content.encode()
+ pipeline = isc_importer.ISCImporterPipeline()
+
+ with mock.patch(
+ "vulnerabilities.pipelines.isc_importer.fetch_advisory_links"
+ ) as mock_links, mock.patch(
+ "vulnerabilities.pipelines.isc_importer.fetch_advisory_data"
+ ) as mock_data:
+ mock_links.return_value = ["https://kb.isc.org/docs/cve-2024-12705"]
+ mock_data.return_value = {
+ "cve": "CVE-2024-12705",
+ "cve_link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-12705",
+ "Score": "7.5",
+ "severity": "High",
+ "Affected": [["9.18.0", "9.18.32"], ["9.20.0", "9.20.4"], ["9.21.0", "9.21.3"]],
+ "Fixed": ["9.18.33", "9.20.5", "9.21.4"],
+ "Description": "DNS-over-HTTPS issue.",
+ "date_published": "2025-01-29T00:00:00+00:00",
+ }
+ generator = pipeline.collect_advisories()
+ advisories = list(generator)
+
+ assert len(advisories) == 1
+ advisory = advisories[0]
+
+ assert advisory.aliases == "CVE-2024-12705"
+ assert "DNS-over-HTTPS issue." in advisory.summary
+ assert (
+ advisory.references[0].url
+ == "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-12705"
+ )
diff --git a/vulnerabilities/tests/test_data/isc/isc_expected.json b/vulnerabilities/tests/test_data/isc/isc_expected.json
new file mode 100644
index 000000000..0220fb810
--- /dev/null
+++ b/vulnerabilities/tests/test_data/isc/isc_expected.json
@@ -0,0 +1,59 @@
+{
+ "aliases": "CVE-2024-12705",
+ "summary": "Clients using DNS-over-HTTPS (DoH) can exhaust a DNS resolver's CPU and/or memory by flooding it with crafted valid or invalid HTTP/2 traffic.",
+ "affected_packages": [
+ {
+ "package": {
+ "type": "isc",
+ "namespace": "",
+ "name": "BIND",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:generic/9.18.0|9.18.32",
+ "fixed_version": "9.18.33"
+ },
+ {
+ "package": {
+ "type": "isc",
+ "namespace": "",
+ "name": "BIND",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:generic/9.20.0|9.20.4",
+ "fixed_version": "9.20.5"
+ },
+ {
+ "package": {
+ "type": "isc",
+ "namespace": "",
+ "name": "BIND",
+ "version": "",
+ "qualifiers": "",
+ "subpath": ""
+ },
+ "affected_version_range": "vers:generic/9.21.0|9.21.3",
+ "fixed_version": "9.21.4"
+ }
+ ],
+ "references": [
+ {
+ "reference_id": "CVE-2024-12705",
+ "reference_type": "",
+ "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-12705",
+ "severities": [
+ {
+ "system": "cvssv3.1",
+ "value": "7.5",
+ "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
+ }
+ ]
+ }
+ ],
+ "date_published": "2025-01-29T00:00:00+00:00",
+ "weaknesses": [],
+ "url": "https://kb.isc.org/v1/docs/cve-2024-12705"
+}
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/isc/isc_links.html b/vulnerabilities/tests/test_data/isc/isc_links.html
new file mode 100644
index 000000000..14671bdfb
--- /dev/null
+++ b/vulnerabilities/tests/test_data/isc/isc_links.html
@@ -0,0 +1,252 @@
+Listing of Vulnerabilities affecting current branches of BIND
+
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/isc/isc_test.html b/vulnerabilities/tests/test_data/isc/isc_test.html
new file mode 100644
index 000000000..65ccb3f1c
--- /dev/null
+++ b/vulnerabilities/tests/test_data/isc/isc_test.html
@@ -0,0 +1,68 @@
+CVE: CVE-2024-12705
+Title: DNS-over-HTTPS implementation suffers from multiple issues under heavy query load
+Document version: 2.0
+Posting date: 29 January 2025
+Program impacted: BIND 9
+Versions affected:
+BIND
+
+9.18.0 -> 9.18.32
+9.20.0 -> 9.20.4
+9.21.0 -> 9.21.3
+
+(Versions prior to 9.18.27 were not assessed.)
+BIND Supported Preview Edition
+
+9.18.11-S1 -> 9.18.32-S1
+
+(Versions prior to 9.18.27-S1 were not assessed.)
+Severity: High
+Exploitable: Remotely
+Description:
+Clients using DNS-over-HTTPS (DoH) can exhaust a DNS resolver's CPU and/or memory by flooding it with crafted valid or invalid HTTP/2 traffic.
+Impact:
+By flooding a target resolver with HTTP/2 traffic and exploiting this flaw, an attacker could overwhelm the server, causing high CPU and/or memory usage and preventing other clients from establishing DoH connections. This would significantly impair the resolver's performance and effectively deny legitimate clients access to the DNS resolution service.
+
+CVSS Score: 7.5
+CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
+For more information on the Common Vulnerability Scoring System and to obtain your specific environmental score please visit: https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H&version=3.1 .
+Workarounds:
+The issue affects only the DNS-over-HTTPS protocol and does not apply to instances where DoH is not enabled.
+Active exploits:
+We are not aware of any active exploits.
+Solution:
+Upgrade to the patched release most closely related to your current version of BIND 9:
+
+9.18.33
+9.20.5
+9.21.4
+
+BIND Supported Preview Edition is a special feature preview branch of BIND provided to eligible ISC support customers.
+
+Acknowledgments:
+ISC would like to thank Jean-François Billaud for bringing this vulnerability to our attention.
+Document revision history:
+
+1.0 Early Notification, 22 January 2025
+2.0 Public disclosure, 29 January 2025
+
+Related documents:
+See our BIND 9 Security Vulnerability Matrix for a complete listing of security vulnerabilities and versions affected.
+Do you still have questions? Questions regarding this advisory should be mailed to bind-security@isc.org or posted as confidential GitLab issues at https://gitlab.isc.org/isc-projects/bind9/-/issues/new?issue[confidential]=true .
+Note:
+ISC patches only currently supported versions. When possible we indicate EOL versions affected. For current information on which versions are actively supported, please see https://www.isc.org/download/ .
+ISC Security Vulnerability Disclosure Policy:
+Details of our current security advisory policy and practice can be found in the ISC Software Defect and Security Vulnerability Disclosure Policy at https://kb.isc.org/docs/aa-00861 .
+The Knowledgebase article https://kb.isc.org/docs/cve-2024-12705 is the complete and official security advisory document.
+Legal Disclaimer:
+Internet Systems Consortium (ISC) is providing this notice on an "AS IS" basis. No warranty or guarantee of any kind is expressed in this notice and none should be implied. ISC expressly excludes and disclaims any warranties regarding this notice or materials referred to in this notice, including, without limitation, any implied warranty of merchantability, fitness for a particular purpose, absence of hidden defects, or of non-infringement. Your use or reliance on this notice or materials referred to in this notice is at your own risk. ISC may change this notice at any time. A stand-alone copy or paraphrase of the text of this document that omits the document URL is an uncontrolled copy. Uncontrolled copies may lack important information, be out of date, or contain factual errors.
+
\ No newline at end of file