Skip to content

Commit 592158e

Browse files
committed
refactor: use XDG_CACHE_HOME for default cache directory
Update the tool to determine the default cache directory using the XDG_CACHE_HOME environment variable, falling back to ~/.cache if unset. This brings the tool in line with the XDG Base Directory Specification. Move cache-related default values into a new `database_defaults.py` module to centralize configuration and improve code maintainability. Add a test to verify environment-sensitive cache directory behavior. Update the MANUAL to document the new cache path logic. These changes improve compatibility with diverse environments and promote cleaner filesystem usage. Signed-off-by: Rafal Ilnicki <[email protected]>
1 parent b8fcf3b commit 592158e

21 files changed

+86
-40
lines changed

cve_bin_tool/available_fix/debian_cve_tracker.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44
from __future__ import annotations
55

66
from json import dump, load
7-
from pathlib import Path
87
from time import time
98

109
from cve_bin_tool.cve_scanner import CVEData
10+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
1111
from cve_bin_tool.log import LOGGER
1212
from cve_bin_tool.output_engine.util import ProductInfo, format_output
1313
from cve_bin_tool.util import make_http_requests
1414

1515
JSON_URL = "https://security-tracker.debian.org/tracker/data/json"
16-
DEB_CVE_JSON_PATH = (
17-
Path("~").expanduser() / ".cache" / "cve-bin-tool" / "debian_cve_data.json"
18-
)
16+
DEB_CVE_JSON_PATH = DISK_LOCATION_DEFAULT / "debian_cve_data.json"
1917

2018
UBUNTU_DEBIAN_MAP = {
2119
"hirsute": "bullseye",

cve_bin_tool/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from cve_bin_tool.config import ConfigParser
4343
from cve_bin_tool.config_generator import config_generator
4444
from cve_bin_tool.cve_scanner import CVEScanner
45-
from cve_bin_tool.cvedb import CVEDB, OLD_CACHE_DIR
45+
from cve_bin_tool.cvedb import CVEDB
4646
from cve_bin_tool.data_sources import (
4747
DataSourceSupport,
4848
curl_source,
@@ -53,6 +53,7 @@
5353
purl2cpe_source,
5454
redhat_source,
5555
)
56+
from cve_bin_tool.database_defaults import OLD_CACHE_DIR
5657
from cve_bin_tool.error_handler import (
5758
ERROR_CODES,
5859
CVEDataMissing,

cve_bin_tool/cve_scanner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from rich.console import Console
1313

14-
from cve_bin_tool.cvedb import DBNAME, DISK_LOCATION_DEFAULT
14+
from cve_bin_tool.database_defaults import DBNAME, DISK_LOCATION_DEFAULT
1515
from cve_bin_tool.error_handler import ErrorMode
1616
from cve_bin_tool.input_engine import TriageData
1717
from cve_bin_tool.log import LOGGER

cve_bin_tool/cvedb.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
osv_source,
3232
purl2cpe_source,
3333
)
34+
from cve_bin_tool.database_defaults import (
35+
DBNAME,
36+
DISK_LOCATION_BACKUP,
37+
DISK_LOCATION_DEFAULT,
38+
OLD_CACHE_DIR,
39+
)
3440
from cve_bin_tool.error_handler import ERROR_CODES, CVEDBError, ErrorMode, SigningError
3541
from cve_bin_tool.fetch_json_db import Fetch_JSON_DB
3642
from cve_bin_tool.log import LOGGER
@@ -39,12 +45,6 @@
3945

4046
logging.basicConfig(level=logging.DEBUG)
4147

42-
# database defaults
43-
DISK_LOCATION_DEFAULT = Path("~").expanduser() / ".cache" / "cve-bin-tool"
44-
DISK_LOCATION_BACKUP = Path("~").expanduser() / ".cache" / "cve-bin-tool-backup"
45-
DBNAME = "cve.db"
46-
OLD_CACHE_DIR = Path("~") / ".cache" / "cvedb"
47-
4848
UNKNOWN_METRIC_ID = 0
4949
EPSS_METRIC_ID = 1
5050
CVSS_2_METRIC_ID = 2

cve_bin_tool/data_sources/__init__.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,12 @@
55

66
import sys
77
from abc import ABC, abstractmethod
8-
from pathlib import Path
98

109
if sys.version_info >= (3, 9):
1110
import importlib.resources as resources
1211
else:
1312
import importlib_resources as resources
1413

15-
USER_HOME = Path("~")
16-
17-
# database defaults
18-
DISK_LOCATION_DEFAULT = str(USER_HOME.expanduser() / ".cache" / "cve-bin-tool")
19-
DISK_LOCATION_BACKUP = str(USER_HOME.expanduser() / ".cache" / "cve-bin-tool-backup")
20-
DBNAME = "cve.db"
21-
OLD_CACHE_DIR = str(USER_HOME.expanduser() / ".cache" / "cvedb")
22-
NVD_FILENAME_TEMPLATE = "nvdcve-1.1-{}.json.gz"
23-
2414

2515
class Data_Source(ABC):
2616
@abstractmethod

cve_bin_tool/data_sources/curl_source.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import aiohttp
1111

1212
from cve_bin_tool.async_utils import FileIO, RateLimiter
13-
from cve_bin_tool.data_sources import (
13+
from cve_bin_tool.data_sources import Data_Source
14+
from cve_bin_tool.database_defaults import (
1415
DISK_LOCATION_BACKUP,
1516
DISK_LOCATION_DEFAULT,
16-
Data_Source,
1717
)
1818
from cve_bin_tool.error_handler import ErrorMode
1919
from cve_bin_tool.log import LOGGER

cve_bin_tool/data_sources/epss_source.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import aiohttp
1515

16-
from cve_bin_tool.data_sources import DISK_LOCATION_BACKUP, DISK_LOCATION_DEFAULT
16+
from cve_bin_tool.database_defaults import DISK_LOCATION_BACKUP, DISK_LOCATION_DEFAULT
1717
from cve_bin_tool.error_handler import ErrorMode
1818
from cve_bin_tool.version import HTTP_HEADERS
1919

cve_bin_tool/data_sources/gad_source.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from yaml.loader import SafeLoader
1717

1818
from cve_bin_tool.async_utils import FileIO, RateLimiter
19-
from cve_bin_tool.data_sources import DISK_LOCATION_DEFAULT, Data_Source
19+
from cve_bin_tool.data_sources import Data_Source
20+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
2021
from cve_bin_tool.error_handler import ErrorMode
2122
from cve_bin_tool.log import LOGGER
2223
from cve_bin_tool.version import HTTP_HEADERS

cve_bin_tool/data_sources/nvd_source.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
from rich.progress import track
1919

2020
from cve_bin_tool.async_utils import FileIO, GzipFile, RateLimiter
21-
from cve_bin_tool.data_sources import (
21+
from cve_bin_tool.data_sources import Data_Source
22+
from cve_bin_tool.database_defaults import (
2223
DBNAME,
2324
DISK_LOCATION_BACKUP,
2425
DISK_LOCATION_DEFAULT,
2526
NVD_FILENAME_TEMPLATE,
26-
Data_Source,
2727
)
2828
from cve_bin_tool.error_handler import (
2929
AttemptedToWriteOutsideCachedir,

cve_bin_tool/data_sources/osv_source.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
from cvss import CVSS3
1717

1818
from cve_bin_tool.async_utils import FileIO, RateLimiter, aio_run_command
19-
from cve_bin_tool.data_sources import DISK_LOCATION_DEFAULT, Data_Source
19+
from cve_bin_tool.data_sources import Data_Source
20+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
2021
from cve_bin_tool.error_handler import ErrorMode
2122
from cve_bin_tool.log import LOGGER
2223
from cve_bin_tool.version import HTTP_HEADERS

cve_bin_tool/data_sources/purl2cpe_source.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
import aiohttp
88

9-
from cve_bin_tool.data_sources import DISK_LOCATION_DEFAULT, Data_Source
9+
from cve_bin_tool.data_sources import Data_Source
10+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
1011
from cve_bin_tool.error_handler import ErrorMode
1112
from cve_bin_tool.log import LOGGER
1213
from cve_bin_tool.version import HTTP_HEADERS

cve_bin_tool/data_sources/redhat_source.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import aiohttp
99

1010
from cve_bin_tool.async_utils import FileIO, RateLimiter
11-
from cve_bin_tool.data_sources import DISK_LOCATION_DEFAULT, Data_Source
11+
from cve_bin_tool.data_sources import Data_Source
12+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
1213
from cve_bin_tool.error_handler import ErrorMode
1314
from cve_bin_tool.log import LOGGER
1415
from cve_bin_tool.version import HTTP_HEADERS

cve_bin_tool/data_sources/rsd_source.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from cvss import CVSS2, CVSS3
1515

1616
from cve_bin_tool.async_utils import FileIO, RateLimiter
17-
from cve_bin_tool.data_sources import DISK_LOCATION_DEFAULT, Data_Source
17+
from cve_bin_tool.data_sources import Data_Source
18+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
1819
from cve_bin_tool.error_handler import ErrorMode
1920
from cve_bin_tool.log import LOGGER
2021
from cve_bin_tool.version import HTTP_HEADERS

cve_bin_tool/database_defaults.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (C) 2025 Intel Corporation
2+
# SPDX-License-Identifier: GPL-3.0-or-later
3+
4+
import os
5+
from pathlib import Path
6+
7+
CACHE_DIR = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
8+
DISK_LOCATION_DEFAULT = CACHE_DIR / "cve-bin-tool"
9+
DISK_LOCATION_BACKUP = CACHE_DIR / "cve-bin-tool-backup"
10+
OLD_CACHE_DIR = Path.home() / ".cache" / "cvedb"
11+
DBNAME = "cve.db"
12+
NVD_FILENAME_TEMPLATE = "nvdcve-1.1-{}.json.gz"

cve_bin_tool/helper_script.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
from rich import print as rprint
1616
from rich.console import Console
1717

18-
from cve_bin_tool.cvedb import CVEDB, DBNAME, DISK_LOCATION_DEFAULT
18+
from cve_bin_tool.cvedb import CVEDB
19+
from cve_bin_tool.database_defaults import DBNAME, DISK_LOCATION_DEFAULT
1920
from cve_bin_tool.error_handler import ErrorHandler, ErrorMode, UnknownArchiveType
2021
from cve_bin_tool.extractor import Extractor, TempDirExtractorContext
2122
from cve_bin_tool.log import LOGGER

cve_bin_tool/merge.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from cve_bin_tool.cve_scanner import CVEScanner
1313

14-
from .cvedb import DISK_LOCATION_DEFAULT
14+
from .database_defaults import DISK_LOCATION_DEFAULT
1515
from .error_handler import (
1616
ErrorHandler,
1717
ErrorMode,

cve_bin_tool/mismatch_loader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import yaml
77

8-
from cve_bin_tool.cvedb import DBNAME, DISK_LOCATION_DEFAULT
8+
from cve_bin_tool.database_defaults import DBNAME, DISK_LOCATION_DEFAULT
99
from cve_bin_tool.log import LOGGER
1010

1111
SQL_CREATE_TABLE = """

cve_bin_tool/version_signature.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from datetime import datetime
99
from pathlib import Path
1010

11-
from cve_bin_tool.cvedb import DISK_LOCATION_DEFAULT
11+
from cve_bin_tool.database_defaults import DISK_LOCATION_DEFAULT
1212

1313

1414
class InvalidVersionSignatureTable(ValueError):

doc/MANUAL.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,21 @@ CVE binary tool is intended for use by developers wishing to track known vulnera
380380

381381
We usually assume that the people providing the binaries for scanning will be the same people who set up and control the environment in which they are run. For example, a normal use case would be an open source project scanning their own generated files as a build check. We don't really expect people to use this as a forensics tool on a compromised system. (Although if you use it that way, we'd love to hear how that worked for you!)
382382

383+
### Cache Directory Behavior
384+
385+
The CVE Binary Tool uses a local cache directory to store downloaded vulnerability data (e.g., NVD feeds).
386+
By default, it follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
387+
388+
- If the `XDG_CACHE_HOME` environment variable is set, the cache will be stored in: `$XDG_CACHE_HOME/cve-bin-tool`
389+
- If `XDG_CACHE_HOME` is not set, the cache defaults to: `~/.cache/cve-bin-tool`
390+
391+
This allows users to customize where temporary vulnerability data is stored.
392+
383393
### Use user-level permissions with appropriate file system access
384394

385395
You should give cve-bin-tool minimal, user-level permissions. The user for cve-bin-tool will need access to the following things:
386396

387-
- Read/write access to a cache directory for storing and reading the vulnerability data (`~/.cache/cve-bin-tool/`).
397+
- Read/write access to a cache directory for storing and reading the vulnerability data.
388398
- Write access is only needed during data updates, which typically run once a day and can be scheduled separately.
389399
- Read access to the file/directory to be scanned.
390400
- Write access to the system temp directory if extracting files.

mismatch/cli.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import argparse
22
import os
33
import sqlite3
4-
from pathlib import Path
54

5+
from cve_bin_tool.database_defaults import DBNAME, DISK_LOCATION_DEFAULT
66
from cve_bin_tool.mismatch_loader import run_mismatch_loader
77

8-
DBNAME = "cve.db"
9-
DISK_LOCATION_DEFAULT = Path("~").expanduser() / ".cache" / "cve-bin-tool"
108
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
119
data_dir = os.path.join(parent_dir, "mismatch_data")
1210
dbpath = DISK_LOCATION_DEFAULT / DBNAME

test/test_database_defaults.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import importlib
2+
from pathlib import Path
3+
4+
5+
def test_cache_paths_with_xdg(mocker):
6+
mocker.patch.dict("os.environ", {"XDG_CACHE_HOME": "/tmp/custom_cache"})
7+
8+
import cve_bin_tool.database_defaults as db_defaults
9+
importlib.reload(db_defaults)
10+
11+
assert db_defaults.CACHE_DIR == Path("/tmp/custom_cache")
12+
assert db_defaults.DISK_LOCATION_DEFAULT == Path("/tmp/custom_cache/cve-bin-tool")
13+
assert db_defaults.DISK_LOCATION_BACKUP == Path("/tmp/custom_cache/cve-bin-tool-backup")
14+
assert db_defaults.OLD_CACHE_DIR == Path.home() / ".cache" / "cvedb"
15+
assert db_defaults.DBNAME == "cve.db"
16+
assert db_defaults.NVD_FILENAME_TEMPLATE.format("2024") == "nvdcve-1.1-2024.json.gz"
17+
18+
19+
def test_cache_paths_fallback_to_home(mocker):
20+
mocker.patch.dict("os.environ", {}, clear=True)
21+
22+
import cve_bin_tool.database_defaults as db_defaults
23+
importlib.reload(db_defaults)
24+
25+
expected_cache = Path.home() / ".cache"
26+
assert db_defaults.CACHE_DIR == expected_cache
27+
assert db_defaults.DISK_LOCATION_DEFAULT == expected_cache / "cve-bin-tool"
28+
assert db_defaults.DISK_LOCATION_BACKUP == expected_cache / "cve-bin-tool-backup"
29+
assert db_defaults.OLD_CACHE_DIR == Path.home() / ".cache" / "cvedb"
30+
assert db_defaults.DBNAME == "cve.db"
31+
assert db_defaults.NVD_FILENAME_TEMPLATE.format("2023") == "nvdcve-1.1-2023.json.gz"

0 commit comments

Comments
 (0)