From 8832c69bb3a25baf89419aaafda6bcf9d619a8ab Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 20 Jun 2024 15:26:14 +0200 Subject: [PATCH 01/24] add security linter bandit to nox --- exasol/toolbox/nox/_lint.py | 19 +++++++++++++ poetry.lock | 55 +++++++++++++++++++++++++++++++++++-- pyproject.toml | 1 + 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index b476c734..be2227f8 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -37,6 +37,18 @@ def _type_check(session: Session, files: Iterable[str]) -> None: ) +def _security_lint(session: Session, files: Iterable[str]) -> None: + session.run( + "poetry", + "run", + "python" + "bandit", + "-lll", + *files, + ) + + + @nox.session(python=False) def lint(session: Session) -> None: """Runs the linter on the project""" @@ -49,3 +61,10 @@ def type_check(session: Session) -> None: """Runs the type checker on the project""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] _type_check(session, py_files) + + +@nox.session(name="security-lint", python=False) +def security_lint(session: Session) -> None: + """runs the security linter bandit on the project""" + py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] + _type_check(session, py_files) diff --git a/poetry.lock b/poetry.lock index b8ca6798..f0c624bc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "alabaster" @@ -104,6 +104,31 @@ pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] +[[package]] +name = "bandit" +version = "1.7.9" +description = "Security oriented static analyser for python code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"}, + {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"}, +] + +[package.dependencies] +colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} +PyYAML = ">=5.3.1" +rich = "*" +stevedore = ">=1.20.0" +tomli = {version = ">=1.1.0", optional = true, markers = "python_version < \"3.11\" and extra == \"toml\""} + +[package.extras] +baseline = ["GitPython (>=3.1.30)"] +sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] +toml = ["tomli (>=1.1.0)"] +yaml = ["PyYAML"] + [[package]] name = "beautifulsoup4" version = "4.12.3" @@ -886,6 +911,17 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] +[[package]] +name = "pbr" +version = "6.0.0" +description = "Python Build Reasonableness" +optional = false +python-versions = ">=2.6" +files = [ + {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, + {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, +] + [[package]] name = "platformdirs" version = "4.2.2" @@ -1219,6 +1255,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1532,6 +1569,20 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "stevedore" +version = "5.2.0" +description = "Manage dynamic plugins for Python applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, + {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + [[package]] name = "tokenize-rt" version = "5.2.0" @@ -1670,4 +1721,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "53474f5621415a7d7492363b9307e6e3cd9d178bb9b6bc87c0b43400e6238c25" +content-hash = "51479a76d095da1392ac25c94c20728df6555e21f77640ff5688bc2759c4fa6c" diff --git a/pyproject.toml b/pyproject.toml index db9fc8ed..21a972f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,6 +56,7 @@ shibuya = ">=2024.5.14" sphinx-design = "^0.5.0" +bandit = {extras = ["toml"], version = "^1.7.9"} [tool.poetry.group.dev.dependencies] autoimport = "^1.4.0" From 8b307b99c015089c141ff8c64d67d0d6e4a204a2 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Fri, 21 Jun 2024 14:46:07 +0200 Subject: [PATCH 02/24] bandit starting problem solved --- exasol/toolbox/nox/_lint.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index be2227f8..ee5b9d88 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -41,9 +41,13 @@ def _security_lint(session: Session, files: Iterable[str]) -> None: session.run( "poetry", "run", - "python" "bandit", - "-lll", + "-l", + "-f", + "txt", + "-o", + ".security_lint.txt", + "-q", *files, ) @@ -67,4 +71,4 @@ def type_check(session: Session) -> None: def security_lint(session: Session) -> None: """runs the security linter bandit on the project""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] - _type_check(session, py_files) + _security_lint(session, py_files) From 5afccc262b7c840e62d9ace37a67815e2803c99e Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 26 Jun 2024 14:44:43 +0200 Subject: [PATCH 03/24] change bandit options --- exasol/toolbox/nox/_lint.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index ee5b9d88..6d9452f1 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -42,12 +42,9 @@ def _security_lint(session: Session, files: Iterable[str]) -> None: "poetry", "run", "bandit", - "-l", - "-f", - "txt", - "-o", - ".security_lint.txt", - "-q", + "--severity-level", + "low", + "--quiet", *files, ) @@ -67,7 +64,7 @@ def type_check(session: Session) -> None: _type_check(session, py_files) -@nox.session(name="security-lint", python=False) +@nox.session(name="security", python=False) def security_lint(session: Session) -> None: """runs the security linter bandit on the project""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] From bb62b2d3022880c52047445c3bf001aaca988179 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 3 Jul 2024 16:45:29 +0200 Subject: [PATCH 04/24] bandit report --- exasol/toolbox/metrics.py | 7 +++++-- exasol/toolbox/nox/_metrics.py | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 1af908de..e978f765 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -124,7 +124,9 @@ def reliability() -> Rating: return Rating.NotAvailable -def security() -> Rating: +def security(file: Union[str, Path]) -> Rating: + with open(file, 'r') as json_file: + security_lint = json.load(json_file) return Rating.NotAvailable @@ -137,6 +139,7 @@ def create_report( date: Optional[datetime.datetime] = None, coverage_report: Union[str, Path] = ".coverage", pylint_report: Union[str, Path] = ".lint.txt", + bandit_report: Union[str, Path] = ".security.json", ) -> Report: return Report( commit=commit, @@ -144,7 +147,7 @@ def create_report( coverage=total_coverage(coverage_report), maintainability=maintainability(pylint_report), reliability=reliability(), - security=security(), + security=security(bandit_report), technical_debt=technical_debt(), ) diff --git a/exasol/toolbox/nox/_metrics.py b/exasol/toolbox/nox/_metrics.py index 0d43936a..471390c2 100644 --- a/exasol/toolbox/nox/_metrics.py +++ b/exasol/toolbox/nox/_metrics.py @@ -47,6 +47,7 @@ def report(session: Session) -> None: required_files = ( PROJECT_CONFIG.root / ".coverage", PROJECT_CONFIG.root / ".lint.txt", + PROJECT_CONFIG.root / ".security.json", ) if not all(file.exists() for file in required_files): session.error( From 4ad9ac14da0bd11fefd1eeb741792091d680d55e Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Fri, 5 Jul 2024 15:11:21 +0200 Subject: [PATCH 05/24] add security scoring --- exasol/toolbox/metrics.py | 49 ++++++++++++++++++++++++++++++++++ exasol/toolbox/nox/_lint.py | 37 +++++++++++++++++-------- exasol/toolbox/nox/_metrics.py | 2 +- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index e978f765..02f612d3 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -130,6 +130,55 @@ def security(file: Union[str, Path]) -> Rating: return Rating.NotAvailable +def security_scoring(ratings: list[Dict[str, any]]) -> float: + evaluation = {"LL": 0, "LM": 0, "LH": 0, + "ML": 0, "MM": 0, "MH": 0, + "HL": 0, "HM": 0, "HH": 0} + for infos in ratings: + if infos["issue_severity"] == "HIGH": + severity = "H" + else: + if infos["issue_severity"] == "MEDIUM": + severity = "H" + else: + if infos["issue_severity"] == "LOW": + severity = "L" + else: + severity = "H" + + if infos["issue_confidence"] == "HIGH": + confidence = "H" + else: + if infos["issue_confidence"] == "MEDIUM": + confidence = "M" + else: + if infos["issue_confidence"] == "LOW": + confidence = "L" + else: + confidence = "H" + evaluation[f"{severity}{confidence}"] += 1 + weighting ={ + "HH": evaluation["HH"] * (4**(1/8))**8, + "HM": evaluation["HM"] * (4**(1/8))**7, + "HL": evaluation["HL"] * (4**(1/8))**6, + "MH": evaluation["MH"] * (4**(1/8))**5, + "MM": evaluation["MM"] * (4**(1/8))**4, + "ML": evaluation["ML"] * (4**(1/8))**3, + "LH": evaluation["LH"] * (4**(1/8))**2, + "LM": evaluation["LM"] * (4**(1/8))**1, + "LL": evaluation["LL"] * (4**(1/8))**0} + score = 0 + quantity = 0 + multiplier = 0 + for level in weighting: + score += weighting[level] * multiplier + quantity += weighting[level] + multiplier += 1 + if quantity == 0: + return 10 + return score / quantity + + def technical_debt() -> Rating: return Rating.NotAvailable diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index 6d9452f1..da733329 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -11,14 +11,15 @@ def _pylint(session: Session, files: Iterable[str]) -> None: session.run( - "poetry", - "run", - "python", - "-m", - "pylint", - "--output-format", - "colorized,json:.lint.json,text:.lint.txt", - *files) + "poetry", + "run", + "python", + "-m", + "pylint", + "--output-format", + "colorized,json:.lint.json,text:.lint.txt", + *files + ) def _type_check(session: Session, files: Iterable[str]) -> None: @@ -45,9 +46,23 @@ def _security_lint(session: Session, files: Iterable[str]) -> None: "--severity-level", "low", "--quiet", + "--format", + "json", + "--output", + ".security.json", + "--exit-zero", + *files, + ) + session.run( + "poetry", + "run", + "bandit", + "--severity-level", + "low", + "--quiet", + "--exit-zero", *files, ) - @nox.session(python=False) @@ -66,6 +81,6 @@ def type_check(session: Session) -> None: @nox.session(name="security", python=False) def security_lint(session: Session) -> None: - """runs the security linter bandit on the project""" + """runs the security linter bandit on the project without the test files""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] - _security_lint(session, py_files) + _security_lint(session, list(filter(lambda file: "test" not in file, py_files))) diff --git a/exasol/toolbox/nox/_metrics.py b/exasol/toolbox/nox/_metrics.py index 471390c2..d00ba06e 100644 --- a/exasol/toolbox/nox/_metrics.py +++ b/exasol/toolbox/nox/_metrics.py @@ -51,7 +51,7 @@ def report(session: Session) -> None: ) if not all(file.exists() for file in required_files): session.error( - "Please make sure you run the `coverage` and the `lint` target first" + "Please make sure you run the `coverage`, `security` and the `lint` target first" ) sha1 = str( session.run("git", "rev-parse", "HEAD", external=True, silent=True) From 0f0dfebf746b1948ea97824a4d2c3a09e381722d Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 9 Jul 2024 12:42:48 +0200 Subject: [PATCH 06/24] new bandit scoring + bandit rating --- exasol/toolbox/metrics.py | 81 +++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 02f612d3..fe3e35e7 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -67,6 +67,26 @@ def from_score(score: float) -> "Rating": "Uncategorized score, score should be in the following interval [0,10]." ) + @staticmethod + def bandit_rating(score: float) -> "Rating": + score = round(score, 3) + if score == 0: + return Rating.F + elif 0 < score <= 2: + return Rating.E + elif 2 < score <= 4: + return Rating.D + elif 4 < score <= 5: + return Rating.C + elif 5 < score <= 6: + return Rating.B + elif 6 < score <= 7: + return Rating.A + else: + raise ValueError( + "Uncategorized score, score should be in the following interval [0,7]." + ) + @dataclass(frozen=True) class Report: @@ -127,55 +147,48 @@ def reliability() -> Rating: def security(file: Union[str, Path]) -> Rating: with open(file, 'r') as json_file: security_lint = json.load(json_file) - return Rating.NotAvailable + return Rating.bandit_rating(bandit_scoring(security_lint["results"])) -def security_scoring(ratings: list[Dict[str, any]]) -> float: +def bandit_scoring(ratings: list[Dict[str, any]]) -> float: evaluation = {"LL": 0, "LM": 0, "LH": 0, - "ML": 0, "MM": 0, "MH": 0, - "HL": 0, "HM": 0, "HH": 0} + "ML": 0, "MM": 0, "MH": 0} + multiplier = {"LL": 6, "LM": 5, "LH": 4, + "ML": 3, "MM": 2, "MH": 1} for infos in ratings: if infos["issue_severity"] == "HIGH": - severity = "H" + return 0.0 + elif infos["issue_severity"] == "MEDIUM": + severity = "M" + elif infos["issue_severity"] == "LOW": + severity = "L" else: - if infos["issue_severity"] == "MEDIUM": - severity = "H" - else: - if infos["issue_severity"] == "LOW": - severity = "L" - else: - severity = "H" - + severity = "H" if infos["issue_confidence"] == "HIGH": confidence = "H" + elif infos["issue_confidence"] == "MEDIUM": + confidence = "M" + elif infos["issue_confidence"] == "LOW": + confidence = "L" else: - if infos["issue_confidence"] == "MEDIUM": - confidence = "M" - else: - if infos["issue_confidence"] == "LOW": - confidence = "L" - else: - confidence = "H" + confidence = "H" evaluation[f"{severity}{confidence}"] += 1 - weighting ={ - "HH": evaluation["HH"] * (4**(1/8))**8, - "HM": evaluation["HM"] * (4**(1/8))**7, - "HL": evaluation["HL"] * (4**(1/8))**6, - "MH": evaluation["MH"] * (4**(1/8))**5, - "MM": evaluation["MM"] * (4**(1/8))**4, - "ML": evaluation["ML"] * (4**(1/8))**3, - "LH": evaluation["LH"] * (4**(1/8))**2, - "LM": evaluation["LM"] * (4**(1/8))**1, - "LL": evaluation["LL"] * (4**(1/8))**0} + + print(evaluation) + weighting = { + "MH": evaluation["MH"] * (1/(2 ** (1 / 4))) ** 5, + "MM": evaluation["MM"] * (1/(2 ** (1 / 4))) ** 4, + "ML": evaluation["ML"] * (1/(2 ** (1 / 4))) ** 3, + "LH": evaluation["LH"] * (1/(2 ** (1 / 4))) ** 2, + "LM": evaluation["LM"] * (1/(2 ** (1 / 4))) ** 1, + "LL": evaluation["LL"] * (1/(2 ** (1 / 4))) ** 0} score = 0 quantity = 0 - multiplier = 0 for level in weighting: - score += weighting[level] * multiplier + score += weighting[level] * multiplier[level] quantity += weighting[level] - multiplier += 1 if quantity == 0: - return 10 + return 7 return score / quantity From fdd11faf5e1ce1831b1ebe1659ee94f92f6d1ad2 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 9 Jul 2024 12:46:52 +0200 Subject: [PATCH 07/24] typing List --- exasol/toolbox/metrics.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index fe3e35e7..72c58e63 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -21,6 +21,7 @@ Dict, Optional, Union, + List, ) @@ -150,7 +151,7 @@ def security(file: Union[str, Path]) -> Rating: return Rating.bandit_rating(bandit_scoring(security_lint["results"])) -def bandit_scoring(ratings: list[Dict[str, any]]) -> float: +def bandit_scoring(ratings: List[Dict[str, any]]) -> float: evaluation = {"LL": 0, "LM": 0, "LH": 0, "ML": 0, "MM": 0, "MH": 0} multiplier = {"LL": 6, "LM": 5, "LH": 4, From 75fa656719c7979ae457a98922f9f6651ef97d57 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 9 Jul 2024 12:55:41 +0200 Subject: [PATCH 08/24] types corrected --- exasol/toolbox/metrics.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 72c58e63..472199a4 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -19,9 +19,9 @@ Any, Callable, Dict, + List, Optional, Union, - List, ) @@ -146,16 +146,14 @@ def reliability() -> Rating: def security(file: Union[str, Path]) -> Rating: - with open(file, 'r') as json_file: + with open(file) as json_file: security_lint = json.load(json_file) return Rating.bandit_rating(bandit_scoring(security_lint["results"])) -def bandit_scoring(ratings: List[Dict[str, any]]) -> float: - evaluation = {"LL": 0, "LM": 0, "LH": 0, - "ML": 0, "MM": 0, "MH": 0} - multiplier = {"LL": 6, "LM": 5, "LH": 4, - "ML": 3, "MM": 2, "MH": 1} +def bandit_scoring(ratings: List[Dict[str, Any]]) -> float: + evaluation = {"LL": 0, "LM": 0, "LH": 0, "ML": 0, "MM": 0, "MH": 0} + multiplier = {"LL": 6, "LM": 5, "LH": 4, "ML": 3, "MM": 2, "MH": 1} for infos in ratings: if infos["issue_severity"] == "HIGH": return 0.0 @@ -177,14 +175,15 @@ def bandit_scoring(ratings: List[Dict[str, any]]) -> float: print(evaluation) weighting = { - "MH": evaluation["MH"] * (1/(2 ** (1 / 4))) ** 5, - "MM": evaluation["MM"] * (1/(2 ** (1 / 4))) ** 4, - "ML": evaluation["ML"] * (1/(2 ** (1 / 4))) ** 3, - "LH": evaluation["LH"] * (1/(2 ** (1 / 4))) ** 2, - "LM": evaluation["LM"] * (1/(2 ** (1 / 4))) ** 1, - "LL": evaluation["LL"] * (1/(2 ** (1 / 4))) ** 0} - score = 0 - quantity = 0 + "MH": evaluation["MH"] * (1 / (2 ** (1 / 4))) ** 5, + "MM": evaluation["MM"] * (1 / (2 ** (1 / 4))) ** 4, + "ML": evaluation["ML"] * (1 / (2 ** (1 / 4))) ** 3, + "LH": evaluation["LH"] * (1 / (2 ** (1 / 4))) ** 2, + "LM": evaluation["LM"] * (1 / (2 ** (1 / 4))) ** 1, + "LL": evaluation["LL"] * (1 / (2 ** (1 / 4))) ** 0, + } + score = 0.0 + quantity = 0.0 for level in weighting: score += weighting[level] * multiplier[level] quantity += weighting[level] From 283f368db3d0b4d81f999b0b89e8c8fa03ece82e Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 11 Jul 2024 10:40:40 +0200 Subject: [PATCH 09/24] added a test for bandit_scoring --- exasol/toolbox/metrics.py | 6 ++---- test/unit/report_test.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 472199a4..6c3dd255 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -148,10 +148,10 @@ def reliability() -> Rating: def security(file: Union[str, Path]) -> Rating: with open(file) as json_file: security_lint = json.load(json_file) - return Rating.bandit_rating(bandit_scoring(security_lint["results"])) + return Rating.bandit_rating(_bandit_scoring(security_lint["results"])) -def bandit_scoring(ratings: List[Dict[str, Any]]) -> float: +def _bandit_scoring(ratings: List[Dict[str, Any]]) -> float: evaluation = {"LL": 0, "LM": 0, "LH": 0, "ML": 0, "MM": 0, "MH": 0} multiplier = {"LL": 6, "LM": 5, "LH": 4, "ML": 3, "MM": 2, "MH": 1} for infos in ratings: @@ -172,8 +172,6 @@ def bandit_scoring(ratings: List[Dict[str, Any]]) -> float: else: confidence = "H" evaluation[f"{severity}{confidence}"] += 1 - - print(evaluation) weighting = { "MH": evaluation["MH"] * (1 / (2 ** (1 / 4))) ** 5, "MM": evaluation["MM"] * (1 / (2 ** (1 / 4))) ** 4, diff --git a/test/unit/report_test.py b/test/unit/report_test.py index 24f7c9a6..df6c2494 100644 --- a/test/unit/report_test.py +++ b/test/unit/report_test.py @@ -5,6 +5,7 @@ from exasol.toolbox.metrics import ( Rating, _static_code_analysis, + _bandit_scoring, ) @@ -110,3 +111,22 @@ def test_static_code_analysis( coverage_report = named_temp_file(name=".lint.txt", content=content) actual = _static_code_analysis(coverage_report) assert actual == expected + + +@pytest.mark.parametrize( + "rating, expected", + [ + ([{"issue_severity": "HIGH", "issue_confidence": "HIGH"}], 0), + ([{"issue_severity": "HIGH", "issue_confidence": "MEDIUM"}], 0), + ([{"issue_severity": "HIGH", "issue_confidence": "LOW"}], 0), + ([{"issue_severity": "MEDIUM", "issue_confidence": "HIGH"}], 1), + ([{"issue_severity": "MEDIUM", "issue_confidence": "MEDIUM"}], 2), + ([{"issue_severity": "MEDIUM", "issue_confidence": "LOW"}], 3), + ([{"issue_severity": "LOW", "issue_confidence": "HIGH"}], 4), + ([{"issue_severity": "LOW", "issue_confidence": "MEDIUM"}], 5), + ([{"issue_severity": "LOW", "issue_confidence": "LOW"}], 6), + ] +) +def test_bandit_scoring(rating, expected): + actual = _bandit_scoring(rating) + assert actual <= expected From ce0b1d012f13487766352d72e6847de9da832f15 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 11 Jul 2024 10:49:16 +0200 Subject: [PATCH 10/24] run bandit test --- .security.json | 997 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 997 insertions(+) create mode 100644 .security.json diff --git a/.security.json b/.security.json new file mode 100644 index 00000000..8c0980ce --- /dev/null +++ b/.security.json @@ -0,0 +1,997 @@ +{ + "errors": [], + "generated_at": "2024-07-11T08:48:31Z", + "metrics": { + "/home/jami/Git/python-toolbox/doc/conf.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 35, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/doc/user_guide/modules/sphinx/multiversion/conf.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 38, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/cli.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 8, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/error.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 2, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/git.py": { + "CONFIDENCE.HIGH": 2, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 2, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 12, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py": { + "CONFIDENCE.HIGH": 3, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 3, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 294, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_documentation.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 39, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_format.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 33, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_lint.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 71, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_metrics.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 53, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_release.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 127, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_shared.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 52, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/plugin.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 85, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/nox/tasks.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 60, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py": { + "CONFIDENCE.HIGH": 3, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 2, + "SEVERITY.MEDIUM": 1, + "SEVERITY.UNDEFINED": 0, + "loc": 110, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py": { + "CONFIDENCE.HIGH": 2, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 2, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 123, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/github.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 22, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/__main__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 3, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py": { + "CONFIDENCE.HIGH": 6, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 1, + "SEVERITY.LOW": 5, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 139, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py": { + "CONFIDENCE.HIGH": 4, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 2, + "SEVERITY.LOW": 2, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 499, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/sphinx.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 208, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/templates/noxconfig.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 26, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/templates/noxfile.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 3, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/__init__.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 0, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/issue.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 67, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/replace_version.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 24, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py": { + "CONFIDENCE.HIGH": 3, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 3, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 203, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/tbx.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 12, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/template.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 135, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/tools/workflow.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 69, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/exasol/toolbox/version.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 4, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/noxconfig.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 30, + "nosec": 0, + "skipped_tests": 0 + }, + "/home/jami/Git/python-toolbox/noxfile.py": { + "CONFIDENCE.HIGH": 0, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 0, + "SEVERITY.LOW": 0, + "SEVERITY.MEDIUM": 0, + "SEVERITY.UNDEFINED": 0, + "loc": 51, + "nosec": 0, + "skipped_tests": 0 + }, + "_totals": { + "CONFIDENCE.HIGH": 23, + "CONFIDENCE.LOW": 0, + "CONFIDENCE.MEDIUM": 0, + "CONFIDENCE.UNDEFINED": 0, + "SEVERITY.HIGH": 3, + "SEVERITY.LOW": 19, + "SEVERITY.MEDIUM": 1, + "SEVERITY.UNDEFINED": 0, + "loc": 2637, + "nosec": 0, + "skipped_tests": 0 + } + }, + "results": [ + { + "code": "1 import subprocess\n2 from typing import Iterable\n3 \n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 1, + "line_range": [ + 1 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "12 command = [\"git\", \"tag\", \"--sort=committerdate\"]\n13 result = subprocess.run(command, capture_output=True, check=True)\n14 return [tag.strip() for tag in result.stdout.decode(\"utf-8\").splitlines()]\n", + "col_offset": 13, + "end_col_offset": 69, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 13, + "line_range": [ + 13 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "15 from pathlib import Path\n16 from subprocess import run\n17 from tempfile import TemporaryDirectory\n", + "col_offset": 0, + "end_col_offset": 26, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 16, + "line_range": [ + 16 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "106 report = tmp_dir / \"coverage.json\"\n107 run(\n108 [\"coverage\", \"json\", f\"--data-file={file}\", \"-o\", f\"{report}\"],\n109 capture_output=True,\n110 check=True,\n111 )\n112 with open(report, encoding=\"utf-8\") as r:\n", + "col_offset": 8, + "end_col_offset": 9, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Starting a process with a partial executable path", + "line_number": 107, + "line_range": [ + 107, + 108, + 109, + 110, + 111 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b607_start_process_with_partial_path.html", + "test_id": "B607", + "test_name": "start_process_with_partial_path" + }, + { + "code": "106 report = tmp_dir / \"coverage.json\"\n107 run(\n108 [\"coverage\", \"json\", f\"--data-file={file}\", \"-o\", f\"{report}\"],\n109 capture_output=True,\n110 check=True,\n111 )\n112 with open(report, encoding=\"utf-8\") as r:\n", + "col_offset": 8, + "end_col_offset": 9, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 107, + "line_range": [ + 107, + 108, + 109, + 110, + 111 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "1 import subprocess\n2 import sys\n3 from argparse import (\n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 1, + "line_range": [ + 1 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "53 _globals: Dict[str, Any] = {}\n54 exec(file.read(), _locals, _globals)\n55 \n", + "col_offset": 8, + "end_col_offset": 44, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "MEDIUM", + "issue_text": "Use of exec detected.", + "line_number": 54, + "line_range": [ + 54 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b102_exec_used.html", + "test_id": "B102", + "test_name": "exec_used" + }, + { + "code": "68 \n69 result = subprocess.run(\n70 [poetry, \"version\", \"--no-ansi\"], capture_output=True, check=False\n71 )\n72 version = result.stdout.decode().split()[1]\n", + "col_offset": 13, + "end_col_offset": 5, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 69, + "line_range": [ + 69, + 70, + 71 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "2 \n3 import subprocess\n4 from dataclasses import dataclass\n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 3, + "line_range": [ + 3 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "70 try:\n71 result = subprocess.run(\n72 [poetry, \"version\", \"--no-ansi\", \"--short\"], capture_output=True\n73 )\n74 except subprocess.CalledProcessError as ex:\n", + "col_offset": 21, + "end_col_offset": 13, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 71, + "line_range": [ + 71, + 72, + 73 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "5 import re\n6 import subprocess\n7 import tarfile\n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 6, + "line_range": [ + 6 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "30 )\n31 output = subprocess.check_output(cmd, cwd=cwd).decode()\n32 return output.rstrip(\"\\n\")\n", + "col_offset": 13, + "end_col_offset": 50, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 31, + "line_range": [ + 31 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "42 )\n43 output = subprocess.check_output(cmd, cwd=gitroot).decode()\n44 for line in output.splitlines():\n", + "col_offset": 13, + "end_col_offset": 54, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 43, + "line_range": [ + 43 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "135 )\n136 proc = subprocess.run(\n137 cmd,\n138 cwd=gitroot,\n139 stdout=subprocess.DEVNULL,\n140 stderr=subprocess.DEVNULL,\n141 check=False,\n142 )\n143 return proc.returncode == 0\n", + "col_offset": 11, + "end_col_offset": 5, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 136, + "line_range": [ + 136, + 137, + 138, + 139, + 140, + 141, + 142 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "156 )\n157 subprocess.check_call(cmd, cwd=gitroot, stdout=fp)\n158 fp.seek(0)\n", + "col_offset": 8, + "end_col_offset": 58, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 157, + "line_range": [ + 157 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "159 with tarfile.TarFile(fileobj=fp) as tarfp:\n160 tarfp.extractall(dst)\n", + "col_offset": 12, + "end_col_offset": 33, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 22, + "link": "https://cwe.mitre.org/data/definitions/22.html" + }, + "issue_severity": "HIGH", + "issue_text": "tarfile.extractall used without any validation. Please check and discard dangerous members.", + "line_number": 160, + "line_range": [ + 160 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b202_tarfile_unsafe_members.html", + "test_id": "B202", + "test_name": "tarfile_unsafe_members" + }, + { + "code": "12 import string\n13 import subprocess\n14 import sys\n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 13, + "line_range": [ + 13 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "402 subprocess.check_call(\n403 config.smv_prebuild_command, cwd=current_cwd, shell=True\n404 )\n405 \n406 if config.smv_prebuild_export_pattern != \"\":\n", + "col_offset": 16, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "HIGH", + "issue_text": "subprocess call with shell=True identified, security issue.", + "line_number": 403, + "line_range": [ + 402, + 403, + 404 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b602_subprocess_popen_with_shell_equals_true.html", + "test_id": "B602", + "test_name": "subprocess_popen_with_shell_equals_true" + }, + { + "code": "470 # Run sphinx-build\n471 subprocess.check_call(cmd, cwd=current_cwd, env=env)\n472 \n", + "col_offset": 16, + "end_col_offset": 68, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 471, + "line_range": [ + 471 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "555 subprocess.check_call(\n556 config.smv_postbuild_command, cwd=current_cwd, shell=True\n557 )\n558 if config.smv_postbuild_export_pattern != \"\":\n559 matches = find_matching_files_and_dirs(\n", + "col_offset": 16, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "HIGH", + "issue_text": "subprocess call with shell=True identified, security issue.", + "line_number": 556, + "line_range": [ + 555, + 556, + 557 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b602_subprocess_popen_with_shell_equals_true.html", + "test_id": "B602", + "test_name": "subprocess_popen_with_shell_equals_true" + }, + { + "code": "3 import re\n4 import subprocess\n5 import sys\n", + "col_offset": 0, + "end_col_offset": 17, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "Consider possible security implications associated with the subprocess module.", + "line_number": 4, + "line_range": [ + 4 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", + "test_id": "B404", + "test_name": "blacklist" + }, + { + "code": "68 try:\n69 result = subprocess.run(command, check=True, capture_output=True)\n70 except FileNotFoundError as ex:\n", + "col_offset": 17, + "end_col_offset": 73, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 69, + "line_range": [ + 69 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + }, + { + "code": "142 try:\n143 result = subprocess.run(command, check=True, capture_output=True)\n144 except FileNotFoundError as ex:\n", + "col_offset": 17, + "end_col_offset": 73, + "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", + "issue_confidence": "HIGH", + "issue_cwe": { + "id": 78, + "link": "https://cwe.mitre.org/data/definitions/78.html" + }, + "issue_severity": "LOW", + "issue_text": "subprocess call - check for execution of untrusted input.", + "line_number": 143, + "line_range": [ + 143 + ], + "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", + "test_id": "B603", + "test_name": "subprocess_without_shell_equals_true" + } + ] +} \ No newline at end of file From 9a9dff1a63f82425d3268ee29e71d0cdc541938e Mon Sep 17 00:00:00 2001 From: Nicola Coretti Date: Fri, 5 Jul 2024 10:40:41 +0200 Subject: [PATCH 11/24] Update depdendency constraints (#214) --- doc/changes/unreleased.md | 3 + poetry.lock | 168 +++++++++++++++++++------------------- pyproject.toml | 10 +-- 3 files changed, 92 insertions(+), 89 deletions(-) diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 4d8eac50..9fbc10b8 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -3,3 +3,6 @@ ## ✨ Added * Added cookiecutter-template for creating new project +## 🔩 Internal +* Update depdency constraints +* Relock dependencies diff --git a/poetry.lock b/poetry.lock index a7de77c8..38df22f3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -41,13 +41,13 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] [[package]] name = "astroid" -version = "3.2.2" +version = "3.2.3" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" files = [ - {file = "astroid-3.2.2-py3-none-any.whl", hash = "sha256:e8a0083b4bb28fcffb6207a3bfc9e5d0a68be951dd7e336d5dcf639c682388c0"}, - {file = "astroid-3.2.2.tar.gz", hash = "sha256:8ead48e31b92b2e217b6c9733a21afafe479d52d6e164dd25fb1a770c7c3cf94"}, + {file = "astroid-3.2.3-py3-none-any.whl", hash = "sha256:3eae9ea67c11c858cdd2c91337d2e816bd019ac897ca07d7b346ac10105fceb3"}, + {file = "astroid-3.2.3.tar.gz", hash = "sha256:7099b5a60985529d8d46858befa103b82d0d05a5a5e8b816b5303ed96075e1d9"}, ] [package.dependencies] @@ -70,13 +70,13 @@ tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} [[package]] name = "autoimport" -version = "1.5.0" +version = "1.6.0" description = "Autoimport missing python libraries." optional = false python-versions = ">=3.8" files = [ - {file = "autoimport-1.5.0-py3-none-any.whl", hash = "sha256:8966768b35219fdcf457c708391072bbd38da134253f376d07d72822bd73a8de"}, - {file = "autoimport-1.5.0.tar.gz", hash = "sha256:c136a3944d2267d5f6f228221956b55b55a53bd9c43b0719d08e3a0252a35e9a"}, + {file = "autoimport-1.6.0-py3-none-any.whl", hash = "sha256:917713701035f23fcd6d85ad3d51bab6c09e10802e4296f08ec7d712b1c18242"}, + {file = "autoimport-1.6.0.tar.gz", hash = "sha256:94e7ee73469c4de4a37ce1eb9d59ffced163a0df066cb3b7f4d3c2af52683db4"}, ] [package.dependencies] @@ -361,63 +361,63 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] [[package]] name = "coverage" -version = "7.5.4" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, - {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, - {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, - {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, - {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, - {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, - {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, - {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, - {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, - {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, - {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, - {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, - {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, - {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, - {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, - {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, - {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, - {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, - {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, - {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, - {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, - {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, - {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, - {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, - {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, - {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, - {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, - {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.extras] @@ -451,24 +451,24 @@ files = [ [[package]] name = "docutils" -version = "0.19" +version = "0.20.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=3.7" files = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -509,13 +509,13 @@ sphinx-basic-ng = ">=1.0.0.beta2" [[package]] name = "identify" -version = "2.5.36" +version = "2.6.0" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"}, + {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"}, ] [package.extras] @@ -973,13 +973,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prysk" -version = "0.17.0" +version = "0.20.0" description = "Functional tests for command line applications" optional = false -python-versions = ">=3.8,<4.0.0" +python-versions = "<4.0.0,>=3.8" files = [ - {file = "prysk-0.17.0-py3-none-any.whl", hash = "sha256:c2e0ce69ede821e5a7e03f576c51e2a35000c570f6e22cf7c13daec1b3978832"}, - {file = "prysk-0.17.0.tar.gz", hash = "sha256:0a500bb9ff742eca878d5802bad9fcfd7ba1c6bbae64b2a2ff96bff94d4f8ad8"}, + {file = "prysk-0.20.0-py3-none-any.whl", hash = "sha256:3758f59febe1ff27710c8ba69a8edad42286050d041ed8df519fc4bbeea41133"}, + {file = "prysk-0.20.0.tar.gz", hash = "sha256:3499d24c9c8d534754d3915218cb2ab59cf59a8d6f37acfb68dc582650e67e33"}, ] [package.dependencies] @@ -1366,13 +1366,13 @@ files = [ [[package]] name = "shibuya" -version = "2024.6.23" +version = "2024.7.13" description = "A clean, responsive, and customizable Sphinx documentation theme with light/dark mode." optional = false python-versions = ">=3.7" files = [ - {file = "shibuya-2024.6.23-py3-none-any.whl", hash = "sha256:0ec37b150efb107d699318358ee106a1d2f01221d468adc0e716a6d09e3d77b5"}, - {file = "shibuya-2024.6.23.tar.gz", hash = "sha256:efb7da3c6691ff9cd475c93f1c1bea3a10377756ea32fd6da6bccf4adab33e38"}, + {file = "shibuya-2024.7.13-py3-none-any.whl", hash = "sha256:810dde8580d46ce31f3de356fca715d5a2389ecfbfcba653f03086028bb1e5f4"}, + {file = "shibuya-2024.7.13.tar.gz", hash = "sha256:8fbe547d371e907a55d185b9471dc57c4823cfb344ed7ff7eed1a13c881abd11"}, ] [package.dependencies] @@ -1402,20 +1402,20 @@ files = [ [[package]] name = "sphinx" -version = "6.2.1" +version = "7.1.2" description = "Python documentation generator" optional = false python-versions = ">=3.8" files = [ - {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, - {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, + {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"}, + {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.20" +docutils = ">=0.18.1,<0.21" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" @@ -1631,13 +1631,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.5" +version = "0.13.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, - {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, ] [[package]] @@ -1734,4 +1734,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "4de549e8fcc08af9bd47c34cb7465c8e3a25599ba83ec3991c479e7642321a9e" +content-hash = "fa25028120b416a0b7acf67737e56c82ca386f73e14587ccf7d58e67f95de91c" diff --git a/pyproject.toml b/pyproject.toml index 129a7e69..1e26dbff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,24 +36,24 @@ keywords = [ [tool.poetry.dependencies] python = "^3.8" nox = ">=2022.8.7" -sphinx = ">=5.3,<7.0" -pytest = "^7.2.2" +sphinx = ">=5.3,<8" +pytest = ">=7.2.2,<9" mypy = ">=0.971" sphinx-copybutton = "^0.5.0" furo = ">=2022.9.15" pyupgrade = ">=2.38.2,<4.0.0" black = ">=24.1.0" isort = "^5.12.0" -pre-commit = "^3.1.1" +pre-commit = ">=3.1.1,<4" coverage = ">=6.4.4,<8.0.0" pylint = ">=2.15.4" typer = {extras = ["all"], version = ">=0.7.0"} -prysk = {extras = ["pytest-plugin"], version = "^0.17.0"} +prysk = {extras = ["pytest-plugin"], version = ">0.17.0,<1"} importlib-resources = ">=5.12.0" myst-parser = ">=2.0.0,<4" pluggy = "^1.5.0" shibuya = ">=2024.5.14" -sphinx-design = "^0.5.0" +sphinx-design = ">=0.5.0,<1" bandit = {extras = ["toml"], version = "^1.7.9"} From ad400347284975c0da3f8a53a3794d1b5a6e509b Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 20 Jun 2024 15:26:14 +0200 Subject: [PATCH 12/24] add security linter bandit to nox --- exasol/toolbox/nox/_lint.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index da733329..72f35eae 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -11,15 +11,14 @@ def _pylint(session: Session, files: Iterable[str]) -> None: session.run( - "poetry", - "run", - "python", - "-m", - "pylint", - "--output-format", - "colorized,json:.lint.json,text:.lint.txt", - *files - ) + "poetry", + "run", + "python", + "-m", + "pylint", + "--output-format", + "colorized,json:.lint.json,text:.lint.txt", + *files) def _type_check(session: Session, files: Iterable[str]) -> None: From 7d4c1eb32866fb6930800409b9a330821f8f3609 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 16 Jul 2024 10:11:18 +0200 Subject: [PATCH 13/24] problems solved --- exasol/toolbox/metrics.py | 54 ++++++++++++++--------------------- test/unit/report_test.py | 59 +++++++++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 6c3dd255..0c319a0a 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -152,43 +152,31 @@ def security(file: Union[str, Path]) -> Rating: def _bandit_scoring(ratings: List[Dict[str, Any]]) -> float: - evaluation = {"LL": 0, "LM": 0, "LH": 0, "ML": 0, "MM": 0, "MH": 0} - multiplier = {"LL": 6, "LM": 5, "LH": 4, "ML": 3, "MM": 2, "MH": 1} + def char(value: str, default: str = "H") -> str: + if value in ["HIGH", "MEDIUM", "LOW"]: + return value[0] + return default + + def rating_dict(*values: int) -> Dict[str, int]: + return dict(zip(["LL", "LM", "LH", "ML", "MM", "MH"], values)) + + count = rating_dict(0, 0, 0, 0, 0, 0,) for infos in ratings: - if infos["issue_severity"] == "HIGH": + severity = infos["issue_severity"] + if severity == "HIGH": return 0.0 - elif infos["issue_severity"] == "MEDIUM": - severity = "M" - elif infos["issue_severity"] == "LOW": - severity = "L" - else: - severity = "H" - if infos["issue_confidence"] == "HIGH": - confidence = "H" - elif infos["issue_confidence"] == "MEDIUM": - confidence = "M" - elif infos["issue_confidence"] == "LOW": - confidence = "L" - else: - confidence = "H" - evaluation[f"{severity}{confidence}"] += 1 - weighting = { - "MH": evaluation["MH"] * (1 / (2 ** (1 / 4))) ** 5, - "MM": evaluation["MM"] * (1 / (2 ** (1 / 4))) ** 4, - "ML": evaluation["ML"] * (1 / (2 ** (1 / 4))) ** 3, - "LH": evaluation["LH"] * (1 / (2 ** (1 / 4))) ** 2, - "LM": evaluation["LM"] * (1 / (2 ** (1 / 4))) ** 1, - "LL": evaluation["LL"] * (1 / (2 ** (1 / 4))) ** 0, - } + index = char(severity) + char(infos["issue_confidence"]) + count[index] += 1 + weight: Dict[str, float] = rating_dict(0, 1, 2, 3, 4, 5) + for k, v in weight.items(): + weight[k] = count[k] * round((2 ** 0.20) ** v, 10) score = 0.0 quantity = 0.0 - for level in weighting: - score += weighting[level] * multiplier[level] - quantity += weighting[level] - if quantity == 0: - return 7 - return score / quantity - + factor = rating_dict(6, 5, 4, 3, 2, 1) + for value in weight: + score += weight[value] * factor[value] + quantity += weight[value] + return 7 if quantity == 0 else score / quantity def technical_debt() -> Rating: return Rating.NotAvailable diff --git a/test/unit/report_test.py b/test/unit/report_test.py index df6c2494..15000a44 100644 --- a/test/unit/report_test.py +++ b/test/unit/report_test.py @@ -7,6 +7,7 @@ _static_code_analysis, _bandit_scoring, ) +from typing import List, Dict @pytest.mark.parametrize( @@ -114,19 +115,53 @@ def test_static_code_analysis( @pytest.mark.parametrize( - "rating, expected", + "severity, confidence, expected", [ - ([{"issue_severity": "HIGH", "issue_confidence": "HIGH"}], 0), - ([{"issue_severity": "HIGH", "issue_confidence": "MEDIUM"}], 0), - ([{"issue_severity": "HIGH", "issue_confidence": "LOW"}], 0), - ([{"issue_severity": "MEDIUM", "issue_confidence": "HIGH"}], 1), - ([{"issue_severity": "MEDIUM", "issue_confidence": "MEDIUM"}], 2), - ([{"issue_severity": "MEDIUM", "issue_confidence": "LOW"}], 3), - ([{"issue_severity": "LOW", "issue_confidence": "HIGH"}], 4), - ([{"issue_severity": "LOW", "issue_confidence": "MEDIUM"}], 5), - ([{"issue_severity": "LOW", "issue_confidence": "LOW"}], 6), + ("HIGH", "HIGH", 0), + ("HIGH", "MEDIUM", 0), + ("HIGH", "LOW", 0), + ("MEDIUM", "HIGH", 1), + ("MEDIUM", "MEDIUM", 2), + ("MEDIUM", "LOW", 3), + ("LOW", "HIGH", 4), + ("LOW", "MEDIUM", 5), + ("LOW", "LOW", 6), ] ) -def test_bandit_scoring(rating, expected): +def test_bandit_scoring(severity, confidence, expected): + rating = [{"issue_severity": severity, "issue_confidence": confidence}] actual = _bandit_scoring(rating) - assert actual <= expected + assert actual == expected + +@pytest.mark.parametrize( + "testcase", + [ + ("HH Date: Fri, 19 Jul 2024 15:25:20 +0200 Subject: [PATCH 14/24] type check --- exasol/toolbox/metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index 0c319a0a..b664de52 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -167,7 +167,7 @@ def rating_dict(*values: int) -> Dict[str, int]: return 0.0 index = char(severity) + char(infos["issue_confidence"]) count[index] += 1 - weight: Dict[str, float] = rating_dict(0, 1, 2, 3, 4, 5) + weight: Dict[str, float] = {"LL": 0, "LM": 1, "LH": 2, "ML": 3, "MM": 4, "MH": 5} for k, v in weight.items(): weight[k] = count[k] * round((2 ** 0.20) ** v, 10) score = 0.0 From bed13b05306ad1ea978974a631b6db1802a1d7ae Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 25 Jul 2024 15:06:58 +0200 Subject: [PATCH 15/24] new version of bandit rating and test --- exasol/toolbox/metrics.py | 34 ++++++--------- test/unit/report_test.py | 87 +++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 71 deletions(-) diff --git a/exasol/toolbox/metrics.py b/exasol/toolbox/metrics.py index b664de52..cea643a4 100644 --- a/exasol/toolbox/metrics.py +++ b/exasol/toolbox/metrics.py @@ -71,21 +71,21 @@ def from_score(score: float) -> "Rating": @staticmethod def bandit_rating(score: float) -> "Rating": score = round(score, 3) - if score == 0: + if score <= 0.2: return Rating.F - elif 0 < score <= 2: + elif 0.2 < score <= 1.6: return Rating.E - elif 2 < score <= 4: + elif 1.6 < score <= 3: return Rating.D - elif 4 < score <= 5: + elif 3 < score <= 4.4: return Rating.C - elif 5 < score <= 6: + elif 4.4 < score <= 5.8: return Rating.B - elif 6 < score <= 7: + elif 5.8 < score <= 6: return Rating.A else: raise ValueError( - "Uncategorized score, score should be in the following interval [0,7]." + "Uncategorized score, score should be in the following interval [0,6]." ) @@ -157,26 +157,16 @@ def char(value: str, default: str = "H") -> str: return value[0] return default - def rating_dict(*values: int) -> Dict[str, int]: - return dict(zip(["LL", "LM", "LH", "ML", "MM", "MH"], values)) - - count = rating_dict(0, 0, 0, 0, 0, 0,) + weight = {"LL": 1/18, "LM": 1/15, "LH": 1/12, "ML": 1/9, "MM": 1/6, "MH": 1/3} + exp = 0.0 for infos in ratings: severity = infos["issue_severity"] if severity == "HIGH": return 0.0 index = char(severity) + char(infos["issue_confidence"]) - count[index] += 1 - weight: Dict[str, float] = {"LL": 0, "LM": 1, "LH": 2, "ML": 3, "MM": 4, "MH": 5} - for k, v in weight.items(): - weight[k] = count[k] * round((2 ** 0.20) ** v, 10) - score = 0.0 - quantity = 0.0 - factor = rating_dict(6, 5, 4, 3, 2, 1) - for value in weight: - score += weight[value] * factor[value] - quantity += weight[value] - return 7 if quantity == 0 else score / quantity + exp += weight[index] + return 6 * (2**-exp) + def technical_debt() -> Rating: return Rating.NotAvailable diff --git a/test/unit/report_test.py b/test/unit/report_test.py index 15000a44..42e674e1 100644 --- a/test/unit/report_test.py +++ b/test/unit/report_test.py @@ -1,13 +1,16 @@ from inspect import cleandoc +from typing import ( + Dict, + List, +) import pytest from exasol.toolbox.metrics import ( Rating, - _static_code_analysis, _bandit_scoring, + _static_code_analysis, ) -from typing import List, Dict @pytest.mark.parametrize( @@ -115,53 +118,39 @@ def test_static_code_analysis( @pytest.mark.parametrize( - "severity, confidence, expected", + "lower,compare", [ - ("HIGH", "HIGH", 0), - ("HIGH", "MEDIUM", 0), - ("HIGH", "LOW", 0), - ("MEDIUM", "HIGH", 1), - ("MEDIUM", "MEDIUM", 2), - ("MEDIUM", "LOW", 3), - ("LOW", "HIGH", 4), - ("LOW", "MEDIUM", 5), - ("LOW", "LOW", 6), - ] -) -def test_bandit_scoring(severity, confidence, expected): - rating = [{"issue_severity": severity, "issue_confidence": confidence}] - actual = _bandit_scoring(rating) - assert actual == expected - -@pytest.mark.parametrize( - "testcase", - [ - ("HH Date: Tue, 13 Aug 2024 10:42:40 +0200 Subject: [PATCH 16/24] function split up --- test/unit/report_test.py | 52 ++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/test/unit/report_test.py b/test/unit/report_test.py index 42e674e1..1d9b34ac 100644 --- a/test/unit/report_test.py +++ b/test/unit/report_test.py @@ -117,13 +117,39 @@ def test_static_code_analysis( assert actual == expected +def _level(char): + levels = {"H": "HIGH", "M": "MEDIUM", "L": "LOW"} + return levels[char] + + +def _ratings(cases): + output = [] + for rating in cases: + output.append( + { + "issue_severity": _level(rating[0]), + "issue_confidence": _level(rating[1]), + } + ) + return output + + @pytest.mark.parametrize( - "lower,compare", + "given,expected", [ (["HH", "LL"], 0), (["HM", "LM", "ML"], 0), (["HL", "MH"], 0), ([], 6), + ], +) +def test_bandit_value(given, expected): + assert _bandit_scoring(_ratings(given)) == expected + + +@pytest.mark.parametrize( + "lower,higher", + [ (["HL"], ["MH"]), (["MH"], ["MM"]), (["MM"], ["ML"]), @@ -132,25 +158,5 @@ def test_static_code_analysis( (["MH", "LL"], ["MH"]), ], ) -def test_bandit_order(lower, compare): - def level(char): - levels = {"H": "HIGH", "M": "MEDIUM", "L": "LOW"} - return levels[char] - - def ratings(cases): - output = [] - for rating in cases: - output.append( - { - "issue_severity": level(rating[0]), - "issue_confidence": level(rating[1]), - } - ) - return output - - if isinstance(compare, int): - assert _bandit_scoring(ratings(lower)) == compare - elif isinstance(compare, list): - assert _bandit_scoring(ratings(lower)) < _bandit_scoring(ratings(compare)) - else: - assert False +def test_bandit_order(lower, higher): + assert _bandit_scoring(_ratings(lower)) < _bandit_scoring(_ratings(higher)) From 3da401d8cb0aa84d088af70964a6c8aba2fb5835 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 13 Aug 2024 10:55:52 +0200 Subject: [PATCH 17/24] remove .security.json from git --- .gitignore | 1 + .security.json | 997 ------------------------------------------------- 2 files changed, 1 insertion(+), 997 deletions(-) delete mode 100644 .security.json diff --git a/.gitignore b/.gitignore index e86a9935..0ed5574d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .lint.json .lint.txt +.security.json odbcconfig/odbcinst.ini diff --git a/.security.json b/.security.json deleted file mode 100644 index 8c0980ce..00000000 --- a/.security.json +++ /dev/null @@ -1,997 +0,0 @@ -{ - "errors": [], - "generated_at": "2024-07-11T08:48:31Z", - "metrics": { - "/home/jami/Git/python-toolbox/doc/conf.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 35, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/doc/user_guide/modules/sphinx/multiversion/conf.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 38, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/cli.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 8, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/error.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 2, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/git.py": { - "CONFIDENCE.HIGH": 2, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 2, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 12, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py": { - "CONFIDENCE.HIGH": 3, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 3, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 294, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_documentation.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 39, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_format.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 33, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_lint.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 71, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_metrics.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 53, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_release.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 127, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/_shared.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 52, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/plugin.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 85, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/nox/tasks.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 60, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py": { - "CONFIDENCE.HIGH": 3, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 2, - "SEVERITY.MEDIUM": 1, - "SEVERITY.UNDEFINED": 0, - "loc": 110, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py": { - "CONFIDENCE.HIGH": 2, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 2, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 123, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/github.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 22, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/__main__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 3, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py": { - "CONFIDENCE.HIGH": 6, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 1, - "SEVERITY.LOW": 5, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 139, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py": { - "CONFIDENCE.HIGH": 4, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 2, - "SEVERITY.LOW": 2, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 499, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/sphinx.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 208, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/templates/noxconfig.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 26, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/templates/noxfile.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 3, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/__init__.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 0, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/issue.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 67, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/replace_version.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 24, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py": { - "CONFIDENCE.HIGH": 3, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 3, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 203, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/tbx.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 12, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/template.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 135, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/tools/workflow.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 69, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/exasol/toolbox/version.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 4, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/noxconfig.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 30, - "nosec": 0, - "skipped_tests": 0 - }, - "/home/jami/Git/python-toolbox/noxfile.py": { - "CONFIDENCE.HIGH": 0, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 0, - "SEVERITY.LOW": 0, - "SEVERITY.MEDIUM": 0, - "SEVERITY.UNDEFINED": 0, - "loc": 51, - "nosec": 0, - "skipped_tests": 0 - }, - "_totals": { - "CONFIDENCE.HIGH": 23, - "CONFIDENCE.LOW": 0, - "CONFIDENCE.MEDIUM": 0, - "CONFIDENCE.UNDEFINED": 0, - "SEVERITY.HIGH": 3, - "SEVERITY.LOW": 19, - "SEVERITY.MEDIUM": 1, - "SEVERITY.UNDEFINED": 0, - "loc": 2637, - "nosec": 0, - "skipped_tests": 0 - } - }, - "results": [ - { - "code": "1 import subprocess\n2 from typing import Iterable\n3 \n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 1, - "line_range": [ - 1 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "12 command = [\"git\", \"tag\", \"--sort=committerdate\"]\n13 result = subprocess.run(command, capture_output=True, check=True)\n14 return [tag.strip() for tag in result.stdout.decode(\"utf-8\").splitlines()]\n", - "col_offset": 13, - "end_col_offset": 69, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 13, - "line_range": [ - 13 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "15 from pathlib import Path\n16 from subprocess import run\n17 from tempfile import TemporaryDirectory\n", - "col_offset": 0, - "end_col_offset": 26, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 16, - "line_range": [ - 16 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "106 report = tmp_dir / \"coverage.json\"\n107 run(\n108 [\"coverage\", \"json\", f\"--data-file={file}\", \"-o\", f\"{report}\"],\n109 capture_output=True,\n110 check=True,\n111 )\n112 with open(report, encoding=\"utf-8\") as r:\n", - "col_offset": 8, - "end_col_offset": 9, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Starting a process with a partial executable path", - "line_number": 107, - "line_range": [ - 107, - 108, - 109, - 110, - 111 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b607_start_process_with_partial_path.html", - "test_id": "B607", - "test_name": "start_process_with_partial_path" - }, - { - "code": "106 report = tmp_dir / \"coverage.json\"\n107 run(\n108 [\"coverage\", \"json\", f\"--data-file={file}\", \"-o\", f\"{report}\"],\n109 capture_output=True,\n110 check=True,\n111 )\n112 with open(report, encoding=\"utf-8\") as r:\n", - "col_offset": 8, - "end_col_offset": 9, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/metrics.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 107, - "line_range": [ - 107, - 108, - 109, - 110, - 111 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "1 import subprocess\n2 import sys\n3 from argparse import (\n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 1, - "line_range": [ - 1 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "53 _globals: Dict[str, Any] = {}\n54 exec(file.read(), _locals, _globals)\n55 \n", - "col_offset": 8, - "end_col_offset": 44, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "MEDIUM", - "issue_text": "Use of exec detected.", - "line_number": 54, - "line_range": [ - 54 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b102_exec_used.html", - "test_id": "B102", - "test_name": "exec_used" - }, - { - "code": "68 \n69 result = subprocess.run(\n70 [poetry, \"version\", \"--no-ansi\"], capture_output=True, check=False\n71 )\n72 version = result.stdout.decode().split()[1]\n", - "col_offset": 13, - "end_col_offset": 5, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/pre_commit_hooks/package_version.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 69, - "line_range": [ - 69, - 70, - 71 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "2 \n3 import subprocess\n4 from dataclasses import dataclass\n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 3, - "line_range": [ - 3 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "70 try:\n71 result = subprocess.run(\n72 [poetry, \"version\", \"--no-ansi\", \"--short\"], capture_output=True\n73 )\n74 except subprocess.CalledProcessError as ex:\n", - "col_offset": 21, - "end_col_offset": 13, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/release/__init__.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 71, - "line_range": [ - 71, - 72, - 73 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "5 import re\n6 import subprocess\n7 import tarfile\n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 6, - "line_range": [ - 6 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "30 )\n31 output = subprocess.check_output(cmd, cwd=cwd).decode()\n32 return output.rstrip(\"\\n\")\n", - "col_offset": 13, - "end_col_offset": 50, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 31, - "line_range": [ - 31 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "42 )\n43 output = subprocess.check_output(cmd, cwd=gitroot).decode()\n44 for line in output.splitlines():\n", - "col_offset": 13, - "end_col_offset": 54, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 43, - "line_range": [ - 43 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "135 )\n136 proc = subprocess.run(\n137 cmd,\n138 cwd=gitroot,\n139 stdout=subprocess.DEVNULL,\n140 stderr=subprocess.DEVNULL,\n141 check=False,\n142 )\n143 return proc.returncode == 0\n", - "col_offset": 11, - "end_col_offset": 5, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 136, - "line_range": [ - 136, - 137, - 138, - 139, - 140, - 141, - 142 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "156 )\n157 subprocess.check_call(cmd, cwd=gitroot, stdout=fp)\n158 fp.seek(0)\n", - "col_offset": 8, - "end_col_offset": 58, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 157, - "line_range": [ - 157 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "159 with tarfile.TarFile(fileobj=fp) as tarfp:\n160 tarfp.extractall(dst)\n", - "col_offset": 12, - "end_col_offset": 33, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/git.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 22, - "link": "https://cwe.mitre.org/data/definitions/22.html" - }, - "issue_severity": "HIGH", - "issue_text": "tarfile.extractall used without any validation. Please check and discard dangerous members.", - "line_number": 160, - "line_range": [ - 160 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b202_tarfile_unsafe_members.html", - "test_id": "B202", - "test_name": "tarfile_unsafe_members" - }, - { - "code": "12 import string\n13 import subprocess\n14 import sys\n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 13, - "line_range": [ - 13 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "402 subprocess.check_call(\n403 config.smv_prebuild_command, cwd=current_cwd, shell=True\n404 )\n405 \n406 if config.smv_prebuild_export_pattern != \"\":\n", - "col_offset": 16, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "HIGH", - "issue_text": "subprocess call with shell=True identified, security issue.", - "line_number": 403, - "line_range": [ - 402, - 403, - 404 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b602_subprocess_popen_with_shell_equals_true.html", - "test_id": "B602", - "test_name": "subprocess_popen_with_shell_equals_true" - }, - { - "code": "470 # Run sphinx-build\n471 subprocess.check_call(cmd, cwd=current_cwd, env=env)\n472 \n", - "col_offset": 16, - "end_col_offset": 68, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 471, - "line_range": [ - 471 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "555 subprocess.check_call(\n556 config.smv_postbuild_command, cwd=current_cwd, shell=True\n557 )\n558 if config.smv_postbuild_export_pattern != \"\":\n559 matches = find_matching_files_and_dirs(\n", - "col_offset": 16, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/sphinx/multiversion/main.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "HIGH", - "issue_text": "subprocess call with shell=True identified, security issue.", - "line_number": 556, - "line_range": [ - 555, - 556, - 557 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b602_subprocess_popen_with_shell_equals_true.html", - "test_id": "B602", - "test_name": "subprocess_popen_with_shell_equals_true" - }, - { - "code": "3 import re\n4 import subprocess\n5 import sys\n", - "col_offset": 0, - "end_col_offset": 17, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "Consider possible security implications associated with the subprocess module.", - "line_number": 4, - "line_range": [ - 4 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/blacklists/blacklist_imports.html#b404-import-subprocess", - "test_id": "B404", - "test_name": "blacklist" - }, - { - "code": "68 try:\n69 result = subprocess.run(command, check=True, capture_output=True)\n70 except FileNotFoundError as ex:\n", - "col_offset": 17, - "end_col_offset": 73, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 69, - "line_range": [ - 69 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - }, - { - "code": "142 try:\n143 result = subprocess.run(command, check=True, capture_output=True)\n144 except FileNotFoundError as ex:\n", - "col_offset": 17, - "end_col_offset": 73, - "filename": "/home/jami/Git/python-toolbox/exasol/toolbox/tools/security.py", - "issue_confidence": "HIGH", - "issue_cwe": { - "id": 78, - "link": "https://cwe.mitre.org/data/definitions/78.html" - }, - "issue_severity": "LOW", - "issue_text": "subprocess call - check for execution of untrusted input.", - "line_number": 143, - "line_range": [ - 143 - ], - "more_info": "https://bandit.readthedocs.io/en/1.7.9/plugins/b603_subprocess_without_shell_equals_true.html", - "test_id": "B603", - "test_name": "subprocess_without_shell_equals_true" - } - ] -} \ No newline at end of file From 706e6cfc1a962326f574b7ead6e284624bea0ea7 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 10 Sep 2024 13:24:49 +0200 Subject: [PATCH 18/24] Add security-check to Github jobs --- .github/workflows/checks.yml | 21 +++++++++++++++++++++ exasol/toolbox/nox/_lint.py | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 6f4a71ee..3b0440a5 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -89,6 +89,27 @@ jobs: - name: Run type-check run: poetry run nox -s type-check + security-check-job: + name: Security Checking (Python-${{ matrix.python-version }}) + needs: [ version-check-job ] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11" ] + + steps: + - name: SCM Checkout + uses: actions/checkout@v4 + + - name: Setup Python & Poetry Environment + uses: ./.github/actions/python-environment + with: + python-version: ${{ matrix.python-version }} + + - name: Run security-check + run: poetry run nox -s security-check + tests-job: name: Tests (Python-${{ matrix.python-version }}, Exasol-${{ matrix.exasol-version}}) needs: [ build-documentation-job, lint-job, type-check-job ] diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index 72f35eae..73bf7030 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -78,7 +78,7 @@ def type_check(session: Session) -> None: _type_check(session, py_files) -@nox.session(name="security", python=False) +@nox.session(name="security-check", python=False) def security_lint(session: Session) -> None: """runs the security linter bandit on the project without the test files""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] From b28e378ca10d7de838a3fb47529cffdd7733e9ec Mon Sep 17 00:00:00 2001 From: Christoph Kuhnke Date: Mon, 23 Sep 2024 13:54:29 +0200 Subject: [PATCH 19/24] Update exasol/toolbox/nox/_lint.py Co-authored-by: Nicola Coretti --- exasol/toolbox/nox/_lint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index 73bf7030..72f35eae 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -78,7 +78,7 @@ def type_check(session: Session) -> None: _type_check(session, py_files) -@nox.session(name="security-check", python=False) +@nox.session(name="security", python=False) def security_lint(session: Session) -> None: """runs the security linter bandit on the project without the test files""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] From ad7a8bde598a2a371708da72c826ebe2cfcc2241 Mon Sep 17 00:00:00 2001 From: ckunki Date: Mon, 23 Sep 2024 13:57:45 +0200 Subject: [PATCH 20/24] Renamed security check to "security" in GitHub workflow, too --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3b0440a5..5f66e2e7 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -108,7 +108,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Run security-check - run: poetry run nox -s security-check + run: poetry run nox -s security tests-job: name: Tests (Python-${{ matrix.python-version }}, Exasol-${{ matrix.exasol-version}}) From d2867bbbffe3e64adbfb9025a056a7adb1be9151 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 24 Sep 2024 15:47:26 +0200 Subject: [PATCH 21/24] fix github workflow security-job --- .github/workflows/checks.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 27675a21..df6b1770 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -89,7 +89,7 @@ jobs: - name: Run type-check run: poetry run nox -s type-check - security-check-job: + security-job: name: Security Checking (Python-${{ matrix.python-version }}) needs: [ version-check-job ] runs-on: ubuntu-latest @@ -107,9 +107,16 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Run security-check + - name: Run security run: poetry run nox -s security + - name: Upload Artifacts + uses: actions/upload-artifact@v4.4.0 + with: + name: lint-python${{ matrix.python-version }} + path: .security.json + include-hidden-files: true + tests-job: name: Tests (Python-${{ matrix.python-version }}, Exasol-${{ matrix.exasol-version}}) needs: [ build-documentation-job, lint-job, type-check-job ] From 8337ad27fca92a4555375c2c2a343b60b0b742e1 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 24 Sep 2024 15:49:53 +0200 Subject: [PATCH 22/24] fix github workflow security-job --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index df6b1770..754e26f0 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -113,7 +113,7 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4.4.0 with: - name: lint-python${{ matrix.python-version }} + name: security-python${{ matrix.python-version }} path: .security.json include-hidden-files: true From 26b132a54a2dcb0ddbb9fa36a21d25952b1da890 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 24 Sep 2024 15:57:56 +0200 Subject: [PATCH 23/24] add security file to github workflow report --- .github/workflows/report.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/report.yml b/.github/workflows/report.yml index 451ffc3e..483bfbe9 100644 --- a/.github/workflows/report.yml +++ b/.github/workflows/report.yml @@ -33,6 +33,7 @@ jobs: run: | cp coverage-python3.9/.coverage ../ cp lint-python3.9/.lint.txt ../ + cp security-python3.9/.security.json ../ - name: Generate Report run: poetry run nox -s report -- -- --format json | tee metrics.json From 5afd5358274bff27f4618af96528a3bb102d2736 Mon Sep 17 00:00:00 2001 From: Nicola Coretti Date: Wed, 25 Sep 2024 09:03:14 +0200 Subject: [PATCH 24/24] Update exasol/toolbox/nox/_lint.py --- exasol/toolbox/nox/_lint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exasol/toolbox/nox/_lint.py b/exasol/toolbox/nox/_lint.py index 72f35eae..bc474e7d 100644 --- a/exasol/toolbox/nox/_lint.py +++ b/exasol/toolbox/nox/_lint.py @@ -80,6 +80,6 @@ def type_check(session: Session) -> None: @nox.session(name="security", python=False) def security_lint(session: Session) -> None: - """runs the security linter bandit on the project without the test files""" + """Runs the security linter on the project""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] _security_lint(session, list(filter(lambda file: "test" not in file, py_files)))