Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add security linter bandit to nox #208

Merged
merged 30 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8832c69
add security linter bandit to nox
Jannis-Mittenzwei Jun 20, 2024
8b307b9
bandit starting problem solved
Jannis-Mittenzwei Jun 21, 2024
5afccc2
change bandit options
Jannis-Mittenzwei Jun 26, 2024
bb62b2d
bandit report
Jannis-Mittenzwei Jul 3, 2024
8a01c78
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
Jannis-Mittenzwei Jul 4, 2024
4ad9ac1
add security scoring
Jannis-Mittenzwei Jul 5, 2024
0f0dfeb
new bandit scoring + bandit rating
Jannis-Mittenzwei Jul 9, 2024
fdd11fa
typing List
Jannis-Mittenzwei Jul 9, 2024
75fa656
types corrected
Jannis-Mittenzwei Jul 9, 2024
283f368
added a test for bandit_scoring
Jannis-Mittenzwei Jul 11, 2024
ce0b1d0
run bandit test
Jannis-Mittenzwei Jul 11, 2024
9a9dff1
Update depdendency constraints (#214)
Nicoretti Jul 5, 2024
ad40034
add security linter bandit to nox
Jannis-Mittenzwei Jun 20, 2024
7d4c1eb
problems solved
Jannis-Mittenzwei Jul 16, 2024
700bcf5
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
Jannis-Mittenzwei Jul 18, 2024
cc06d80
type check
Jannis-Mittenzwei Jul 19, 2024
bed13b0
new version of bandit rating and test
Jannis-Mittenzwei Jul 25, 2024
f19d66a
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
Jannis-Mittenzwei Aug 13, 2024
4d9516d
function split up
Jannis-Mittenzwei Aug 13, 2024
3da401d
remove .security.json from git
Jannis-Mittenzwei Aug 13, 2024
d4cfe08
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
Jannis-Mittenzwei Sep 10, 2024
706e6cf
Add security-check to Github jobs
Jannis-Mittenzwei Sep 10, 2024
acb07bd
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
ckunki Sep 23, 2024
b28e378
Update exasol/toolbox/nox/_lint.py
ckunki Sep 23, 2024
ad7a8bd
Renamed security check to "security" in GitHub workflow, too
ckunki Sep 23, 2024
24c4900
Merge branch 'main' into feature#74-add-security-linter-to-the-toolbox
Jannis-Mittenzwei Sep 24, 2024
d2867bb
fix github workflow security-job
Jannis-Mittenzwei Sep 24, 2024
8337ad2
fix github workflow security-job
Jannis-Mittenzwei Sep 24, 2024
26b132a
add security file to github workflow report
Jannis-Mittenzwei Sep 24, 2024
5afd535
Update exasol/toolbox/nox/_lint.py
Nicoretti Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.lint.json
.lint.txt
.security.json

odbcconfig/odbcinst.ini

Expand Down
47 changes: 44 additions & 3 deletions exasol/toolbox/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Any,
Callable,
Dict,
List,
Optional,
Union,
)
Expand Down Expand Up @@ -67,6 +68,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.2:
return Rating.F
elif 0.2 < score <= 1.6:
return Rating.E
elif 1.6 < score <= 3:
return Rating.D
elif 3 < score <= 4.4:
return Rating.C
elif 4.4 < score <= 5.8:
return Rating.B
elif 5.8 < score <= 6:
return Rating.A
else:
raise ValueError(
"Uncategorized score, score should be in the following interval [0,6]."
)


@dataclass(frozen=True)
class Report:
Expand Down Expand Up @@ -124,8 +145,27 @@ def reliability() -> Rating:
return Rating.NotAvailable


def security() -> Rating:
return Rating.NotAvailable
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"]))


def _bandit_scoring(ratings: List[Dict[str, Any]]) -> float:
def char(value: str, default: str = "H") -> str:
if value in ["HIGH", "MEDIUM", "LOW"]:
return value[0]
return default

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"])
exp += weight[index]
return 6 * (2**-exp)


def technical_debt() -> Rating:
Expand All @@ -137,14 +177,15 @@ 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,
date=date if date is not None else datetime.datetime.now(),
coverage=total_coverage(coverage_report),
maintainability=maintainability(pylint_report),
reliability=reliability(),
security=security(),
security=security(bandit_report),
technical_debt=technical_debt(),
)

Expand Down
34 changes: 34 additions & 0 deletions exasol/toolbox/nox/_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ def _type_check(session: Session, files: Iterable[str]) -> None:
)


def _security_lint(session: Session, files: Iterable[str]) -> None:
session.run(
"poetry",
"run",
"bandit",
"--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)
def lint(session: Session) -> None:
"""Runs the linter on the project"""
Expand All @@ -49,3 +76,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-check", python=False)
ckunki marked this conversation as resolved.
Show resolved Hide resolved
def security_lint(session: Session) -> None:
"""runs the security linter bandit on the project without the test files"""
Nicoretti marked this conversation as resolved.
Show resolved Hide resolved
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)))
3 changes: 2 additions & 1 deletion exasol/toolbox/nox/_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ def report(session: Session) -> None:
required_files = (
PROJECT_CONFIG.root / ".coverage",
PROJECT_CONFIG.root / ".lint.txt",
PROJECT_CONFIG.root / ".security.json",
Jannis-Mittenzwei marked this conversation as resolved.
Show resolved Hide resolved
)
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)
Expand Down
Loading
Loading