Skip to content

Commit

Permalink
Restructure security module
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicoretti committed Oct 24, 2023
1 parent f4693b0 commit a0832d7
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 93 deletions.
159 changes: 87 additions & 72 deletions exasol/toolbox/tools/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,40 @@
stdout = Console()
stderr = Console(stderr=True)

ISSUE_CLI = typer.Typer()

from dataclasses import (
asdict,
dataclass,
)


# Note:
# In the long term we may want to adapt the official CVE json schema,
# support for this could be generated using pydantic.
# See here: https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/CVE_JSON_5.0_schema.json
@dataclass(frozen=True)
class Issue:
# Note: Add support additional (custom) information e.g. dependency tree etc.
cve: str
cwe: str
description: str
coordinates: str
references: tuple


def _issues(input) -> Generator[Issue, None, None]:
issues = input.read()
issues = (line for line in issues.split("\n"))
issues = (json.loads(raw) for raw in issues)
issues = (Issue(**obj) for obj in issues)
yield from issues


def _issues_as_json_str(issues):
for issue in issues:
issue = asdict(issue) # type: ignore
yield json.dumps(issue)


def gh_security_issues() -> Generator[Tuple[str, str], None, None]:
"""
Yields issue-id, cve-id pairs for all (closed, open) issues associated with CVEs
Expand Down Expand Up @@ -67,34 +93,6 @@ def gh_security_issues() -> Generator[Tuple[str, str], None, None]:
return issues


# Note:
# In the long term we may want to adapt the official CVE json schema,
# support for this could be generated using pydantic.
# See here: https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/CVE_JSON_5.0_schema.json
@dataclass(frozen=True)
class Issue:
# Note: Add support additional (custom) information e.g. dependency tree etc.
cve: str
cwe: str
description: str
coordinates: str
references: tuple


def _issues(input) -> Generator[Issue, None, None]:
issues = input.read()
issues = (line for line in issues.split("\n"))
issues = (json.loads(raw) for raw in issues)
issues = (Issue(**obj) for obj in issues)
yield from issues


def _issues_as_json_str(issues):
for issue in issues:
issue = asdict(issue) # type: ignore
yield json.dumps(issue)


def from_maven(report: str) -> Iterable[Issue]:
# Note: Consider adding warnings if there is the same cve with multiple coordinates
report = json.loads(report)
Expand All @@ -111,9 +109,64 @@ def from_maven(report: str) -> Iterable[Issue]:
)


def security_issue_title(issue: Issue) -> str:
return f"🔐 {issue.cve}: {issue.coordinates}"


def security_issue_body(issue: Issue) -> str:
def as_markdown_listing(elements: Iterable[str]):
return "\n".join(f"- {element}" for element in elements)

body = cleandoc(
"""
## Summary
{description}
CVE: {cve}
CWE: {cwe}
## References
{references}
"""
)
return body.format(
cve=issue.cve,
cwe=issue.cwe,
description=issue.description,
references=as_markdown_listing(issue.references),
)


def create_security_issue(issue: Issue) -> Tuple[str, str]:
command = [
"gh",
"issue",
"create",
"--label",
"security",
"--title",
security_issue_title(issue),
"--body",
security_issue_body(issue),
]
try:
result = subprocess.run(command, check=True)
except:
raise

stderr = result.stderr.decode("utf-8")
stdout = result.stdout.decode("utf-8")
return stderr, stdout


CLI = typer.Typer()
ISSUE_CLI = typer.Typer()
CLI.add_typer(ISSUE_CLI, name="issue")


@ISSUE_CLI.command(name="convert")
def convert(
format: str = typer.Argument(..., help="input format to be converted."),
format: str = typer.Argument(..., help="input format to be converted."),
) -> None:
if format == "maven":
issues = from_maven(sys.stdin.read())
Expand All @@ -126,7 +179,7 @@ def convert(

@ISSUE_CLI.command(name="filter")
def filter(
type: str = typer.Argument(..., help="filter type to apply"),
type: str = typer.Argument(..., help="filter type to apply"),
) -> None:
if type != "github":
stderr.print(
Expand All @@ -146,47 +199,9 @@ def filter(

@ISSUE_CLI.command(name="create")
def create() -> None:
for line in sys.stdin:
stdout.print(line, end="")

title = "🔐 {cve}: {coordinates}"
for issue in _issues(sys.stdin):
create_security_issue(issue)

body = cleandoc(
"""
## Summary
{description}
CVE: {cve}
CWE: {cwe}
## References
{references}
"""
)
body = "another test"
command = [
"gh",
"issue",
"create",
"--label",
"security",
"--title",
title.format(cve="CVE-TEST", coordinates="some-package"),
"--body",
body.format(
cve="CVE-TEST",
cwe="CWE-TEST",
description="Some detailed description",
references="\n".join(f"- {ref}" for ref in ''),
),
]

result = subprocess.run(command, check=True)
print(result)


CLI = typer.Typer()
CLI.add_typer(ISSUE_CLI, name='issuet s')

if __name__ == "__main__":
CLI()
42 changes: 21 additions & 21 deletions test/unit/security_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ def test_convert_maven_input(maven_report):
cve="CVE-2023-39410",
cwe="CWE-502",
description="When deserializing untrusted or corrupted data, it is "
"possible for a reader to consume memory beyond the allowed "
"constraints and thus lead to out of memory on the system.\n"
"\n"
"This issue affects Java applications using Apache Avro "
"Java SDK up to and including 1.11.2. Users should update "
"to apache-avro version 1.11.3 which addresses this issue.\n"
"\n",
"possible for a reader to consume memory beyond the allowed "
"constraints and thus lead to out of memory on the system.\n"
"\n"
"This issue affects Java applications using Apache Avro "
"Java SDK up to and including 1.11.2. Users should update "
"to apache-avro version 1.11.3 which addresses this issue.\n"
"\n",
coordinates="pkg:maven/org.apache.avro/[email protected]",
references=(
"https://ossindex.sonatype.org/vulnerability/CVE-2023-39410?component-type=maven&component-name=org.apache.avro%2Favro&utm_source=ossindex-client&utm_medium=integration&utm_content=1.8.1",
Expand All @@ -174,20 +174,20 @@ def test_convert_maven_input(maven_report):
cve="CVE-2020-36641",
cwe="CWE-611",
description="A vulnerability classified as problematic was found in "
"gturri aXMLRPC up to 1.12.0. This vulnerability affects "
"the function ResponseParser of the file "
"src/main/java/de/timroes/axmlrpc/ResponseParser.java. The "
"manipulation leads to xml external entity reference. "
"Upgrading to version 1.12.1 is able to address this issue. "
"The patch is identified as "
"ad6615b3ec41353e614f6ea5fdd5b046442a832b. It is "
"recommended to upgrade the affected component. VDB-217450 "
"is the identifier assigned to this vulnerability.\n"
"\n"
"Sonatype's research suggests that this CVE's details "
"differ from those defined at NVD. See "
"https://ossindex.sonatype.org/vulnerability/CVE-2020-36641 "
"for details",
"gturri aXMLRPC up to 1.12.0. This vulnerability affects "
"the function ResponseParser of the file "
"src/main/java/de/timroes/axmlrpc/ResponseParser.java. The "
"manipulation leads to xml external entity reference. "
"Upgrading to version 1.12.1 is able to address this issue. "
"The patch is identified as "
"ad6615b3ec41353e614f6ea5fdd5b046442a832b. It is "
"recommended to upgrade the affected component. VDB-217450 "
"is the identifier assigned to this vulnerability.\n"
"\n"
"Sonatype's research suggests that this CVE's details "
"differ from those defined at NVD. See "
"https://ossindex.sonatype.org/vulnerability/CVE-2020-36641 "
"for details",
coordinates="pkg:maven/fr.turri/[email protected]",
references=(
"https://ossindex.sonatype.org/vulnerability/CVE-2020-36641?component-type=maven&component-name=fr.turri%2FaXMLRPC&utm_source=ossindex-client&utm_medium=integration&utm_content=1.8.1",
Expand Down

0 comments on commit a0832d7

Please sign in to comment.