From 0dfe31a008e7db21fa62f05fe600c62759561a6b Mon Sep 17 00:00:00 2001 From: swatipersistent <99341045+swatipersistent@users.noreply.github.com> Date: Wed, 17 May 2023 04:14:55 -0700 Subject: [PATCH] Integration april 23 (#124) * Made the changes done in jackson-fix branch for fixing high vulnerabilities in CLI plugin * Incremented the version * Implemented Post Scan Action * Removed local changes to refer own cx-client-common version. The cx-client-common version also need to be updated with correct version * Update pom.xml Updated cx-config-provider version - 1.0.14 * Updated parameter name * Solved Sca Scantimeout error and removed the compulsory Sca Resolver additional parameter * Updated code for sca report generation * Added code for asynchronous mode and exploitable path params * Updated if condition for Sca alone exploitable path * Updated client-common versions * Updated CLI Version * Updated Scalocation path for sca resolver additional params * made sca report format as mandatory * Getting " --cxserver, --cxuser, --cxpassword, --cxprojectname" option value, if absent in sca resolver additional param in SAST+SCA scan * Updated CLI version * Updated error message for sca report path. * Resolved sast+sca scan error while sca scan with sca resolver * Updated cxprojectid in scaresolver params * Updated CLI version --------- Co-authored-by: Subhadra.Sahoo@checkmarx.com Co-authored-by: RahulPiddeCheckmarx Co-authored-by: Nidhi Jaiswal --- pom.xml | 28 ++++-- .../com/cx/plugin/cli/CxConsoleLauncher.java | 5 +- .../plugin/cli/constants/ArgDescriptions.java | 3 + .../com/cx/plugin/cli/constants/Command.java | 3 + .../cx/plugin/cli/constants/Parameters.java | 2 + .../cx/plugin/cli/utils/CxConfigHelper.java | 93 ++++++++++++++++++- 6 files changed, 119 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 3bf939a..d848d0c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.cx.plugin CxConsolePlugin - 1.1.21 + 1.1.26 jar @@ -24,6 +24,8 @@ libs-snapshot ~/.m2 + + @@ -132,7 +134,7 @@ com.checkmarx cx-client-common - 2022.4.4 + 2023.2.5 @@ -208,7 +210,7 @@ org.json json - 20220924 + 20230227 com.google.guava @@ -241,7 +243,17 @@ com.fasterxml.jackson.core jackson-databind - 2.14.0 + 2.15.0-rc1 + + + com.fasterxml.jackson.core + jackson-core + 2.15.0-rc1 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.15.0-rc1 org.springframework @@ -277,11 +289,7 @@ netty-codec 4.1.86.Final - - org.yaml - snakeyaml - 1.33 - + org.jsoup jsoup @@ -318,7 +326,7 @@ com.checkmarx cx-config-provider - 1.0.13 + 1.0.14 commons-io diff --git a/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java b/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java index 344d4d6..c0a1544 100644 --- a/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java +++ b/src/main/java/com/cx/plugin/cli/CxConsoleLauncher.java @@ -23,6 +23,7 @@ import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.slf4j.Log4jLoggerFactory; +import org.awaitility.core.ConditionTimeoutException; import javax.naming.ConfigurationException; import java.io.File; @@ -86,8 +87,7 @@ public static void main(String[] args) { } catch (CxClientException | IOException | InterruptedException e) { log.error("CLI process terminated, error: " + e.getMessage()); exitCode = ErrorParsingHelper.parseError(e.getMessage()); - } - + } System.exit(exitCode); } @@ -200,6 +200,7 @@ private static int execute(Command command, CommandLine commandLine) } } else { getScanResultExceptionIfExists(results); + log.info("Scan is Running in Asynchronous mode. Not waiting for scan to finish."); } return exitCode; diff --git a/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java b/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java index 9ccc43e..dc79787 100644 --- a/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java +++ b/src/main/java/com/cx/plugin/cli/constants/ArgDescriptions.java @@ -84,6 +84,7 @@ private ArgDescriptions() { static final String XML_REPORT = "Name or path to results report, by type. Optional. Not supported in AsyncScan mode."; static final String CSV_REPORT = "Name or path to results report, by type. Optional. Not supported in AsyncScan mode."; static final String RTF_REPORT = "Name or path to results report, by type. Optional. Not supported in AsyncScan mode."; + static final String SCA_REPORT_PATH = "Path to SCA results report, by type. Optional. Not supported in AsyncScan mode."; static final String IS_INCREMENTAL = "Run incremental scan instead of a full scan. Scans only new and modified files, relative to project's last scan(-Incremental will disable any -ForceScan setting). Optional."; static final String IS_FORCE_SCAN = "Force scan on source code, which has not been changed since the last scan of the same project (not compatible with -Incremental option). Optional."; static final String IS_PRIVATE = "Scan will not be visible to other users. Optional"; @@ -154,6 +155,8 @@ private ArgDescriptions() { static final String ENABLE_SAST_BRANCHING = "Enable to create child project"; static final String MASTER_BRANCH_PROJ_NAME = "Master branch project name"; + static final String POST_SCAN_ACTION = "Post Scan Action name that is to be performed automatically after a scan."; + static final String PERIODIC_FULL_SCAN = "Run a full scan after X incremental scans . Scans all files, (-Incremental should be enable). Optional."; } diff --git a/src/main/java/com/cx/plugin/cli/constants/Command.java b/src/main/java/com/cx/plugin/cli/constants/Command.java index b04925d..837e97b 100644 --- a/src/main/java/com/cx/plugin/cli/constants/Command.java +++ b/src/main/java/com/cx/plugin/cli/constants/Command.java @@ -126,6 +126,7 @@ public static Options getOptions() { options.addOption(GENERATE_SCA_REPORT, false, ArgDescriptions.GENERATE_SCA_REPORT); options.addOption(SCA_REPORT_FORMAT, true, ArgDescriptions.SCA_REPORT_FORMAT); + options.addOption(SCA_REPORT_PATH, true, ArgDescriptions.SCA_REPORT_PATH); options.addOption(IS_INCREMENTAL, false, ArgDescriptions.IS_INCREMENTAL); options.addOption(IS_FORCE_SCAN, false, ArgDescriptions.IS_FORCE_SCAN); @@ -179,6 +180,8 @@ public static Options getOptions() { options.addOption(ENABLE_SAST_BRANCHING, false, ArgDescriptions.ENABLE_SAST_BRANCHING); options.addOption(MASTER_BRANCH_PROJ_NAME, true, ArgDescriptions.MASTER_BRANCH_PROJ_NAME); + + options.addOption(POST_SCAN_ACTION, true, ArgDescriptions.POST_SCAN_ACTION); options.addOption(PERIODIC_FULL_SCAN, true, ArgDescriptions.PERIODIC_FULL_SCAN); diff --git a/src/main/java/com/cx/plugin/cli/constants/Parameters.java b/src/main/java/com/cx/plugin/cli/constants/Parameters.java index f4d5c13..ad74ab2 100644 --- a/src/main/java/com/cx/plugin/cli/constants/Parameters.java +++ b/src/main/java/com/cx/plugin/cli/constants/Parameters.java @@ -62,6 +62,7 @@ private Parameters() { public static final String GENERATE_SCA_REPORT = "generateScaReport"; public static final String SCA_REPORT_FORMAT = "scareportformat"; + public static final String SCA_REPORT_PATH = "scareportpath"; public static final String RTF_REPORT = "reportrtf"; public static final String IS_INCREMENTAL = "incremental"; @@ -117,6 +118,7 @@ private Parameters() { public static final String ENABLE_SAST_BRANCHING = "enablesastbranching"; public static final String MASTER_BRANCH_PROJ_NAME = "masterbranchprojname"; + public static final String POST_SCAN_ACTION = "postscanaction"; public static final String PERIODIC_FULL_SCAN = "periodicfullscan"; diff --git a/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java b/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java index 30c3645..be20eae 100644 --- a/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java +++ b/src/main/java/com/cx/plugin/cli/utils/CxConfigHelper.java @@ -161,7 +161,11 @@ public CxScanConfig resolveConfiguration(Command command, CommandLine cmd) throw if (cmd.hasOption(SCA_TIMEOUT)) { scanConfig.setSCAScanTimeoutInMinutes(Integer.valueOf(cmd.getOptionValue(SCA_TIMEOUT))); } - } else { + } + else { + if(cmd.hasOption(SCA_ENABLED) && cmd.hasOption(SCA_TIMEOUT)) { + scanConfig.setSCAScanTimeoutInMinutes(Integer.valueOf(cmd.getOptionValue(SCA_TIMEOUT))); + } scanConfig.setProjectName(extractProjectName(cmd.getOptionValue(FULL_PROJECT_PATH), false)); scanConfig.setTeamPath(extractTeamPath(cmd.getOptionValue(FULL_PROJECT_PATH), false)); } @@ -175,12 +179,23 @@ public CxScanConfig resolveConfiguration(Command command, CommandLine cmd) throw scanConfig.setSastFilterPattern(sastFilterPattern); scanConfig.setScanComment(cmd.getOptionValue(SCAN_COMMENT)); setScanReports(scanConfig); + String reportPath = getReportPath(SCA_REPORT_PATH); + if(reportPath != null && !reportPath.isEmpty()) { + File reportDir = new File(reportPath); + scanConfig.setReportsDir(reportDir); + } scanConfig.setGenerateScaReport(cmd.hasOption(GENERATE_SCA_REPORT)); scanConfig.setScaReportFormat(cmd.getOptionValue(SCA_REPORT_FORMAT)); - if(scanConfig.isGenerateScaReport()) + if(scanConfig.isGenerateScaReport()) { throwForInvalidScaReportFormat(scanConfig.getScaReportFormat()); + if (!cmd.hasOption(SCA_REPORT_PATH)) { + throw new CLIParsingException("scareportpath command line option must be specified."); + } + } scanConfig.setIncremental(cmd.hasOption(IS_INCREMENTAL)); + String postScanAction = cmd.getOptionValue(POST_SCAN_ACTION); + scanConfig.setPostScanName(postScanAction); scanConfig.setForceScan(cmd.hasOption(IS_FORCE_SCAN)); scanConfig.setEnableSASTBranching(cmd.hasOption(ENABLE_SAST_BRANCHING)); if (cmd.hasOption(ENABLE_SAST_BRANCHING)) { @@ -672,6 +687,8 @@ private void setScaSpecificConfig(CxScanConfig scanConfig) throws CLIParsingExce sca.setEnableScaResolver(true); String pathToResolver = getRequiredParam(commandLine, PATH_TO_RESOLVER, null); String additionalParams = getRequiredParam(commandLine, SCA_RESOLVER_ADD_PARAMETERS, null); + additionalParams = checkMissingMandatoryAdditionalParams(commandLine, additionalParams); + log.debug("SCA Resolver Additional Parameters: " + additionalParams); validateSCAResolverParams(); sca.setPathToScaResolver(pathToResolver); sca.setScaResolverAddParameters(additionalParams); @@ -717,7 +734,16 @@ private void configureScaWithSastDetails(AstScaConfig sca) throws CLIParsingExce //SCA alone scan if ((!commandLine.hasOption(SCA_ENABLED))) { - if (exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { + if (commandLine.hasOption(SAST_PROJECT_NAME) || commandLine.hasOption(SAST_PROJECT_ID)) { + if (exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { + serverURL = StringUtils.isEmpty(serverURL) ? getOptionalParam(SERVER_URL, "") : serverURL; + user = StringUtils.isEmpty(user) ? getOptionalParam(USER_NAME, "") : user; + password = StringUtils.isEmpty(password) ? getOptionalParam(USER_PASSWORD, "") : password; + projectName = StringUtils.isEmpty(projectName) ? getOptionalParam(FULL_PROJECT_PATH, "") + : projectName; + } + } + if (exploitablePathParamsIncomplete(serverURL, user, password, projectId, projectName)) { if (!exploitablePathParamsEmpty(serverURL, user, password, projectId, projectName)) throw new CLIParsingException( "[CxConsole] For SCA exploitable path, CxSAST server details like url, user, password and full project path or project id are required. Received partial parameters."); @@ -1131,6 +1157,67 @@ private static String getRequiredParam(CommandLine cmdLine, String cmdLineOption return result; } + public static String checkMissingMandatoryAdditionalParams(CommandLine cmdLine, String addParams) + throws CLIParsingException { + if (addParams == null) + addParams = ""; + if (!addParams.contains("-n ")) { + String projectName = cmdLine.getOptionValue(FULL_PROJECT_PATH); + if (StringUtils.isNotEmpty(projectName)) { + projectName = projectName.trim(); + addParams += " -n " + projectName; + } else + throw new CLIParsingException("projectname command line option must be specified"); + } + if (!addParams.contains("-s ")) { + String locationPath = cmdLine.getOptionValue(LOCATION_PATH); + String scaLocationPath = cmdLine.getOptionValue(SCA_LOCATION_PATH); + if (StringUtils.isNotEmpty(locationPath)) { + locationPath = locationPath.trim(); + addParams += " -s " + locationPath; + } else if (StringUtils.isNotEmpty(scaLocationPath)) { + scaLocationPath = scaLocationPath.trim(); + addParams += " -s " + scaLocationPath; + } else + throw new CLIParsingException("locationpath command line option must be specified"); + } + if (cmdLine.hasOption(SCA_ENABLED) + && (addParams.contains("--cxprojectname ") || addParams.contains("--cxprojectid "))) { + if (!addParams.contains("--cxserver ")) { + String cxserver = cmdLine.getOptionValue(SERVER_URL); + if (StringUtils.isNotEmpty(cxserver)) { + cxserver = cxserver.trim(); + addParams += " --cxserver " + cxserver; + } else + throw new CLIParsingException("cxserver command line option must be specified"); + } + if (!addParams.contains("--cxuser ")) { + String cxuser = cmdLine.getOptionValue(USER_NAME); + if (StringUtils.isNotEmpty(cxuser)) { + cxuser = cxuser.trim(); + addParams += " --cxuser " + cxuser; + } else + throw new CLIParsingException("cxuser command line option must be specified"); + } + if (!addParams.contains("--cxpassword ")) { + String cxpassword = cmdLine.getOptionValue(USER_PASSWORD); + if (StringUtils.isNotEmpty(cxpassword)) { + cxpassword = cxpassword.trim(); + addParams += " --cxpassword " + cxpassword; + } else + throw new CLIParsingException("cxpassword command line option must be specified"); + } + } else if (addParams.contains("--cxprojectname ") || addParams.contains("--cxprojectid ")) { + if (!addParams.contains("--cxserver ") || !addParams.contains("--cxuser ") + || !addParams.contains("--cxpassword ")) { + throw new CLIParsingException( + "--cxserver, --cxuser, --cxpassword and --cxprojectname must be specified to use Exploitable Path."); + } + + } + return addParams; + } + private static String normalizeUrl(String rawValue) { return rawValue.startsWith("http") ? rawValue : "http://" + rawValue; }