Hanno Böck commited on 2022-07-15 12:43:59
Zeige 6 geänderte Dateien mit 174 Einfügungen und 134 Löschungen.
| ... | ... |
@@ -58,40 +58,48 @@ def checkoldsafe(old_safe, find_version): |
| 58 | 58 |
return False |
| 59 | 59 |
|
| 60 | 60 |
|
| 61 |
-def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, |
|
| 62 |
- xml): |
|
| 63 |
- appdir = '/'.join(os.path.abspath(vfilename).split('/')[:-1 - subdir])
|
|
| 61 |
+def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, xml): |
|
| 62 |
+ appdir = "/".join(os.path.abspath(vfilename).split("/")[: -1 - subdir])
|
|
| 64 | 63 |
if not xml: |
| 65 | 64 |
print(f"{appname} {version} ({safeversion}) {vuln} {appdir}")
|
| 66 | 65 |
else: |
| 67 |
- state = 'vulnerable' |
|
| 68 |
- if safeversion == 'ok': |
|
| 69 |
- state = 'ok' |
|
| 66 |
+ state = "vulnerable" |
|
| 67 |
+ if safeversion == "ok": |
|
| 68 |
+ state = "ok" |
|
| 70 | 69 |
print(f' <app state="{state}">')
|
| 71 |
- print(f' <appname>{escape(appname)}</appname>')
|
|
| 72 |
- print(f' <version>{escape(version)}</version>')
|
|
| 73 |
- print(f' <directory>{escape(appdir)}</directory>')
|
|
| 74 |
- if state == 'vulnerable': |
|
| 75 |
- print(f' <safeversion>{escape(safeversion)}</safeversion>')
|
|
| 76 |
- print(f' <vulninfo>{escape(vuln)}</vulninfo>')
|
|
| 77 |
- print(' </app>')
|
|
| 70 |
+ print(f" <appname>{escape(appname)}</appname>")
|
|
| 71 |
+ print(f" <version>{escape(version)}</version>")
|
|
| 72 |
+ print(f" <directory>{escape(appdir)}</directory>")
|
|
| 73 |
+ if state == "vulnerable": |
|
| 74 |
+ print(f" <safeversion>{escape(safeversion)}</safeversion>")
|
|
| 75 |
+ print(f" <vulninfo>{escape(vuln)}</vulninfo>")
|
|
| 76 |
+ print(" </app>")
|
|
| 78 | 77 |
|
| 79 | 78 |
|
| 80 | 79 |
# Command-line options |
| 81 | 80 |
parser = argparse.ArgumentParser() |
| 82 |
-parser.add_argument("dirs", nargs="*",
|
|
| 83 |
- help="Directories to scan") |
|
| 84 |
-parser.add_argument("-a", "--all", action="store_true",
|
|
| 85 |
- help="Show all webapps found, not just vulnerable") |
|
| 86 |
-parser.add_argument("-x", "--xml", action="store_true",
|
|
| 87 |
- help="Output results as XML") |
|
| 88 |
-parser.add_argument("-3", "--thirdparty", action="store_true",
|
|
| 89 |
- help="Scan for third-party components like jquery") |
|
| 81 |
+parser.add_argument("dirs", nargs="*", help="Directories to scan")
|
|
| 82 |
+parser.add_argument( |
|
| 83 |
+ "-a", |
|
| 84 |
+ "--all", |
|
| 85 |
+ action="store_true", |
|
| 86 |
+ help="Show all webapps found, not just vulnerable", |
|
| 87 |
+) |
|
| 88 |
+parser.add_argument("-x", "--xml", action="store_true", help="Output results as XML")
|
|
| 89 |
+parser.add_argument( |
|
| 90 |
+ "-3", |
|
| 91 |
+ "--thirdparty", |
|
| 92 |
+ action="store_true", |
|
| 93 |
+ help="Scan for third-party components like jquery", |
|
| 94 |
+) |
|
| 90 | 95 |
opts = parser.parse_args() |
| 91 | 96 |
|
| 92 | 97 |
jdir = False |
| 93 |
-for p in [os.path.dirname(sys.argv[0]) + '/freewvsdb', '/var/lib/freewvs', |
|
| 94 |
- str(pathlib.Path.home()) + "/.cache/freewvs/"]: |
|
| 98 |
+for p in [ |
|
| 99 |
+ os.path.dirname(sys.argv[0]) + "/freewvsdb", |
|
| 100 |
+ "/var/lib/freewvs", |
|
| 101 |
+ str(pathlib.Path.home()) + "/.cache/freewvs/", |
|
| 102 |
+]: |
|
| 95 | 103 |
if os.path.isdir(p): |
| 96 | 104 |
jdir = p |
| 97 | 105 |
break |
| ... | ... |
@@ -100,20 +108,20 @@ if not jdir: |
| 100 | 108 |
sys.exit(1) |
| 101 | 109 |
|
| 102 | 110 |
jconfig = [] |
| 103 |
-for cfile in glob.glob(jdir + '/*.json'): |
|
| 111 |
+for cfile in glob.glob(jdir + "/*.json"): |
|
| 104 | 112 |
with open(cfile, encoding="ascii") as json_file: |
| 105 | 113 |
data = json.load(json_file) |
| 106 | 114 |
jconfig += data |
| 107 | 115 |
|
| 108 | 116 |
scanfiles = set() |
| 109 | 117 |
for app in jconfig: |
| 110 |
- for det in app['detection']: |
|
| 111 |
- scanfiles.add(det['file']) |
|
| 118 |
+ for det in app["detection"]: |
|
| 119 |
+ scanfiles.add(det["file"]) |
|
| 112 | 120 |
|
| 113 | 121 |
|
| 114 | 122 |
if opts.xml: |
| 115 | 123 |
print('<?xml version="1.0" ?>')
|
| 116 |
- print('<freewvs>')
|
|
| 124 |
+ print("<freewvs>")
|
|
| 117 | 125 |
|
| 118 | 126 |
# start the search |
| 119 | 127 |
|
| ... | ... |
@@ -125,61 +133,78 @@ for fdir in opts.dirs: |
| 125 | 133 |
del dirs[:] |
| 126 | 134 |
for filename in scanfiles.intersection(files): |
| 127 | 135 |
for item in jconfig: |
| 128 |
- if not opts.thirdparty and 'thirdparty' in item: |
|
| 136 |
+ if not opts.thirdparty and "thirdparty" in item: |
|
| 129 | 137 |
continue |
| 130 |
- for det in item['detection']: |
|
| 131 |
- if filename == det['file']: |
|
| 138 |
+ for det in item["detection"]: |
|
| 139 |
+ if filename == det["file"]: |
|
| 132 | 140 |
mfile = os.path.join(root, filename) |
| 133 | 141 |
try: |
| 134 |
- file = open(mfile, encoding='ascii', |
|
| 135 |
- errors='replace') |
|
| 142 |
+ file = open(mfile, encoding="ascii", errors="replace") |
|
| 136 | 143 |
except OSError: |
| 137 | 144 |
continue |
| 138 | 145 |
filestr = file.read(200000) |
| 139 | 146 |
file.close() |
| 140 | 147 |
|
| 141 |
- if (('extra_match' in det
|
|
| 142 |
- and det['extra_match'] not in filestr) |
|
| 143 |
- or ('extra_nomatch' in det
|
|
| 144 |
- and det['extra_nomatch'] in filestr)): |
|
| 148 |
+ if ( |
|
| 149 |
+ "extra_match" in det and det["extra_match"] not in filestr |
|
| 150 |
+ ) or ( |
|
| 151 |
+ "extra_nomatch" in det and det["extra_nomatch"] in filestr |
|
| 152 |
+ ): |
|
| 145 | 153 |
continue |
| 146 | 154 |
|
| 147 |
- if ('path_match' in det
|
|
| 148 |
- and (not root.endswith(det['path_match']))): |
|
| 155 |
+ if "path_match" in det and ( |
|
| 156 |
+ not root.endswith(det["path_match"]) |
|
| 157 |
+ ): |
|
| 149 | 158 |
continue |
| 150 | 159 |
|
| 151 |
- findversion = re.search(re.escape(det['variable']) |
|
| 152 |
- + r"[^0-9\n\r]*[.]*" |
|
| 160 |
+ findversion = re.search( |
|
| 161 |
+ re.escape(det["variable"]) + r"[^0-9\n\r]*[.]*" |
|
| 153 | 162 |
"([0-9.]*[0-9])[^0-9.]", |
| 154 |
- filestr) |
|
| 163 |
+ filestr, |
|
| 164 |
+ ) |
|
| 155 | 165 |
if not findversion: |
| 156 | 166 |
continue |
| 157 | 167 |
findversion = findversion.group(1) |
| 158 | 168 |
|
| 159 | 169 |
# Very ugly phpbb workaround |
| 160 |
- if 'add_minor' in det: |
|
| 161 |
- findversion = findversion.split('.')
|
|
| 162 |
- findversion[-1] = str(int(findversion[-1]) |
|
| 163 |
- + int(det['add_minor'])) |
|
| 164 |
- findversion = '.'.join(findversion) |
|
| 165 |
- |
|
| 166 |
- if (not versioncompare(item['safe'], findversion) |
|
| 167 |
- or ('old_safe' in item
|
|
| 168 |
- and checkoldsafe(item['old_safe'], |
|
| 169 |
- findversion))): |
|
| 170 |
+ if "add_minor" in det: |
|
| 171 |
+ findversion = findversion.split(".")
|
|
| 172 |
+ findversion[-1] = str( |
|
| 173 |
+ int(findversion[-1]) + int(det["add_minor"]) |
|
| 174 |
+ ) |
|
| 175 |
+ findversion = ".".join(findversion) |
|
| 176 |
+ |
|
| 177 |
+ if not versioncompare(item["safe"], findversion) or ( |
|
| 178 |
+ "old_safe" in item |
|
| 179 |
+ and checkoldsafe(item["old_safe"], findversion) |
|
| 180 |
+ ): |
|
| 170 | 181 |
if opts.all: |
| 171 |
- vulnprint(item['name'], findversion, "ok", "", |
|
| 172 |
- mfile, det['subdir'], opts.xml) |
|
| 182 |
+ vulnprint( |
|
| 183 |
+ item["name"], |
|
| 184 |
+ findversion, |
|
| 185 |
+ "ok", |
|
| 186 |
+ "", |
|
| 187 |
+ mfile, |
|
| 188 |
+ det["subdir"], |
|
| 189 |
+ opts.xml, |
|
| 190 |
+ ) |
|
| 173 | 191 |
continue |
| 174 | 192 |
|
| 175 |
- safev = item['safe'] |
|
| 176 |
- if 'old_safe' in item: |
|
| 177 |
- for ver in item['old_safe'].split(','):
|
|
| 193 |
+ safev = item["safe"] |
|
| 194 |
+ if "old_safe" in item: |
|
| 195 |
+ for ver in item["old_safe"].split(","):
|
|
| 178 | 196 |
if versioncompare(ver, findversion): |
| 179 | 197 |
safev = ver |
| 180 | 198 |
|
| 181 |
- vulnprint(item['name'], findversion, safev, |
|
| 182 |
- item['vuln'], mfile, det['subdir'], opts.xml) |
|
| 199 |
+ vulnprint( |
|
| 200 |
+ item["name"], |
|
| 201 |
+ findversion, |
|
| 202 |
+ safev, |
|
| 203 |
+ item["vuln"], |
|
| 204 |
+ mfile, |
|
| 205 |
+ det["subdir"], |
|
| 206 |
+ opts.xml, |
|
| 207 |
+ ) |
|
| 183 | 208 |
|
| 184 | 209 |
if opts.xml: |
| 185 |
- print('</freewvs>')
|
|
| 210 |
+ print("</freewvs>")
|
| ... | ... |
@@ -4,34 +4,36 @@ import os |
| 4 | 4 |
import setuptools |
| 5 | 5 |
import setuptools.command.install |
| 6 | 6 |
|
| 7 |
-f = open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md'), |
|
| 8 |
- encoding="ascii") |
|
| 7 |
+f = open( |
|
| 8 |
+ os.path.join(os.path.abspath(os.path.dirname(__file__)), "README.md"), |
|
| 9 |
+ encoding="ascii", |
|
| 10 |
+) |
|
| 9 | 11 |
readme = f.read() |
| 10 | 12 |
f.close() |
| 11 | 13 |
|
| 12 | 14 |
setuptools.setup( |
| 13 |
- name='freewvs', |
|
| 15 |
+ name="freewvs", |
|
| 14 | 16 |
version="0.1.2", |
| 15 | 17 |
description="A free web vulnerability scanner", |
| 16 | 18 |
long_description=readme, |
| 17 |
- long_description_content_type='text/markdown', |
|
| 18 |
- url='https://freewvs.schokokeks.org/', |
|
| 19 |
+ long_description_content_type="text/markdown", |
|
| 20 |
+ url="https://freewvs.schokokeks.org/", |
|
| 19 | 21 |
packages=[], |
| 20 |
- scripts=['freewvs', 'update-freewvsdb'], |
|
| 21 |
- python_requires='>=3', |
|
| 22 |
+ scripts=["freewvs", "update-freewvsdb"], |
|
| 23 |
+ python_requires=">=3", |
|
| 22 | 24 |
license="CC0", |
| 23 |
- keywords=['security', 'vulnerability', 'web'], |
|
| 25 |
+ keywords=["security", "vulnerability", "web"], |
|
| 24 | 26 |
classifiers=[ |
| 25 |
- 'Development Status :: 4 - Beta', |
|
| 26 |
- 'Intended Audience :: System Administrators', |
|
| 27 |
- 'License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication', |
|
| 28 |
- 'Natural Language :: English', |
|
| 29 |
- 'Programming Language :: Python :: 3', |
|
| 30 |
- 'Programming Language :: Python :: 3 :: Only', |
|
| 31 |
- 'Programming Language :: Python :: 3.7', |
|
| 32 |
- 'Programming Language :: Python :: 3.8', |
|
| 33 |
- 'Programming Language :: Python :: 3.9', |
|
| 34 |
- 'Programming Language :: Python :: 3.10', |
|
| 35 |
- 'Programming Language :: Python :: 3.11', |
|
| 36 |
- ] |
|
| 27 |
+ "Development Status :: 4 - Beta", |
|
| 28 |
+ "Intended Audience :: System Administrators", |
|
| 29 |
+ "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", |
|
| 30 |
+ "Natural Language :: English", |
|
| 31 |
+ "Programming Language :: Python :: 3", |
|
| 32 |
+ "Programming Language :: Python :: 3 :: Only", |
|
| 33 |
+ "Programming Language :: Python :: 3.7", |
|
| 34 |
+ "Programming Language :: Python :: 3.8", |
|
| 35 |
+ "Programming Language :: Python :: 3.9", |
|
| 36 |
+ "Programming Language :: Python :: 3.10", |
|
| 37 |
+ "Programming Language :: Python :: 3.11", |
|
| 38 |
+ ], |
|
| 37 | 39 |
) |
| ... | ... |
@@ -6,21 +6,22 @@ import glob |
| 6 | 6 |
class TestCodingstyle(unittest.TestCase): |
| 7 | 7 |
@staticmethod |
| 8 | 8 |
def test_codingstyle(): |
| 9 |
- pyfiles = ["freewvs", "update-freewvsdb", |
|
| 10 |
- "setup.py"] + glob.glob("tests/*.py")
|
|
| 11 |
- subprocess.run(["pycodestyle", "--ignore=W503", "--max-line-length=88"] |
|
| 12 |
- + pyfiles, check=True) |
|
| 9 |
+ pyfiles = ["freewvs", "update-freewvsdb", "setup.py"] + glob.glob("tests/*.py")
|
|
| 10 |
+ subprocess.run( |
|
| 11 |
+ ["pycodestyle", "--ignore=W503", "--max-line-length=88"] + pyfiles, |
|
| 12 |
+ check=True, |
|
| 13 |
+ ) |
|
| 13 | 14 |
subprocess.run(["pyflakes"] + pyfiles, check=True) |
| 14 | 15 |
|
| 15 |
- pylint_disable = "missing-docstring,invalid-name,duplicate-code," \ |
|
| 16 |
+ pylint_disable = ( |
|
| 17 |
+ "missing-docstring,invalid-name,duplicate-code," |
|
| 16 | 18 |
+ "too-many-arguments,consider-using-with" |
| 17 |
- subprocess.run(["pylint", f"--disable={pylint_disable}"]
|
|
| 18 |
- + pyfiles, check=True) |
|
| 19 |
+ ) |
|
| 20 |
+ subprocess.run(["pylint", f"--disable={pylint_disable}"] + pyfiles, check=True)
|
|
| 19 | 21 |
|
| 20 | 22 |
subprocess.run(["flake8", "--select=DUO"] + pyfiles, check=True) |
| 21 |
- subprocess.run(["pyupgrade", "--py311-plus"] |
|
| 22 |
- + pyfiles, check=True) |
|
| 23 |
+ subprocess.run(["pyupgrade", "--py311-plus"] + pyfiles, check=True) |
|
| 23 | 24 |
|
| 24 | 25 |
|
| 25 |
-if __name__ == '__main__': |
|
| 26 |
+if __name__ == "__main__": |
|
| 26 | 27 |
unittest.main() |
| ... | ... |
@@ -11,44 +11,46 @@ TESTDATA_REPO = "https://github.com/schokokeksorg/freewvs-testdata" |
| 11 | 11 |
|
| 12 | 12 |
|
| 13 | 13 |
class TestFreewvsData(unittest.TestCase): |
| 14 |
- @unittest.skipUnless(os.environ.get("RUN_ONLINETESTS"),
|
|
| 15 |
- "Not running online tests") |
|
| 14 |
+ @unittest.skipUnless(os.environ.get("RUN_ONLINETESTS"), "Not running online tests")
|
|
| 16 | 15 |
def test_freewvs_testdata(self): |
| 17 | 16 |
tmp = tempfile.mkdtemp(prefix="testdata") |
| 18 | 17 |
if os.environ.get("TESTDATA_REPOSITORY"):
|
| 19 |
- os.symlink(os.environ.get("TESTDATA_REPOSITORY"),
|
|
| 20 |
- tmp + "/testdata") |
|
| 18 |
+ os.symlink(os.environ.get("TESTDATA_REPOSITORY"), tmp + "/testdata")
|
|
| 21 | 19 |
else: |
| 22 |
- subprocess.run(["git", "clone", "--depth=1", |
|
| 23 |
- TESTDATA_REPO, |
|
| 24 |
- tmp + "/testdata"], |
|
| 25 |
- check=True) |
|
| 20 |
+ subprocess.run( |
|
| 21 |
+ ["git", "clone", "--depth=1", TESTDATA_REPO, tmp + "/testdata"], |
|
| 22 |
+ check=True, |
|
| 23 |
+ ) |
|
| 26 | 24 |
|
| 27 | 25 |
for tdir in glob.glob(tmp + "/testdata/webapps/*"): |
| 28 | 26 |
bdir = os.path.basename(tdir) |
| 29 | 27 |
for tarball in glob.glob(tdir + "/dist/*"): |
| 30 | 28 |
tname = os.path.basename(tarball) |
| 31 |
- shutil.unpack_archive(tarball, |
|
| 32 |
- f"{tmp}/{bdir}/{tname}-src")
|
|
| 33 |
- fwrun = subprocess.run(["./freewvs", "-a", tmp + "/" + bdir], |
|
| 34 |
- stdout=subprocess.PIPE, check=True) |
|
| 29 |
+ shutil.unpack_archive(tarball, f"{tmp}/{bdir}/{tname}-src")
|
|
| 30 |
+ fwrun = subprocess.run( |
|
| 31 |
+ ["./freewvs", "-a", tmp + "/" + bdir], |
|
| 32 |
+ stdout=subprocess.PIPE, |
|
| 33 |
+ check=True, |
|
| 34 |
+ ) |
|
| 35 | 35 |
fwdata = re.sub(tmp, "[dir]", fwrun.stdout.decode("utf-8"))
|
| 36 |
- fwclean = re.sub(r' \(.* ', " ", fwdata) |
|
| 36 |
+ fwclean = re.sub(r" \(.* ", " ", fwdata) |
|
| 37 | 37 |
f = open(tdir + "/refdata-a.txt", encoding="ascii") |
| 38 | 38 |
refdata = f.read() |
| 39 | 39 |
f.close() |
| 40 |
- refclean = re.sub(r' \(.* ', " ", refdata) |
|
| 40 |
+ refclean = re.sub(r" \(.* ", " ", refdata) |
|
| 41 | 41 |
fwclean = sorted(fwclean.split("\n"))
|
| 42 | 42 |
refclean = sorted(refclean.split("\n"))
|
| 43 | 43 |
if refclean != fwclean: |
| 44 | 44 |
print("\n".join(difflib.ndiff(refclean, fwclean)))
|
| 45 |
- self.assertEqual(refclean, fwclean, |
|
| 46 |
- msg=f"Output in {bdir} does not match")
|
|
| 45 |
+ self.assertEqual(refclean, fwclean, msg=f"Output in {bdir} does not match")
|
|
| 47 | 46 |
|
| 48 | 47 |
# misc tests, for read errors, garbage data etc. |
| 49 |
- subprocess.run(["./freewvs", "-a", tmp + "/testdata/misc/"], |
|
| 50 |
- stdout=subprocess.PIPE, check=True) |
|
| 48 |
+ subprocess.run( |
|
| 49 |
+ ["./freewvs", "-a", tmp + "/testdata/misc/"], |
|
| 50 |
+ stdout=subprocess.PIPE, |
|
| 51 |
+ check=True, |
|
| 52 |
+ ) |
|
| 51 | 53 |
|
| 52 | 54 |
|
| 53 |
-if __name__ == '__main__': |
|
| 55 |
+if __name__ == "__main__": |
|
| 54 | 56 |
unittest.main() |
| ... | ... |
@@ -13,9 +13,9 @@ def versioncompare(safe_version, find_version): |
| 13 | 13 |
|
| 14 | 14 |
|
| 15 | 15 |
class TestJsonLint(unittest.TestCase): |
| 16 |
- |
|
| 17 |
- @unittest.skipIf(sys.version_info < (3, 6, 0), |
|
| 18 |
- "json.dumps force-sorts on python 3.5") |
|
| 16 |
+ @unittest.skipIf( |
|
| 17 |
+ sys.version_info < (3, 6, 0), "json.dumps force-sorts on python 3.5" |
|
| 18 |
+ ) |
|
| 19 | 19 |
def test_json_lint(self): |
| 20 | 20 |
valid = True |
| 21 | 21 |
for f in glob.glob("freewvsdb/*.json"):
|
| ... | ... |
@@ -32,48 +32,58 @@ class TestJsonLint(unittest.TestCase): |
| 32 | 32 |
|
| 33 | 33 |
def test_json_values(self): |
| 34 | 34 |
jconfig = [] |
| 35 |
- for cfile in glob.glob('freewvsdb/*.json'):
|
|
| 35 |
+ for cfile in glob.glob("freewvsdb/*.json"):
|
|
| 36 | 36 |
with open(cfile, encoding="ascii") as json_file: |
| 37 | 37 |
jconfig += json.load(json_file) |
| 38 | 38 |
|
| 39 |
- mkeys = {'name', 'url', 'safe', 'vuln', 'detection'}
|
|
| 39 |
+ mkeys = {"name", "url", "safe", "vuln", "detection"}
|
|
| 40 | 40 |
for item in jconfig: |
| 41 | 41 |
|
| 42 | 42 |
# check for all mandatory keys |
| 43 |
- self.assertEqual(mkeys.intersection(item.keys()), mkeys, |
|
| 44 |
- msg=f"Missing key in {item['name']}")
|
|
| 43 |
+ self.assertEqual( |
|
| 44 |
+ mkeys.intersection(item.keys()), |
|
| 45 |
+ mkeys, |
|
| 46 |
+ msg=f"Missing key in {item['name']}",
|
|
| 47 |
+ ) |
|
| 45 | 48 |
|
| 46 | 49 |
# check we have at least one detection |
| 47 |
- self.assertTrue(len(item['detection']) >= 1, |
|
| 48 |
- msg=f"No detection in {item['name']}")
|
|
| 50 |
+ self.assertTrue( |
|
| 51 |
+ len(item["detection"]) >= 1, msg=f"No detection in {item['name']}"
|
|
| 52 |
+ ) |
|
| 49 | 53 |
|
| 50 | 54 |
# vuln needs to be CVE or HTTPS URL |
| 51 |
- self.assertTrue(re.match("^CVE-[0-9]*-[0-9]*$", item['vuln'])
|
|
| 52 |
- or item['vuln'].startswith("https://"),
|
|
| 53 |
- msg=f"{item['name']}: Invalid vuln {item['vuln']}")
|
|
| 55 |
+ self.assertTrue( |
|
| 56 |
+ re.match("^CVE-[0-9]*-[0-9]*$", item["vuln"])
|
|
| 57 |
+ or item["vuln"].startswith("https://"),
|
|
| 58 |
+ msg=f"{item['name']}: Invalid vuln {item['vuln']}",
|
|
| 59 |
+ ) |
|
| 54 | 60 |
|
| 55 | 61 |
# make sure old_safe is properly sorted |
| 56 |
- if 'old_safe' in item: |
|
| 57 |
- old_safe = item['old_safe'].split(',')
|
|
| 62 |
+ if "old_safe" in item: |
|
| 63 |
+ old_safe = item["old_safe"].split(",")
|
|
| 58 | 64 |
for i in range(1, len(old_safe)): |
| 59 |
- self.assertTrue(versioncompare(old_safe[i - 1], |
|
| 60 |
- old_safe[i]), |
|
| 65 |
+ self.assertTrue( |
|
| 66 |
+ versioncompare(old_safe[i - 1], old_safe[i]), |
|
| 61 | 67 |
msg=f"{item['name']}: Invalid old_safe"
|
| 62 |
- " ordering {item['old_safe']}")
|
|
| 68 |
+ " ordering {item['old_safe']}",
|
|
| 69 |
+ ) |
|
| 63 | 70 |
|
| 64 | 71 |
# make sure latest is not outdated |
| 65 |
- if 'latest' in item and item['safe'] != "": |
|
| 66 |
- self.assertTrue(not versioncompare(item['safe'], |
|
| 67 |
- item['latest']), |
|
| 72 |
+ if "latest" in item and item["safe"] != "": |
|
| 73 |
+ self.assertTrue( |
|
| 74 |
+ not versioncompare(item["safe"], item["latest"]), |
|
| 68 | 75 |
msg=f"{item['name']}: Safe version "
|
| 69 | 76 |
"{item['safe']} newer than latest"
|
| 70 |
- " {item['latest']}")
|
|
| 77 |
+ " {item['latest']}",
|
|
| 78 |
+ ) |
|
| 71 | 79 |
|
| 72 | 80 |
# subdir needs to be integer |
| 73 |
- for det in item['detection']: |
|
| 74 |
- self.assertTrue(isinstance(det['subdir'], int), |
|
| 75 |
- msg=f"{item['name']}: subdir not int")
|
|
| 81 |
+ for det in item["detection"]: |
|
| 82 |
+ self.assertTrue( |
|
| 83 |
+ isinstance(det["subdir"], int), |
|
| 84 |
+ msg=f"{item['name']}: subdir not int",
|
|
| 85 |
+ ) |
|
| 76 | 86 |
|
| 77 | 87 |
|
| 78 |
-if __name__ == '__main__': |
|
| 88 |
+if __name__ == "__main__": |
|
| 79 | 89 |
unittest.main() |
| ... | ... |
@@ -9,7 +9,7 @@ import tarfile |
| 9 | 9 |
|
| 10 | 10 |
|
| 11 | 11 |
DBURL = "https://freewvsdb.schokokeks.org/" |
| 12 |
-dbpaths = ['/var/lib/freewvs/', str(pathlib.Path.home()) + "/.cache/freewvs/"] |
|
| 12 |
+dbpaths = ["/var/lib/freewvs/", str(pathlib.Path.home()) + "/.cache/freewvs/"] |
|
| 13 | 13 |
|
| 14 | 14 |
target = False |
| 15 | 15 |
for dbpath in dbpaths: |
| 16 | 16 |