Skip to content
Open
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ repos:
hooks:
- id: pyupgrade
exclude: ^fuzz/generated/
args: ["--py38-plus"]
args: ["--py39-plus"]

- repo: https://github.com/pycqa/flake8
rev: 7.3.0
Expand Down
5 changes: 1 addition & 4 deletions cve_bin_tool/checkers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
from importlib import metadata as importlib_metadata
else:
import importlib_metadata
if sys.version_info >= (3, 9):
import importlib.resources as resources
else:
import importlib_resources as resources
import importlib.resources as resources

__all__ = [
"Checker",
Expand Down
14 changes: 10 additions & 4 deletions cve_bin_tool/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,18 @@ def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)


def main(argv=None):
"""Scan a binary file for certain open source libraries that may have CVEs"""
if sys.version_info < (3, 8):
def check_python_version() -> None:
"""Check if the current Python version is supported. Raise OSError if not."""
if sys.version_info < (3, 9):
raise OSError(
"Python no longer provides security updates for version 3.7 as of June 2023. Please upgrade to python 3.8+ to use CVE Binary Tool."
"Python no longer provides security updates for version 3.8 as of October 2024. "
"Please upgrade to Python 3.9+ to use CVE Binary Tool."
)


def main(argv=None):
"""Scan a binary file for certain open source libraries that may have CVEs"""
check_python_version()
argv = argv or sys.argv

# Reset logger level to info
Expand Down
2 changes: 1 addition & 1 deletion cve_bin_tool/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import sys
from collections import ChainMap
from collections.abc import Mapping
from logging import Logger
from pathlib import Path
from typing import Mapping

if sys.version_info >= (3, 11):
import tomllib as toml
Expand Down
5 changes: 1 addition & 4 deletions cve_bin_tool/csv2cve.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

def main(argv: list[str] | None = None):
"""Used to scan a .csv file that lists the dependencies."""
if sys.version_info < (3, 8):
raise OSError(
"Python no longer provides security updates for version 3.7 as of June 2023. Please upgrade to python 3.8+ to use CVE Binary Tool."
)
cli.check_python_version()
logger: logging.Logger = LOGGER.getChild("CSV2CVE")
argv = argv or sys.argv
if len(argv) < 2:
Expand Down
16 changes: 8 additions & 8 deletions cve_bin_tool/cve_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from logging import Logger
from pathlib import Path
from string import ascii_lowercase
from typing import DefaultDict, Dict, List
from typing import DefaultDict

from rich.console import Console

Expand All @@ -28,12 +28,12 @@ class CVEScanner:
products_with_cve: int
products_without_cve: int
all_cve_data: DefaultDict[ProductInfo, CVEData]
all_cve_version_info: Dict[str, VersionInfo]
all_cve_version_info: dict[str, VersionInfo]

RANGE_UNSET: str = ""
dbname: str = str(Path(DISK_LOCATION_DEFAULT) / DBNAME)
CONSOLE: Console = Console(file=sys.stderr, theme=cve_theme)
ALPHA_TO_NUM: Dict[str, int] = dict(zip(ascii_lowercase, range(26)))
ALPHA_TO_NUM: dict[str, int] = dict(zip(ascii_lowercase, range(26)))

def __init__(
self,
Expand All @@ -44,8 +44,8 @@ def __init__(
logger: Logger = None,
error_mode: ErrorMode = ErrorMode.TruncTrace,
check_exploits: bool = False,
exploits_list: List[str] = [],
disabled_sources: List[str] = [],
exploits_list: list[str] = [],
disabled_sources: list[str] = [],
no_scan: bool = False,
):
self.score = score
Expand Down Expand Up @@ -229,10 +229,10 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData):
)

product_info_data: CVEData | None = self.all_cve_data.get(product_info)
prev_cves: List[CVE] = (
prev_cves: list[CVE] = (
product_info_data.get("cves", []) if product_info_data is not None else [] # type: ignore
)
cves: List[CVE] = []
cves: list[CVE] = []

# Go through and get all the severities
if cve_list:
Expand Down Expand Up @@ -403,7 +403,7 @@ def filter_triage_data(self):
Filter out triage data that is not relevant to the CVEs found,
specifically those marked as NotAffected or FalsePositives.
"""
to_delete: List[ProductInfo] = []
to_delete: list[ProductInfo] = []

for product_info, cve_data in self.all_cve_data.items():
original_cves = cve_data["cves"]
Expand Down
7 changes: 1 addition & 6 deletions cve_bin_tool/data_sources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

from __future__ import annotations

import sys
import importlib.resources as resources
from abc import ABC, abstractmethod

if sys.version_info >= (3, 9):
import importlib.resources as resources
else:
import importlib_resources as resources


class Data_Source(ABC):
@abstractmethod
Expand Down
2 changes: 1 addition & 1 deletion cve_bin_tool/helper_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import sys
import textwrap
from collections import ChainMap
from collections.abc import MutableMapping
from logging import Logger
from pathlib import Path
from typing import MutableMapping

from rich import print as rprint
from rich.console import Console
Expand Down
7 changes: 4 additions & 3 deletions cve_bin_tool/input_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
import csv
import json
from collections import defaultdict
from collections.abc import Iterable
from logging import Logger
from pathlib import Path
from typing import Any, DefaultDict, Dict, Iterable, Set, Union
from typing import Any, DefaultDict, Union

from cve_bin_tool.cvedb import CVEDB
from cve_bin_tool.error_handler import (
Expand All @@ -27,7 +28,7 @@
from cve_bin_tool.util import ProductInfo, Remarks

# TriageData is dictionary of cve_number mapped to dictionary of remarks, comments and custom severity
TriageData = Dict[str, Union[Dict[str, Any], Set[str]]]
TriageData = dict[str, Union[dict[str, Any], set[str]]]


class InputEngine:
Expand Down Expand Up @@ -135,7 +136,7 @@ def input_json(self) -> None:

self.parse_data(set(json_data[0].keys()), json_data)

def parse_data(self, fields: Set[str], data: Iterable) -> None:
def parse_data(self, fields: set[str], data: Iterable) -> None:
"""
Parses common data structure for CSV and JSON input formats.

Expand Down
10 changes: 5 additions & 5 deletions cve_bin_tool/package_list_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from logging import Logger
from pathlib import Path
from subprocess import PIPE, run
from typing import Any, Dict, List
from typing import Any

import distro

Expand Down Expand Up @@ -69,10 +69,10 @@ def __init__(
self.logger = logger

self.error_mode = error_mode
self.parsed_data_without_vendor: Dict[Any, Any] = defaultdict(dict)
self.parsed_data_with_vendor: Dict[Any, Any] = defaultdict(dict)
self.package_names_with_vendor: List[Any] = []
self.package_names_without_vendor: List[Any] = []
self.parsed_data_without_vendor: dict[Any, Any] = defaultdict(dict)
self.parsed_data_with_vendor: dict[Any, Any] = defaultdict(dict)
self.package_names_with_vendor: list[Any] = []
self.package_names_without_vendor: list[Any] = []

def parse_list(self):
"""
Expand Down
5 changes: 1 addition & 4 deletions cve_bin_tool/parsers/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
from importlib import metadata as importlib_metadata
else:
import importlib_metadata
if sys.version_info >= (3, 9):
import importlib.resources as resources
else:
import importlib_resources as resources
import importlib.resources as resources

from cve_bin_tool.parsers import Parser

Expand Down
6 changes: 3 additions & 3 deletions cve_bin_tool/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"""

import subprocess
from typing import ClassVar, List, Set
from typing import ClassVar

from cve_bin_tool.async_utils import FileIO, run_coroutine
from cve_bin_tool.util import inpath
Expand All @@ -18,7 +18,7 @@ class Strings:
"""Utility class for parsing files and extracting printable characters."""

# printable characters
PRINTABLE: ClassVar[Set[int]] = set(range(32, 128))
PRINTABLE: ClassVar[set[int]] = set(range(32, 128))
# add tab to the printable character
PRINTABLE.add(9)

Expand All @@ -35,7 +35,7 @@ async def aio_parse(self) -> str:
str: The acuumulated printable characters from the file.
"""
async with FileIO(self.filename, "rb") as f:
tmp: List[str] = []
tmp: list[str] = []
async for line in f:
for char in line:
# remove all unprintable characters
Expand Down
6 changes: 4 additions & 2 deletions cve_bin_tool/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import os
import re
import sys
from collections.abc import Iterator
from enum import Enum
from pathlib import Path
from typing import DefaultDict, Iterator, List, NamedTuple, Pattern, Set, Union
from re import Pattern
from typing import DefaultDict, NamedTuple, Union

import requests
from packageurl import PackageURL
Expand Down Expand Up @@ -248,7 +250,7 @@ class VersionInfo(NamedTuple):
end_excluding: str


class CVEData(DefaultDict[str, Union[List[CVE], Set[str]]]):
class CVEData(DefaultDict[str, Union[list[CVE], set[str]]]):
"""
A Class representing a dictionary of CVEs and paths
"""
Expand Down
2 changes: 1 addition & 1 deletion cve_bin_tool/version_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import subprocess
import sys
from collections.abc import Iterator
from logging import Logger
from pathlib import Path
from typing import Iterator

from cve_bin_tool.checkers import BUILTIN_CHECKERS, Checker
from cve_bin_tool.cvedb import CVEDB
Expand Down
8 changes: 4 additions & 4 deletions cve_bin_tool/vex_manager/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from logging import Logger
from pathlib import Path
from typing import Dict, List, Optional
from typing import Optional

from lib4sbom.data.vulnerability import Vulnerability
from lib4vex.generator import VEXGenerator
Expand Down Expand Up @@ -67,7 +67,7 @@ def __init__(
vendor: str,
filename: str,
vextype: str,
all_cve_data: Dict[ProductInfo, CVEData],
all_cve_data: dict[ProductInfo, CVEData],
revision_reason: str = "",
sbom_serial_number: str = "",
sbom: Optional[str] = None,
Expand Down Expand Up @@ -154,7 +154,7 @@ def __generate_vex_filename(self) -> str:
)
return str(filename)

def __get_metadata(self) -> Dict:
def __get_metadata(self) -> dict:
"""
Generates metadata for the VEX document based on the specified VEX type, product, release,
and vendor information.
Expand Down Expand Up @@ -183,7 +183,7 @@ def __get_metadata(self) -> Dict:

return metadata

def __get_vulnerabilities(self) -> List[Vulnerability]:
def __get_vulnerabilities(self) -> list[Vulnerability]:
"""
Retrieves and constructs a list of vulnerability objects based on the current CVE data.

Expand Down
4 changes: 2 additions & 2 deletions cve_bin_tool/vex_manager/parse.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

from typing import Any, DefaultDict, Dict, Set, Union
from typing import Any, DefaultDict, Union

from lib4vex.parser import VEXParser

from cve_bin_tool.log import LOGGER
from cve_bin_tool.util import ProductInfo, Remarks, decode_bom_ref, decode_purl

TriageData = Dict[str, Union[Dict[str, Any], Set[str]]]
TriageData = dict[str, Union[dict[str, Any], set[str]]]


class VEXParse:
Expand Down
15 changes: 5 additions & 10 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
bandit; python_version <= "3.8"
bandit==1.8.6; python_version > "3.8"
black==25.1.0; python_version > "3.8"
black; python_version <= "3.8"
bandit==1.8.6
black==25.1.0
build
isort; python_version < "3.8"
isort==6.0.1; python_version >= "3.8"
pre-commit; python_version <= "3.8"
pre-commit==4.3.0; python_version > "3.8"
isort==6.0.1
pre-commit==4.3.0
codespell==v2.4.1
flake8; python_version < "3.8"
flake8==7.3.0; python_version >= "3.8"
flake8==7.3.0
gitlint==v0.19.1
interrogate
jsonschema
Expand Down
2 changes: 1 addition & 1 deletion doc/MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ This data source provides the CVEs for the CURL product.
## Limitations

The last release of this tool to support python 2.7 is 0.3.1. Please use
python 3.8+ for development and future versions. Linux and Windows are
currently supported Python for development and future versions. Linux and Windows are
supported, as is usage within cygwin on windows.

This tool does not scan for all possible known public vulnerabilities, it only
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ distro
filetype>=1.2.0
gsutil
importlib_metadata>=3.6; python_version < "3.10"
importlib_resources; python_version < "3.9"
jinja2>=2.11.3
jsonschema>=3.0.2
lib4sbom>=0.8.7
Expand Down
8 changes: 4 additions & 4 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ The recommended way to do this yourself is to use python's `virtualenv`
You can set up virtualenv for all these environments:

```console
virtualenv -p python3.8 venv3.8
virtualenv -p python3.9 venv3.9
virtualenv -p python3.11 venv3.11
virtualenv -p python3.12 venv3.12
```

To activate one of these (the example uses 3.8), run the tests, and deactivate:
To activate one of these (the example uses 3.12), run the tests, and deactivate:

```console
source venv3.8/bin/activate
source venv3.12/bin/activate
pytest
deactivate

Expand Down
3 changes: 1 addition & 2 deletions test/language_data/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ zstandard; python_version >= "3.4"
distro
defusedxml
xmlschema
importlib_metadata; python_version < "3.8"
requests
urllib3>=1.26.5 # dependency of requests added explictly to avoid CVEs
urllib3>=1.26.5 # dependency of requests added explicitly to avoid CVEs
gsutil
cvss
packaging
Loading