Skip to content

Commit 4ab561a

Browse files
authored
Merge branch 'main' into fix-dovecot-checker
2 parents f4eca13 + cbf9f2b commit 4ab561a

32 files changed

+563
-489
lines changed

.github/workflows/build-wheel.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
egress-policy: audit
2929

3030
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
31-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
31+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
3232
with:
3333
python-version: ${{ matrix.python-version }}
3434
cache: 'pip'

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151

5252
# Initializes the CodeQL tools for scanning.
5353
- name: Initialize CodeQL
54-
uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
54+
uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6
5555
with:
5656
languages: ${{ matrix.language }}
5757
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -76,4 +76,4 @@ jobs:
7676
# make release
7777

7878
- name: Perform CodeQL Analysis
79-
uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
79+
uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6

.github/workflows/cve_scan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
egress-policy: audit
2222

2323
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
24-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
24+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
2525
with:
2626
python-version: '3.11'
2727
cache: 'pip'

.github/workflows/formatting.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
egress-policy: audit
2525

2626
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
27-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
27+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
2828
with:
2929
python-version: '3.11'
3030
cache: 'pip'

.github/workflows/fuzzing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
uses: actions/checkout@v4
2020

2121
- name: Set up Python
22-
uses: actions/setup-python@v5.1.1
22+
uses: actions/setup-python@v5.2.0
2323
with:
2424
python-version: 3.9
2525

.github/workflows/linting.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
egress-policy: audit
2424

2525
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
26-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
26+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
2727
with:
2828
python-version: '3.11'
2929
cache: 'pip'

.github/workflows/sbom.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
egress-policy: audit
2828

2929
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
30-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
30+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
3131
with:
3232
python-version: ${{ matrix.python }}
3333
cache: 'pip'

.github/workflows/scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
publish_results: true
4040

4141
- name: "Upload artifact"
42-
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
42+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
4343
with:
4444
name: SARIF file
4545
path: results.sarif

.github/workflows/testing.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
pypi.org:443
5050
5151
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
52-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
52+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
5353
with:
5454
python-version: '3.11'
5555
cache: 'pip'
@@ -108,7 +108,7 @@ jobs:
108108
www.sqlite.org:443
109109
110110
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
111-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
111+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
112112
with:
113113
python-version: ${{ matrix.python }}
114114
cache: 'pip'
@@ -240,7 +240,7 @@ jobs:
240240
www.sqlite.org:443
241241
242242
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
243-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
243+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
244244
with:
245245
python-version: '3.10'
246246
cache: 'pip'
@@ -397,7 +397,7 @@ jobs:
397397
www.sqlite.org:443
398398
399399
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
400-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
400+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
401401
with:
402402
python-version: '3.10'
403403
cache: 'pip'
@@ -503,7 +503,7 @@ jobs:
503503
egress-policy: audit
504504

505505
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
506-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
506+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
507507
with:
508508
python-version: '3.12'
509509
cache: 'pip'

.github/workflows/update-cache.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
egress-policy: audit
3333

3434
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
35-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
35+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
3636
with:
3737
python-version: '3.10'
3838
cache: 'pip'

.github/workflows/update-js-dependencies.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828

2929
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
3030

31-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
31+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
3232
with:
3333
python-version: '3.11'
3434

@@ -73,7 +73,7 @@ jobs:
7373
output_html(TestOutputEngine.MOCK_OUTPUT, None, "", "", "", 3, 3, 0, None, None, open("test.html", "w"))'
7474
7575
- name: Upload mock report
76-
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
76+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
7777
with:
7878
name: HTML report
7979
path: test.html

.github/workflows/update-pre-commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828

2929
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
3030

31-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
31+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
3232
with:
3333
python-version: '3.11'
3434

.github/workflows/validate-yml.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
2020
with:
2121
fetch-depth: 0
22-
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
22+
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
2323
with:
2424
python-version: '3.11'
2525
cache: 'pip'

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repos:
1414
exclude: ^fuzz/generated/
1515

1616
- repo: https://github.com/psf/black-pre-commit-mirror
17-
rev: 24.4.2
17+
rev: 24.8.0
1818
hooks:
1919
- id: black
2020
exclude: ^fuzz/generated/
@@ -27,7 +27,7 @@ repos:
2727
args: ["--py38-plus"]
2828

2929
- repo: https://github.com/pycqa/flake8
30-
rev: 7.1.0
30+
rev: 7.1.1
3131
hooks:
3232
- id: flake8
3333
exclude: ^fuzz/generated/|bandit\.conf$
@@ -45,7 +45,7 @@ repos:
4545
- id: gitlint
4646

4747
- repo: https://github.com/pre-commit/mirrors-mypy
48-
rev: v1.11.1
48+
rev: v1.11.2
4949
hooks:
5050
- id: mypy
5151
additional_dependencies:

cve_bin_tool/cli.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ def main(argv=None):
10251025
total_files: int = 0
10261026
parsed_data: dict[ProductInfo, TriageData] = {}
10271027
vex_product_info: dict[str, str] = {}
1028+
sbom_serial_number = ""
10281029
# Package List parsing
10291030
if args["package_list"]:
10301031
sbom_root = args["package_list"]
@@ -1095,6 +1096,7 @@ def main(argv=None):
10951096
validate=not args["disable_validation_check"],
10961097
)
10971098
parsed_data = sbom_list.parse_sbom()
1099+
sbom_serial_number = sbom_list.serialNumber
10981100
LOGGER.info(
10991101
f"The number of products to process from SBOM - {len(parsed_data)}"
11001102
)
@@ -1103,10 +1105,10 @@ def main(argv=None):
11031105
cve_scanner.get_cves(product_info, triage_data)
11041106

11051107
if args["vex_file"]:
1106-
# for now use cyclonedx as auto detection is not implemented in latest pypi package of lib4vex
1108+
# use auto so that lib4vex can auto-detect the vex type.
11071109
vexdata = VEXParse(
11081110
filename=args["vex_file"],
1109-
vextype="cyclonedx",
1111+
vextype="auto",
11101112
logger=LOGGER,
11111113
)
11121114
parsed_vex_data = vexdata.parse_vex()
@@ -1122,9 +1124,14 @@ def main(argv=None):
11221124
LOGGER.info(
11231125
f"VEX file {args['vex_file']} is not a standalone file and will be used as a triage file"
11241126
)
1125-
# need to do validation on the sbom part
1126-
# need to implement is_linked() function which will check the linkage.
1127-
if args["sbom_file"]:
1127+
# check weather vex is linked with given sbom or not.
1128+
# only check cyclonedx since it have serialNumber.
1129+
if (
1130+
args["sbom_file"]
1131+
and args["sbom"] == "cyclonedx"
1132+
and vexdata.vextype == "cyclonedx"
1133+
and sbom_serial_number not in vexdata.serialNumbers
1134+
):
11281135
LOGGER.warning(
11291136
f"SBOM file: {args['sbom_file']} is not linked to VEX file: {args['vex_file']}."
11301137
)
@@ -1162,6 +1169,7 @@ def main(argv=None):
11621169
"release": args["release"],
11631170
"vendor": args["vendor"],
11641171
"revision_reason": args["revision_reason"],
1172+
"sbom_serial_number": sbom_serial_number,
11651173
}
11661174
elif args["vex_file"]:
11671175
vex_product_info["revision_reason"] = args["revision_reason"]

cve_bin_tool/output_engine/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ def output_cves(self, outfile, output_type="console"):
803803
self.vex_type,
804804
self.all_cve_data,
805805
self.vex_product_info["revision_reason"],
806+
self.vex_product_info["sbom_serial_number"],
806807
logger=self.logger,
807808
)
808809
vexgen.generate_vex()

cve_bin_tool/sbom_manager/parse.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
decode_cpe23,
2424
find_product_location,
2525
validate_location,
26+
validate_serialNumber,
2627
)
2728
from cve_bin_tool.validator import validate_cyclonedx, validate_spdx, validate_swid
2829

@@ -58,6 +59,7 @@ def __init__(
5859
self.type = sbom_type
5960
self.logger = logger or LOGGER.getChild(self.__class__.__name__)
6061
self.validate = validate
62+
self.serialNumber = ""
6163

6264
# Connect to the database
6365
self.cvedb = CVEDB(version_check=False)
@@ -253,6 +255,25 @@ def parse_cyclonedx_spdx(self) -> [(str, str, str)]:
253255
sbom_parser = SBOMParser(sbom_type=self.type)
254256
# Load SBOM
255257
sbom_parser.parse_file(self.filename)
258+
doc = sbom_parser.get_document()
259+
uuid = doc.get("uuid", "")
260+
if self.type == "cyclonedx":
261+
parts = uuid.split(":")
262+
if len(parts) == 3 and parts[0] == "urn" and parts[1] == "uuid":
263+
serialNumber = parts[2]
264+
if validate_serialNumber(serialNumber):
265+
self.serialNumber = serialNumber
266+
else:
267+
LOGGER.error(
268+
f"The SBOM file '{self.filename}' has an invalid serial number."
269+
)
270+
return []
271+
else:
272+
LOGGER.error(
273+
f"The SBOM file '{self.filename}' has an invalid serial number."
274+
)
275+
return []
276+
256277
modules = []
257278
if self.validate and self.filename.endswith(".xml"):
258279
# Only for XML files

cve_bin_tool/util.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ def decode_purl(purl: str) -> ProductInfo | None:
391391
return None
392392

393393

394-
def decode_bom_ref(ref: str) -> ProductInfo | None:
394+
def decode_bom_ref(ref: str):
395395
"""
396396
Decodes the BOM reference for each component.
397397
@@ -418,11 +418,29 @@ def decode_bom_ref(ref: str) -> ProductInfo | None:
418418
urn_cdx = re.compile(
419419
r"urn:cdx:(?P<bomSerialNumber>.*?)\/(?P<bom_version>.*?)#(?P<bom_ref>.*)"
420420
)
421+
urn_cdx_with_purl = re.compile(
422+
r"urn:cdx:(?P<bomSerialNumber>[^/]+)\/(?P<bom_version>[^#]+)#(?P<purl>pkg:[^\s]+)"
423+
)
421424
location = "location/to/product"
422-
match = urn_cbt_ext_ref.match(ref) or urn_cbt_ref.match(ref) or urn_cdx.match(ref)
425+
match = (
426+
urn_cdx_with_purl.match(ref)
427+
or urn_cbt_ext_ref.match(ref)
428+
or urn_cbt_ref.match(ref)
429+
or urn_cdx.match(ref)
430+
)
423431
if match:
424432
urn_dict = match.groupdict()
425-
if "bom_ref" in urn_dict: # For urn_cdx match
433+
if "purl" in urn_dict: # For urn_cdx_with_purl match
434+
serialNumber = urn_dict["bomSerialNumber"]
435+
product_info = decode_purl(urn_dict["purl"])
436+
if not validate_serialNumber(serialNumber):
437+
LOGGER.error(
438+
f"The BOM link contains an invalid serial number: '{serialNumber}'"
439+
)
440+
return product_info
441+
else:
442+
return product_info, serialNumber
443+
elif "bom_ref" in urn_dict: # For urn_cdx match
426444
cdx_bom_ref = urn_dict["bom_ref"]
427445
try:
428446
product, version = cdx_bom_ref.rsplit("-", 1)
@@ -466,6 +484,14 @@ def validate_version(version: str) -> bool:
466484
return re.search(cpe_regex, version) is not None
467485

468486

487+
def validate_serialNumber(serialNumber: str) -> bool:
488+
"""
489+
Validates the serial number present in sbom
490+
"""
491+
pattern = r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
492+
return re.match(pattern, serialNumber) is not None
493+
494+
469495
class DirWalk:
470496
"""
471497
for filename in DirWalk('*.c').walk(roots):

cve_bin_tool/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from cve_bin_tool.log import LOGGER
99
from cve_bin_tool.util import make_http_requests
1010

11-
VERSION: str = "3.4rc1"
11+
VERSION: str = "3.4"
1212

1313
HTTP_HEADERS: dict = {
1414
"User-Agent": f"cve-bin-tool/{VERSION} (https://github.com/intel/cve-bin-tool/)",

cve_bin_tool/vex_manager/generate.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __init__(
4848
vextype: str,
4949
all_cve_data: Dict[ProductInfo, CVEData],
5050
revision_reason: str = "",
51+
sbom_serial_number: str = "",
5152
sbom: Optional[str] = None,
5253
logger: Optional[Logger] = None,
5354
validate: bool = True,
@@ -62,6 +63,7 @@ def __init__(
6263
self.logger = logger or LOGGER.getChild(self.__class__.__name__)
6364
self.validate = validate
6465
self.all_cve_data = all_cve_data
66+
self.sbom_serial_number = sbom_serial_number
6567

6668
def generate_vex(self) -> None:
6769
"""
@@ -155,10 +157,13 @@ def __get_vulnerabilities(self) -> List[Vulnerability]:
155157
else cve.remarks.name
156158
)
157159
# more details will be added using set_value()
158-
bom_version = 1
159-
ref = f"urn:cbt:{bom_version}/{vendor}#{product}:{version}"
160160
if purl is None:
161161
purl = f"pkg:generic/{vendor}/{product}@{version}"
162+
bom_version = 1
163+
if self.sbom_serial_number != "":
164+
ref = f"urn:cdx:{self.sbom_serial_number}/{bom_version}#{purl}"
165+
else:
166+
ref = f"urn:cbt:{bom_version}/{vendor}#{product}:{version}"
162167

163168
vulnerability.set_value("purl", str(purl))
164169
vulnerability.set_value("bom_link", ref)

0 commit comments

Comments
 (0)