From da6e2415983cc0eadacfa49eb43161a6c2be6d36 Mon Sep 17 00:00:00 2001 From: Emma <47212872+EmmaVinen@users.noreply.github.com> Date: Wed, 11 Sep 2024 11:26:53 +0100 Subject: [PATCH] feat(general): allow tool name field to be customised using cli arguments (#6692) * added --tool-name cli parameter to allow customised tools in sarif file outputs * remove test line * updating docs * responding to pull request review * modifying test logic --------- Co-authored-by: Taylor <28880387+tsmithv11@users.noreply.github.com> --- checkov/common/runners/runner_registry.py | 2 +- checkov/common/util/banner.py | 3 ++- checkov/common/util/ext_argument_parser.py | 6 ++++++ checkov/main.py | 7 +++++-- docs/2.Basics/CLI Command Reference.md | 2 ++ docs/8.Outputs/SARIF.md | 3 +++ tests/config/TestCLIArgs.py | 11 +++++++++++ tests/config/example_TestConfigFile/config.yml | 1 - 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/checkov/common/runners/runner_registry.py b/checkov/common/runners/runner_registry.py index 69685c005ce..5cb7c1995f0 100644 --- a/checkov/common/runners/runner_registry.py +++ b/checkov/common/runners/runner_registry.py @@ -42,7 +42,7 @@ from checkov.common.sast.consts import CDKLanguages from checkov.common.typing import _ExitCodeThresholds, _BaseRunner, _ScaExitCodeThresholds, LibraryGraph from checkov.common.util import data_structures_utils -from checkov.common.util.banner import tool as tool_name +from checkov.common.util.banner import default_tool as tool_name from checkov.common.util.consts import S3_UPLOAD_DETAILS_MESSAGE from checkov.common.util.data_structures_utils import pickle_deepcopy from checkov.common.util.json_utils import CustomJSONEncoder diff --git a/checkov/common/util/banner.py b/checkov/common/util/banner.py index 0a4c82a3556..5e6bf8e472b 100644 --- a/checkov/common/util/banner.py +++ b/checkov/common/util/banner.py @@ -4,7 +4,8 @@ from checkov.version import version from checkov.common.version_manager import check_for_update -tool = "Checkov" +default_tool = "Checkov" + banner = r""" _ _ ___| |__ ___ ___| | _______ __ diff --git a/checkov/common/util/ext_argument_parser.py b/checkov/common/util/ext_argument_parser.py index 7abe5f4ff62..907380bfb06 100644 --- a/checkov/common/util/ext_argument_parser.py +++ b/checkov/common/util/ext_argument_parser.py @@ -557,3 +557,9 @@ def add_parser_args(self) -> None: "resource code to OpenAI to request remediation guidance. This will use your OpenAI credits. " "Set your number of findings that will receive enhanced guidelines using CKV_OPENAI_MAX_FINDINGS", ) + self.add( + "--custom-tool-name", + default="Checkov", + help="Add a tool name if you want your output to be tagged with a specific tool name," + "this is useful when integrating with other tools such as uploading SARIF files to github code scanning" + ) diff --git a/checkov/main.py b/checkov/main.py index b2c5a00e047..797e9ca1110 100755 --- a/checkov/main.py +++ b/checkov/main.py @@ -53,7 +53,7 @@ from checkov.common.sast.consts import SastLanguages from checkov.common.typing import LibraryGraph from checkov.common.util import prompt -from checkov.common.util.banner import banner as checkov_banner, tool as checkov_tool +from checkov.common.util.banner import banner as checkov_banner, default_tool as default_tool from checkov.common.util.config_utils import get_default_config_paths from checkov.common.util.ext_argument_parser import ExtArgumentParser, flatten_csv from checkov.common.util.runner_dependency_handler import RunnerDependencyHandler @@ -238,7 +238,7 @@ def normalize_framework_arg(self, raw_framework_arg: List[List[str]], handle_all logging.debug('No framework specified; setting to none') return [] - def run(self, banner: str = checkov_banner, tool: str = checkov_tool, source_type: SourceType | None = None) -> int | None: + def run(self, banner: str = checkov_banner, tool: str = default_tool, source_type: SourceType | None = None) -> int | None: self.run_metadata = { "checkov_version": version, "python_executable": sys.executable, @@ -251,6 +251,9 @@ def run(self, banner: str = checkov_banner, tool: str = checkov_tool, source_typ } logger.debug(f'Run metadata: {json.dumps(self.run_metadata, indent=2)}') + + if self.config.custom_tool_name: # if the user specifies a tool name, use that + tool = self.config.custom_tool_name try: if self.config.add_check: resp = prompt.Prompt() diff --git a/docs/2.Basics/CLI Command Reference.md b/docs/2.Basics/CLI Command Reference.md index 728abeb48e0..a7d110137da 100644 --- a/docs/2.Basics/CLI Command Reference.md +++ b/docs/2.Basics/CLI Command Reference.md @@ -62,4 +62,6 @@ nav_order: 2 | `--block-list-secret-scan CKV_SECRETS_SCAN_BLOCK_LIST` | List of files to filter out in the secret scanner | | `--support` | Enable debug logs and upload the logs to the server. Requires a Prisma Cloud API key. | | `--openai-api-key` | Add an OpenAI API key to enhance finding guidelines by sending violated policies and resource code to OpenAI to request remediation guidance. This will use your OpenAI credits. Set your number of findings that will receive enhanced guidelines using CKV_OPENAI_MAX_FINDINGS | +| `--custom-tool-name` | Add a custom tool name to change the tool name field, this is especially useful for outputting results in SARIF format for upload to Github Code Scanning | + | env variable: `RENDER_EDGES_DUPLICATE_ITER_COUNT` | Set the threshold to break out of calculating duplicate edges in the graph. This can be determined if you see `Reached too many edge duplications...` in the Checkov logs. Default: `4`. | diff --git a/docs/8.Outputs/SARIF.md b/docs/8.Outputs/SARIF.md index 996556589c8..651c372f186 100644 --- a/docs/8.Outputs/SARIF.md +++ b/docs/8.Outputs/SARIF.md @@ -125,6 +125,9 @@ The output can be created via the output flag ```shell checkov -d . -o sarif ``` +The tool.driver.name field can be customised using the --custom-tool-name flag + + ## Structure diff --git a/tests/config/TestCLIArgs.py b/tests/config/TestCLIArgs.py index 6d74775353a..28d9ace215d 100644 --- a/tests/config/TestCLIArgs.py +++ b/tests/config/TestCLIArgs.py @@ -112,6 +112,17 @@ def test_combine_framework_and_skip(self): self.assertEqual(ckv.config.framework, ['all']) self.assertEqual(ckv.config.skip_framework, ['arm']) + def test_custom_tool_name(self): + # try using a non-standard tool name + argv = ["--custom-tool-name", "non_standard_name"] + ckv = Checkov(argv=argv) + self.assertEqual(ckv.config.custom_tool_name, 'non_standard_name') + + # what about a standard tool name? + argv = [] + ckv = Checkov(argv=argv) + self.assertEqual(ckv.config.custom_tool_name, 'Checkov') + if __name__ == '__main__': unittest.main() diff --git a/tests/config/example_TestConfigFile/config.yml b/tests/config/example_TestConfigFile/config.yml index bedf40c1ea0..3067ecab6af 100644 --- a/tests/config/example_TestConfigFile/config.yml +++ b/tests/config/example_TestConfigFile/config.yml @@ -23,4 +23,3 @@ soft-fail: True branch: "master" check: - "CKV_DOCKER_1" -