Skip to content

Commit c5bb334

Browse files
authored
Merge branch 'main' into bandit
2 parents 31404d2 + ab07fb9 commit c5bb334

22 files changed

+1408
-66
lines changed

.github/actions/spelling/allow.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ liblas
180180
libnss
181181
libpng
182182
libraryname
183+
librsvg
183184
libsndfile
184185
libsoup
185186
libsqlite

README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,23 +194,23 @@ The following checkers are available for finding components in binary files:
194194

195195
<!--CHECKERS TABLE BEGIN-->
196196
| | | | Available checkers | | | |
197-
|--------------- |--------- |------------- |---------- |------------- |---------- |------------ |
197+
|--------------- |--------------- |--------- |------------- |------------- |---------- |---------- |
198198
| accountsservice |avahi |bash |bind |binutils |bolt |bubblewrap |
199199
| busybox |bzip2 |cronie |cryptsetup |cups |curl |dbus |
200200
| dnsmasq |dovecot |dpkg |enscript |expat |ffmpeg |freeradius |
201201
| ftp |gcc |gimp |glibc |gnomeshell |gnupg |gnutls |
202202
| gpgme |gstreamer |gupnp |haproxy |hdf5 |hostapd |hunspell |
203203
| icecast |icu |irssi |kbd |kerberos |kexectools |libarchive |
204204
| libbpg |libdb |libgcrypt |libical |libjpeg_turbo |liblas |libnss |
205-
| libsndfile |libsoup |libsrtp |libssh2 |libtiff |libvirt |libvncserver |
206-
| libxslt |lighttpd |logrotate |lua |mariadb |mdadm |memcached |
207-
| mtr |mysql |nano |ncurses |nessus |netpbm |nginx |
208-
| node |ntp |open_vm_tools |openafs |openjpeg |openldap |openssh |
209-
| openssl |openswan |openvpn |p7zip |pcsc_lite |pigz |png |
210-
| polarssl_fedora |poppler |postgresql |pspp |python |qt |radare2 |
211-
| rsyslog |samba |sane_backends |sqlite |strongswan |subversion |sudo |
212-
| syslogng |systemd |tcpdump |trousers |varnish |webkitgtk |wireshark |
213-
| wpa_supplicant |xerces |xml2 |zlib |zsh | | |
205+
| librsvg |libsndfile |libsoup |libsrtp |libssh2 |libtiff |libvirt |
206+
| libvncserver |libxslt |lighttpd |logrotate |lua |mariadb |mdadm |
207+
| memcached |mtr |mysql |nano |ncurses |nessus |netpbm |
208+
| nginx |node |ntp |open_vm_tools |openafs |openjpeg |openldap |
209+
| openssh |openssl |openswan |openvpn |p7zip |pcsc_lite |pigz |
210+
| png |polarssl_fedora |poppler |postgresql |pspp |python |qt |
211+
| radare2 |rsyslog |samba |sane_backends |sqlite |strongswan |subversion |
212+
| sudo |syslogng |systemd |tcpdump |trousers |varnish |webkitgtk |
213+
| wireshark |wpa_supplicant |xerces |xml2 |zlib |zsh | |
214214
<!--CHECKERS TABLE END-->
215215

216216
All the checkers can be found in the checkers directory, as can the
@@ -228,6 +228,12 @@ The scanner examines the `pom.xml` file within a Java package archive to identif
228228

229229
JAR, WAR and EAR archives are supported.
230230

231+
### Javascript
232+
233+
The scanner examines the `package-lock.json` file within a javascript application
234+
to identify components. The package names and versions are used to search the database for vulnerabilities.
235+
236+
231237
### Python
232238

233239
The scanner examines the `PKG-INFO` and `METADATA` files for an installed Python package to extract the component name and version which

cve_bin_tool/available_fix/debian_cve_tracker.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Copyright (C) 2021 Intel Corporation
22
# SPDX-License-Identifier: GPL-3.0-or-later
33

4-
from json import dump, load, loads
4+
from json import dump, load
55
from os.path import exists, expanduser, getmtime, join
66
from time import time
77
from typing import Dict
8-
from urllib import request
8+
9+
import requests
910

1011
from cve_bin_tool.cve_scanner import CVEData
1112
from cve_bin_tool.log import LOGGER
@@ -96,8 +97,7 @@ def update_json():
9697
"""Update the Debian CVE JSON file"""
9798

9899
LOGGER.info("Updating Debian CVE JSON file for checking available fixes.")
99-
response = request.urlopen(JSON_URL).read().decode("utf-8") # nosec - static url
100-
response = loads(response)
100+
response = requests.get(JSON_URL).json()
101101
with open(DEB_CVE_JSON_PATH, "w") as debian_json:
102102
dump(response, debian_json, indent=4)
103103
LOGGER.info("Debian CVE JSON file for checking available fixes is updated.")

cve_bin_tool/available_fix/redhat_cve_tracker.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Copyright (C) 2021 Intel Corporation
22
# SPDX-License-Identifier: GPL-3.0-or-later
33

4-
from json import loads
54
from re import search, split
65
from typing import Dict
7-
from urllib import error, request
6+
7+
import requests
88

99
from cve_bin_tool.cve_scanner import CVEData
1010
from cve_bin_tool.log import LOGGER
@@ -74,10 +74,9 @@ def cve_info(
7474

7575
def get_data(self, cve_number: str, product: str):
7676
try:
77-
full_query = f"{RH_CVE_API}/{cve_number}.json" # static https url above
78-
response = request.urlopen(full_query).read().decode("utf-8") # nosec
79-
return loads(response)
80-
except error.HTTPError as e:
77+
full_query = f"{RH_CVE_API}/{cve_number}.json"
78+
return requests.get(full_query).json()
79+
except requests.HTTPError as e:
8180
LOGGER.debug(e)
8281

8382
def parse_package_data(self, package_data: str) -> str:

cve_bin_tool/checkers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"libjpeg_turbo",
6161
"liblas",
6262
"libnss",
63+
"librsvg",
6364
"libsndfile",
6465
"libsoup",
6566
"libsrtp",

cve_bin_tool/checkers/librsvg.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (C) 2022 Intel Corporation
2+
# SPDX-License-Identifier: GPL-3.0-or-later
3+
4+
"""
5+
CVE checker for librsvg
6+
7+
https://www.cvedetails.com/vulnerability-list/vendor_id-283/product_id-23082/Gnome-Librsvg.html
8+
9+
"""
10+
11+
from cve_bin_tool.checkers import Checker
12+
13+
14+
class LibrsvgChecker(Checker):
15+
CONTAINS_PATTERNS = []
16+
FILENAME_PATTERNS = [r"librsvg"]
17+
VERSION_PATTERNS = [r"librsvg[0-9]?-([0-9]+\.[0-9]+\.[0-9]+)"]
18+
VENDOR_PRODUCT = [("gnome", "librsvg")]

cve_bin_tool/checkers/sqlite.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
1313
"""
1414
import re
15-
import urllib.error as error
16-
import urllib.request as request
15+
16+
import requests
1717

1818
from cve_bin_tool.checkers import Checker
1919
from cve_bin_tool.log import LOGGER
@@ -31,13 +31,11 @@ def get_version_map():
3131
re.compile(r'"*(\d{4}-\d{2}-\d{2} \d+:\d+:\d+ [\w]+)"*'),
3232
]
3333
try:
34-
response = request.urlopen(changeurl) # nosec - static url above
35-
lines = response.readlines()
34+
response = requests.get(changeurl).text
35+
lines = response.splitlines()
3636

3737
last_version = "UNKNOWN"
38-
for line_encoded in lines:
39-
line = line_encoded.decode("UTF-8")
40-
38+
for line in lines:
4139
ver_match = version_pattern.search(line)
4240
if ver_match:
4341
last_version = ver_match.group(1)
@@ -47,7 +45,7 @@ def get_version_map():
4745
version_map.append([last_version, id_match.group(1)])
4846
break
4947

50-
except error.URLError as err:
48+
except requests.RequestException as err:
5149
LOGGER.error("Could not fetch " + changeurl + ", " + str(err))
5250

5351
return version_map

cve_bin_tool/version.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# Copyright (C) 2021 Intel Corporation
22
# SPDX-License-Identifier: GPL-3.0-or-later
33

4-
import json
54
import textwrap
6-
from urllib import request
75

6+
import requests
87
from packaging import version
98

109
from cve_bin_tool.log import LOGGER
@@ -18,19 +17,18 @@ def check_latest_version():
1817
name: str = "cve-bin-tool"
1918
url: str = f"https://pypi.org/pypi/{name}/json"
2019
try:
21-
with request.urlopen(url) as resp: # nosec - static url above
22-
package_json = json.load(resp)
23-
pypi_version = package_json["info"]["version"]
24-
if pypi_version != VERSION:
20+
package_json = requests.get(url).json()
21+
pypi_version = package_json["info"]["version"]
22+
if pypi_version != VERSION:
23+
LOGGER.info(
24+
f"[bold red]You are running version {VERSION} of {name} but the latest PyPI Version is {pypi_version}.[/]",
25+
extra={"markup": True},
26+
)
27+
if version.parse(VERSION) < version.parse(pypi_version):
2528
LOGGER.info(
26-
f"[bold red]You are running version {VERSION} of {name} but the latest PyPI Version is {pypi_version}.[/]",
29+
"[bold yellow]Alert: We recommend using the latest stable release.[/]",
2730
extra={"markup": True},
2831
)
29-
if version.parse(VERSION) < version.parse(pypi_version):
30-
LOGGER.info(
31-
"[bold yellow]Alert: We recommend using the latest stable release.[/]",
32-
extra={"markup": True},
33-
)
3432
except Exception as error:
3533
LOGGER.warning(
3634
textwrap.dedent(

cve_bin_tool/version_scanner.py

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Copyright (C) 2021 Intel Corporation
22
# SPDX-License-Identifier: GPL-3.0-or-later
33

4+
import json
45
import os
56
import subprocess
67
import sys
78
from re import MULTILINE, compile, search
9+
from typing import List
810

911
import defusedxml.ElementTree as ET
1012

@@ -122,6 +124,7 @@ def is_executable(self, filename):
122124
and ("PKG-INFO: " not in output)
123125
and ("METADATA: " not in output)
124126
and ("pom.xml" not in output)
127+
and ("package-lock.json" not in output)
125128
):
126129
return False, None
127130
# otherwise use python implementation of file
@@ -169,8 +172,11 @@ def scan_file(self, filename):
169172

170173
# Check for Java package
171174
if output and "pom.xml" in output:
172-
java_lines = "\n".join(lines.splitlines())
173-
yield from self.run_java_checker(filename, java_lines)
175+
yield from self.run_java_checker(filename)
176+
177+
# Javascript checker
178+
if output and "package-lock.json" in output:
179+
yield from self.run_js_checker(filename)
174180

175181
# If python package then strip the lines to avoid detecting other product strings
176182
if output and ("PKG-INFO: " in output or "METADATA: " in output):
@@ -199,7 +205,7 @@ def find_java_vendor(self, product, version):
199205
return ProductInfo(vendor, product, version), file_path
200206
return None, None
201207

202-
def run_java_checker(self, filename, lines):
208+
def run_java_checker(self, filename: str) -> None:
203209
"""Process maven pom.xml file and extract product and dependency details"""
204210
tree = ET.parse(filename)
205211
# Find root element
@@ -247,6 +253,65 @@ def run_java_checker(self, filename, lines):
247253

248254
self.logger.debug(f"Done scanning file: {filename}")
249255

256+
def find_js_vendor(self, product: str, version: str) -> List[List[str]]:
257+
"""Find vendor for Javascript product"""
258+
if version == "*":
259+
return None
260+
vendor_package_pair = self.cve_db.get_vendor_product_pairs(product)
261+
vendorlist: List[List[str]] = []
262+
if vendor_package_pair != []:
263+
# To handle multiple vendors, return all combinations of product/vendor mappings
264+
for v in vendor_package_pair:
265+
vendor = v["vendor"]
266+
file_path = "".join(self.file_stack)
267+
# Tidy up version string
268+
if "^" in version:
269+
version = version[1:]
270+
self.logger.debug(f"{file_path} {product} {version} by {vendor}")
271+
vendorlist.append([ProductInfo(vendor, product, version), file_path])
272+
return vendorlist if len(vendorlist) > 0 else None
273+
return None
274+
275+
def run_js_checker(self, filename: str) -> None:
276+
"""Process package-lock.json file and extract product and dependency details"""
277+
fh = open(filename)
278+
data = json.load(fh)
279+
product = data["name"]
280+
version = data["version"]
281+
vendor = self.find_js_vendor(product, version)
282+
if vendor is not None:
283+
for v in vendor:
284+
yield v[0], v[1] # product_info, file_path
285+
# Now process dependencies
286+
for i in data["dependencies"]:
287+
# To handle @actions/<product>: lines, extract product name from line
288+
product = i.split("/")[1] if "/" in i else i
289+
# Handle different formats. Either <product> : <version> or
290+
# <product>: {
291+
# ...
292+
# "version" : <version>
293+
# ...
294+
# }
295+
try:
296+
version = data["dependencies"][i]["version"]
297+
except Exception:
298+
# Cater for case when version field not present
299+
version = data["dependencies"][i]
300+
vendor = self.find_js_vendor(product, version)
301+
if vendor is not None:
302+
for v in vendor:
303+
yield v[0], v[1] # product_info, file_path
304+
if "requires" in data["dependencies"][i]:
305+
for r in data["dependencies"][i]["requires"]:
306+
# To handle @actions/<product>: lines, extract product name from line
307+
product = r.split("/")[1] if "/" in r else r
308+
version = data["dependencies"][i]["requires"][r]
309+
vendor = self.find_js_vendor(product, version)
310+
if vendor is not None:
311+
for v in vendor:
312+
yield v[0], v[1] # product_info, file_path
313+
self.logger.debug(f"Done scanning file: {filename}")
314+
250315
def run_python_package_checkers(self, filename, lines):
251316
"""
252317
This generator runs only for python packages.

doc/MANUAL.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,23 @@ which is useful if you're trying the latest code from
118118

119119
<!--CHECKERS TABLE BEGIN-->
120120
| | | | Available checkers | | | |
121-
|--------------- |--------- |------------- |---------- |------------- |---------- |------------ |
121+
|--------------- |--------------- |--------- |------------- |------------- |---------- |---------- |
122122
| accountsservice |avahi |bash |bind |binutils |bolt |bubblewrap |
123123
| busybox |bzip2 |cronie |cryptsetup |cups |curl |dbus |
124124
| dnsmasq |dovecot |dpkg |enscript |expat |ffmpeg |freeradius |
125125
| ftp |gcc |gimp |glibc |gnomeshell |gnupg |gnutls |
126126
| gpgme |gstreamer |gupnp |haproxy |hdf5 |hostapd |hunspell |
127127
| icecast |icu |irssi |kbd |kerberos |kexectools |libarchive |
128128
| libbpg |libdb |libgcrypt |libical |libjpeg_turbo |liblas |libnss |
129-
| libsndfile |libsoup |libsrtp |libssh2 |libtiff |libvirt |libvncserver |
130-
| libxslt |lighttpd |logrotate |lua |mariadb |mdadm |memcached |
131-
| mtr |mysql |nano |ncurses |nessus |netpbm |nginx |
132-
| node |ntp |open_vm_tools |openafs |openjpeg |openldap |openssh |
133-
| openssl |openswan |openvpn |p7zip |pcsc_lite |pigz |png |
134-
| polarssl_fedora |poppler |postgresql |pspp |python |qt |radare2 |
135-
| rsyslog |samba |sane_backends |sqlite |strongswan |subversion |sudo |
136-
| syslogng |systemd |tcpdump |trousers |varnish |webkitgtk |wireshark |
137-
| wpa_supplicant |xerces |xml2 |zlib |zsh | | |
129+
| librsvg |libsndfile |libsoup |libsrtp |libssh2 |libtiff |libvirt |
130+
| libvncserver |libxslt |lighttpd |logrotate |lua |mariadb |mdadm |
131+
| memcached |mtr |mysql |nano |ncurses |nessus |netpbm |
132+
| nginx |node |ntp |open_vm_tools |openafs |openjpeg |openldap |
133+
| openssh |openssl |openswan |openvpn |p7zip |pcsc_lite |pigz |
134+
| png |polarssl_fedora |poppler |postgresql |pspp |python |qt |
135+
| radare2 |rsyslog |samba |sane_backends |sqlite |strongswan |subversion |
136+
| sudo |syslogng |systemd |tcpdump |trousers |varnish |webkitgtk |
137+
| wireshark |wpa_supplicant |xerces |xml2 |zlib |zsh | |
138138
<!--CHECKERS TABLE END-->
139139

140140
For a quick overview of usage and how it works, you can also see [the readme file](README.md).

requirements.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ srossross_not_in_db,rpmfile
1818
indygreg_not_in_db,zstandard
1919
nir0s_not_in_db,distro
2020
tiran_not_in_db,defusedxml
21-
python_not_in_db,importlib_metadata
21+
python_not_in_db,importlib_metadata
22+
python,requests

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ zstandard; python_version >= "3.4"
1717
reportlab
1818
distro
1919
defusedxml
20-
importlib_metadata; python_version < "3.8"
20+
importlib_metadata; python_version < "3.8"
21+
requests
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)