diff --git a/CxScan/CxScanV20/package.json b/CxScan/CxScanV20/package.json index c34ad48f..52cecd19 100644 --- a/CxScan/CxScanV20/package.json +++ b/CxScan/CxScanV20/package.json @@ -1,6 +1,6 @@ { "name": "cxsast", - "version": "2023.3.3", + "version": "2024.2.1", "description": "Add Secure Static Source Code Analysis inside your build process", "main": "index.js", "repository": "https://github.com/checkmarx-ltd/VSTS-Plugin", @@ -10,7 +10,7 @@ "author": "MajdM", "license": "SEE LICENSE IN checkmarx-license-terms.md", "dependencies": { - "@checkmarx/cx-common-js-client": "0.1.83", + "@checkmarx/cx-common-js-client": "0.1.86", "degenerator": "3.0.4", "azure-pipelines-task-lib": "^3.1.7", "cookiejar": "2.1.4", diff --git a/CxScan/CxScanV20/services/configReader.js b/CxScan/CxScanV20/services/configReader.js index 37663d55..9cbdb9e8 100644 --- a/CxScan/CxScanV20/services/configReader.js +++ b/CxScan/CxScanV20/services/configReader.js @@ -63,6 +63,7 @@ var ConfigReader = /** @class */ (function () { comment: taskLib.getInput('comment', false) || '', enablePolicyViolations: taskLib.getBoolInput('enablePolicyViolations', false), vulnerabilityThreshold: taskLib.getBoolInput('vulnerabilityThreshold', false), + criticalThreshold: ConfigReader.getNumericInput('critical'), highThreshold: ConfigReader.getNumericInput('high'), mediumThreshold: ConfigReader.getNumericInput('medium'), lowThreshold: ConfigReader.getNumericInput('low'), @@ -94,6 +95,7 @@ var ConfigReader = /** @class */ (function () { var formatOptionalNumber = function (input) { return (typeof input === 'undefined' ? 'none' : input); }; this.log.info("\n-------------------------------CxSAST Configurations:--------------------------------\nURL: " + config.serverUrl + "\nProject name: " + config.projectName + "\nSource location: " + config.sourceLocation + "\nFull team path: " + config.teamName + "\nPreset name: " + config.presetName + "\nScan timeout in minutes: " + config.scanTimeoutInMinutes + "\nDeny project creation: " + config.denyProject + "\n\nIs incremental scan: " + config.isIncremental + "\nFolder exclusions: " + formatOptionalString(config.folderExclusion) + "\nFile exclusions: " + formatOptionalString(config.fileExtension) + "\nIs synchronous scan: " + config.isSyncMode + "\n\nCxSAST thresholds enabled: " + config.vulnerabilityThreshold); if (config.vulnerabilityThreshold) { + this.log.info("CxSAST critical threshold: " + formatOptionalNumber(config.criticalThreshold)); this.log.info("CxSAST high threshold: " + formatOptionalNumber(config.highThreshold)); this.log.info("CxSAST medium threshold: " + formatOptionalNumber(config.mediumThreshold)); this.log.info("CxSAST low threshold: " + formatOptionalNumber(config.lowThreshold)); diff --git a/CxScan/CxScanV20/services/configReader.ts b/CxScan/CxScanV20/services/configReader.ts index faa1b1a0..e28a5d86 100644 --- a/CxScan/CxScanV20/services/configReader.ts +++ b/CxScan/CxScanV20/services/configReader.ts @@ -19,7 +19,8 @@ export class ConfigReader { private readonly devAzure = 'dev.azure.com'; private readonly MAX_SIZE_CXORIGINURL = 128; private readonly SIZE_CXORIGIN = 50; - private readonly SCARESOLVER_FILENAME = "\\ScaResolver.exe"; + private readonly SCARESOLVER_FILENAME_WINDOWS = "\\ScaResolver.exe"; + private readonly SCARESOLVER_FILENAME_OTHER_OS = "ScaResolver"; constructor(private readonly log: Logger) { } @@ -91,6 +92,8 @@ export class ConfigReader { let vulnerabilityThresholdEnabled = false; let failBuildForNewVulnerabilitiesEnabled = false; let failBuildForNewVulnerabilitiesSeverity = ''; + let enableBranching = false; + let parentBranchProjectName = ''; let buildId = taskLib.getVariable('Build.BuildId') || ''; @@ -107,6 +110,9 @@ export class ConfigReader { presetSASTServiceCon = taskLib.getEndpointAuthorizationParameter(endpointId, 'preset', true) || ''; sastPassword = taskLib.getEndpointAuthorizationParameter(endpointId, 'password', false) || ''; isIncremental = taskLib.getBoolInput('incScan', false) || false; + enableBranching = taskLib.getBoolInput('enableSastBranching', false) || false; + if(enableBranching) + parentBranchProjectName = taskLib.getInput('masterBranchProjectName', false) || ''; // adding if(isIncremental) { isScheduledScan = taskLib.getBoolInput('fullScansScheduled', false) || false; @@ -331,6 +337,12 @@ export class ConfigReader { const postScanAction = taskLib.getInput('postScanAction', false) || ''; const avoidDuplicateProjectScans = taskLib.getBoolInput('avoidDuplicateScans', false); + + let rawWaitTime = taskLib.getInput('waitingTimeBeforeRetryScan', false) as any; + let retryWaitTime = +rawWaitTime; + + let rawSCAWaitTime = taskLib.getInput('waitingTimeBeforeRetrySCAScan', false) as any; + let retrySCAWaitTime = +rawSCAWaitTime; let rawTimeout = taskLib.getInput('scanTimeout', false) as any; @@ -373,7 +385,8 @@ export class ConfigReader { isEnableScaResolver:taskLib.getBoolInput('isEnableScaResolver', false) || false, pathToScaResolver:taskLib.getInput('pathToScaResolver', false) || '', scaResolverAddParameters:taskLib.getInput('scaResolverAddParameters', false) || '', - scaScanTimeoutInMinutes: scaScanTimeoutInMinutes || undefined + scaScanTimeoutInMinutes: scaScanTimeoutInMinutes || undefined, + scaWaitTimeForRetryScan: retrySCAWaitTime || undefined }; var isSyncMode = taskLib.getBoolInput('syncMode', false); @@ -399,6 +412,7 @@ export class ConfigReader { generatePDFReport: generatePDFReport, vulnerabilityThreshold: vulnerabilityThresholdEnabled, + criticalThreshold: ConfigReader.getNumericInput('critical'), highThreshold: ConfigReader.getNumericInput('high'), mediumThreshold: ConfigReader.getNumericInput('medium'), lowThreshold: ConfigReader.getNumericInput('low'), @@ -412,6 +426,9 @@ export class ConfigReader { engineConfigurationId: ConfigReader.getNumericInput('engineConfigId'), postScanActionName: postScanAction, avoidDuplicateProjectScans: avoidDuplicateProjectScans, + enableSastBranching : enableBranching, + masterBranchProjectName : parentBranchProjectName, + waitTimeForRetryScan : retryWaitTime || undefined }; const result: ScanConfig = { @@ -472,7 +489,9 @@ Preset name: ${config.sastConfig.presetName} Deny project creation: ${config.sastConfig.denyProject} Force scan : ${config.sastConfig.forceScan} Is Override Project Settings: ${config.sastConfig.overrideProjectSettings} -Is incremental scan: ${config.sastConfig.isIncremental}`); +Is incremental scan: ${config.sastConfig.isIncremental} +Enable SAST Branching : ${config.sastConfig.enableSastBranching} +Master Branch Project Name : ${config.sastConfig.masterBranchProjectName}`); if (config.sastConfig.isIncremental) { let isScheduledScan = taskLib.getBoolInput('fullScansScheduled', false) || false; let scheduleCycle = taskLib.getInput('fullScanCycle', false) || ''; @@ -482,6 +501,9 @@ if (config.sastConfig.isIncremental) { if(config.sastConfig.scanTimeoutInMinutes != undefined){ this.log.info(`Scan timeout in minutes: ${config.sastConfig.scanTimeoutInMinutes}`); } + if(config.sastConfig.waitTimeForRetryScan != undefined){ + this.log.info(`Waiting Time Before Retry Scan In Seconds: ${config.sastConfig.waitTimeForRetryScan}`); + } this.log.info(`Folder exclusions: ${formatOptionalString(config.sastConfig.folderExclusion)} Include/Exclude Wildcard Patterns: ${formatOptionalString(config.sastConfig.fileExtension)} Is synchronous scan: ${config.isSyncMode} @@ -500,6 +522,7 @@ CxSAST thresholds enabled: ${config.sastConfig.vulnerabilityThreshold}`); if (config.sastConfig.vulnerabilityThreshold) { this.log.info(`CxSAST fail build for new vulnerabilities enabled: ${config.sastConfig.failBuildForNewVulnerabilitiesEnabled}`); this.log.info(`CxSAST fail build for the following severity or greater: ${config.sastConfig.failBuildForNewVulnerabilitiesSeverity}`); + this.log.info(`CxSAST critical threshold: ${formatOptionalNumber(config.sastConfig.criticalThreshold)}`); this.log.info(`CxSAST high threshold: ${formatOptionalNumber(config.sastConfig.highThreshold)}`); this.log.info(`CxSAST medium threshold: ${formatOptionalNumber(config.sastConfig.mediumThreshold)}`); this.log.info(`CxSAST low threshold: ${formatOptionalNumber(config.sastConfig.lowThreshold)}`); @@ -534,22 +557,35 @@ Vulnerability Threshold: ${config.scaConfig.vulnerabilityThreshold} Enable SCA Resolver:${config.scaConfig.isEnableScaResolver} `); if(config.scaConfig.isEnableScaResolver) { - - var isScaResolverFileExists= fs.existsSync(config.scaConfig.pathToScaResolver.concat(this.SCARESOLVER_FILENAME) ); + + let isScaResolverFileExists= false; + let osTypeDetails = os.type(); + if(osTypeDetails == 'Windows_NT') + { + isScaResolverFileExists = fs.existsSync(config.scaConfig.pathToScaResolver.concat(this.SCARESOLVER_FILENAME_WINDOWS)); + } + else if(osTypeDetails == 'Darwin' || osTypeDetails == 'Linux') + { + isScaResolverFileExists = fs.existsSync(path.join(config.scaConfig.pathToScaResolver, this.SCARESOLVER_FILENAME_OTHER_OS)); + } + if (!isScaResolverFileExists && config.scaConfig.pathToScaResolver != '' ) { this.log.warning(`SCA Resolver tool doesn't exists on given SCA Resolver path. Latest SCA Resolver would be auto downloaded for usage in user directory.`); } if (config.scaConfig.pathToScaResolver == '' || !isScaResolverFileExists){ - config.scaConfig.pathToScaResolver = this.getPathToScaResolver(config.scaConfig.pathToScaResolver); + config.scaConfig.pathToScaResolver = this.getPathToScaResolver(config.scaConfig.pathToScaResolver,config.enableProxy,config.proxyConfig?.scaProxyUrl); } this.log.info(`Path To SCA Resolver:${config.scaConfig.pathToScaResolver}`); } if(config.scaConfig.scaScanTimeoutInMinutes != undefined) { this.log.info(`Scan timeout in minutes: ${config.scaConfig.scaScanTimeoutInMinutes}`); } + if(config.scaConfig.scaWaitTimeForRetryScan != undefined) { + this.log.info(`Waiting time before retry SCA scan in seconds: ${config.scaConfig.scaWaitTimeForRetryScan}`); + } if (config.scaConfig.vulnerabilityThreshold) { this.log.info(`CxSCA High Threshold: ${config.scaConfig.highThreshold} CxSCA Medium Threshold: ${config.scaConfig.mediumThreshold} @@ -624,30 +660,63 @@ Proxy Pass: ******`); } //To get path of SCA Resolver - public getPathToScaResolver(config : string){ + public getPathToScaResolver(config : string,enableProxy :boolean,proxyUrl :string = ''){ let pathToScaResolver; try { let SCAResDowonloadCommand = ''; const child_process = require('child_process'); const userHomeDir = os.homedir(); pathToScaResolver = userHomeDir; - + this.log.debug("Downloading SCA Resolver and extracting it to user home directory."); + + if (enableProxy) { + this.log.info(`scanConfig.enableProxy is TRUE`); + } + + if (proxyUrl != undefined && proxyUrl != '') { + + this.log.info(`proxyConfig.proxyUrl is TRUE`); + this.log.info(`SCA proxy URL: ` + proxyUrl); + } + let osType = os.type(); switch(osType) { case 'Darwin': this.log.debug("Downloading and extracting SCA Resolver for Mac operating system"); - SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-macos64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver " + userHomeDir + " && rm ScaResolver.tar.gz"; + if (enableProxy && proxyUrl !=undefined && proxyUrl != '') + { + SCAResDowonloadCommand = `curl -L -x ${proxyUrl} https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-macos64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver ` + userHomeDir + ` && rm ScaResolver.tar.gz`; + } + else + { + SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-macos64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver " + userHomeDir + " && rm ScaResolver.tar.gz"; + } this.log.debug("Sca Resolver gets downloaded at location: "+userHomeDir); break; case 'Linux': this.log.debug("Downloading and extracting SCA Resolver for linux operating system"); - SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-linux64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver " + userHomeDir + " && rm ScaResolver.tar.gz"; + if (enableProxy && proxyUrl !=undefined && proxyUrl != '') + { + SCAResDowonloadCommand = `curl -L -x ${proxyUrl} https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-linux64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver ` + userHomeDir + ` && rm ScaResolver.tar.gz`; + } + else + { + SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-linux64.tar.gz -o ScaResolver.tar.gz && tar -vxzf ScaResolver.tar.gz && sudo mv ScaResolver " + userHomeDir + " && rm ScaResolver.tar.gz"; + } this.log.debug("Sca Resolver gets downloaded at location: "+userHomeDir); break; case 'Windows_NT': this.log.debug("Downloading and extracting SCA Resolver for windows operating system"); - SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-win64.zip -o ScaResolver.zip && tar -xf ScaResolver.zip && move ScaResolver.exe " + userHomeDir + " && del ScaResolver.zip"; + + if (enableProxy && proxyUrl !=undefined && proxyUrl != '') + { + SCAResDowonloadCommand = `curl -L -x ${proxyUrl} https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-win64.zip -o ScaResolver.zip && tar -xf ScaResolver.zip && move ScaResolver.exe ` + userHomeDir + ` && del ScaResolver.zip`; + } + else + { + SCAResDowonloadCommand = "curl -L https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-win64.zip -o ScaResolver.zip && tar -xf ScaResolver.zip && move ScaResolver.exe " + userHomeDir + " && del ScaResolver.zip"; + } this.log.debug("Sca Resolver gets downloaded at location: "+userHomeDir); break; } diff --git a/CxScan/CxScanV20/services/taskRunner.ts b/CxScan/CxScanV20/services/taskRunner.ts index 775538f2..023a0151 100644 --- a/CxScan/CxScanV20/services/taskRunner.ts +++ b/CxScan/CxScanV20/services/taskRunner.ts @@ -3,10 +3,7 @@ import {ConsoleLogger} from "./consoleLogger"; import {ConfigReader} from "./configReader"; import * as fs from "fs"; import {tmpNameSync} from "tmp"; -import {CxClient} from "@checkmarx/cx-common-js-client"; -import {ScanResults} from "@checkmarx/cx-common-js-client"; -import {TaskSkippedError} from "@checkmarx/cx-common-js-client"; -import {Logger} from "@checkmarx/cx-common-js-client"; +import {CxClient, ScanConfig,Logger,TaskSkippedError,ScanResults} from "@checkmarx/cx-common-js-client"; import * as path from "path"; export class TaskRunner { @@ -17,6 +14,8 @@ export class TaskRunner { private static readonly REPORT_SCA_SUMMARY = 'cxSCASummary'; private static readonly CxSAST = 'SAST'; private static readonly CxDependency = 'SCA'; + private readonly MinValue = 1; + private readonly MaxValue = 60; private readonly log: Logger = new ConsoleLogger(); @@ -43,12 +42,15 @@ export class TaskRunner { const reader = new ConfigReader(this.log); const config = reader.readConfig(); - const cxClient = new CxClient(this.log); - const scanResults: ScanResults = await cxClient.scan(config); - await this.attachJsonReport(scanResults); - - if (scanResults.buildFailed) { - taskLib.setResult(taskLib.TaskResult.Failed, 'Build failed'); + if(this.validateConfigParameter(config)) + { + this.log.info('Inside validateConfigParameter'); + const cxClient = new CxClient(this.log); + const scanResults: ScanResults = await cxClient.scan(config); + await this.attachJsonReport(scanResults); + if (scanResults.buildFailed) { + taskLib.setResult(taskLib.TaskResult.Failed, 'Build failed'); + } } } catch (err) { if (err instanceof TaskSkippedError) { @@ -203,4 +205,38 @@ export class TaskRunner { Starting Checkmarx scan`); } + + private validateConfigParameter(config :ScanConfig) : boolean + { + let sastWaitTime = taskLib.getInput('waitingTimeBeforeRetryScan', false) as any; + let scaWaitTime = taskLib.getInput('waitingTimeBeforeRetrySCAScan', false) as any; + if(config.enableSastScan && sastWaitTime!=undefined && sastWaitTime.trim() != '') + { + if(isNaN(sastWaitTime)) + { + taskLib.setResult(taskLib.TaskResult.Failed, 'Waiting time before retry scan input is invalid value.'); + return false; + } + else if (sastWaitTime <= this.MinValue || sastWaitTime >= this.MaxValue) { + taskLib.setResult(taskLib.TaskResult.Failed, `Waiting time before retry scan value must be a between ${this.MinValue} and ${this.MaxValue}.`); + return false; + } + } + + if(config.enableDependencyScan && scaWaitTime!= undefined && scaWaitTime.trim() != '') + { + this.log.info('inside function'); + if(isNaN(scaWaitTime)) + { + taskLib.setResult(taskLib.TaskResult.Failed, 'Waiting time before retry sca scan input is invalid value.'); + return false; + } + else if (scaWaitTime <= this.MinValue || scaWaitTime >= this.MaxValue) { + taskLib.setResult(taskLib.TaskResult.Failed, `Waiting time before retry sca scan value must be a between ${this.MinValue} and ${this.MaxValue}.`); + return false; + } + } + return true; + } + } \ No newline at end of file diff --git a/CxScan/CxScanV20/task.json b/CxScan/CxScanV20/task.json index 138ed41f..2de64496 100644 --- a/CxScan/CxScanV20/task.json +++ b/CxScan/CxScanV20/task.json @@ -10,9 +10,9 @@ ], "author": "Checkmarx", "version": { - "Major": 2023, - "Minor": 3, - "Patch": 3 + "Major": 2024, + "Minor": 2, + "Patch": 1 }, "demands": [], "minimumAgentVersion": "2.144.0", @@ -94,6 +94,25 @@ "groupName": "scanSettings", "visibleRule": "enableSastScan = true" }, + { + "name": "enableSastBranching", + "type": "boolean", + "label": "Enable SAST Branching", + "required": true, + "helpMarkDown": "Enable to support branching. This supports only for creating new project.", + "groupName": "scanSettings", + "defaultValue": false, + "visibleRule": "enableSastScan = true" + }, + { + "name": "masterBranchProjectName", + "type": "string", + "label": "Master Branch Project Name", + "required": true, + "helpMarkDown": "The SAST project will be created from the branch name provided in this parameter value. This parameter is mandatory if the Enable SAST Branching parameter is enabled. This supports only for creating new project.", + "groupName": "scanSettings", + "visibleRule": "enableSastScan = true && enableSastBranching = true" + }, { "name": "preset", "type": "pickList", @@ -101,7 +120,7 @@ "required": false, "groupName": "scanSettings", "defaultValue": "Checkmarx Default", - "helpMarkDown": "predefined sets of queries that you can select when Creating, Configuring and Branching Projects. Predefined presets are provided by Checkmarx and you can configure your own. You can also import and export presets (on the server).If preset is mentioned in Service connection, then this will get overridden with Service connection Preset", + "helpMarkDown": "Predefined sets of queries that you can select when Creating, Configuring and Branching Projects. Predefined presets are provided by Checkmarx and you can configure your own. You can also import and export presets (on the server). In Service Connection if preset(optional) value is added, then it will ignores Preset available in pipeline and uses preset available in service connection only. If Preset is blank in service connection then it will use pipelines preset.", "options": { "Checkmarx Default": "Checkmarx Default", "All": "All", @@ -168,7 +187,7 @@ "type": "string", "label": "Team", "required": false, - "helpMarkDown": "The full team name (for example, CxServer\\SP\\Company\\Users). If team is mentioned in Service connection,then this will get overridden with Service connection Team", + "helpMarkDown": "The full team name(for example, CxServer\\SP\\Company\\Users). In Service Connection if Team(optional) value is added, then it will ignores Team available in pipeline and uses Team available in service connection only. If Team is blank in service connection then it will use pipelines Team.", "groupName": "scanSettings", "visibleRule": "enableSastScan = true" }, @@ -258,6 +277,15 @@ "groupName": "scanSettings", "visibleRule": "enableSastScan = true" }, + { + "name": "waitingTimeBeforeRetryScan", + "type": "string", + "label": "Waiting Time Before Retry Scan In Seconds", + "required": false, + "helpMarkDown": "Wait for specified time before retry scan in seconds. If value is not added then by default waiting time before retry scan in 10 seconds. The maximum value we can add is 60 seconds.", + "groupName": "scanSettings", + "visibleRule": "enableSastScan = true" + }, { "name": "projectcustomfields", "type": "string", @@ -339,15 +367,25 @@ "type": "pickList", "label": "Fail for the following severity or greater", "required": false, - "helpMarkDown": "This will fail the build for following severity or greater. (e.g. if 'MEDIUM' is selected then any new vulnerabilities found for 'MEDIUM' and 'HIGH' severity will cause the build to fail) ", + "helpMarkDown": "This will fail the build for following severity or greater. (e.g. if 'MEDIUM' is selected then any new vulnerabilities found for 'MEDIUM' and 'HIGH' severity will cause the build to fail). SAST 9.6 and lower version will not support critical severity features.", "groupName": "scanSettings", "visibleRule": "vulnerabilityThreshold = true && enableSastScan = true && failBuildForNewVulnerabilitiesEnabled = true", "options": { + "CRITICAL": "CRITICAL", "HIGH": "HIGH", "MEDIUM": "MEDIUM", "LOW": "LOW" } }, + { + "name": "critical", + "type": "string", + "label": "CxSAST Critical", + "required": false, + "helpMarkDown": "Define a threshold for the critical severity vulnerabilities. The build will be marked as failed if the number of the critical severity vulnerabilities is larger than the threshold. SAST 9.6 and lower version will not support critical severity features.", + "groupName": "scanSettings", + "visibleRule": "vulnerabilityThreshold = true && enableSastScan = true" + }, { "name": "high", "type": "string", @@ -553,26 +591,6 @@ "groupName": "dependencyScan", "visibleRule": "enableDependencyScan = true && isEnableScaResolver=false" }, - - { - "name": "scaExploitablePath", - "type": "boolean", - "label": "Enable Exploitable Path", - "required": false, - "defaultValue": "false", - "helpMarkDown": "Exploitable Path feature will attempt to co-relate CxSCA scan with the available CxSAST scan results. In this section, provide details like CxSAST server url, credentials. At the job level, two more parameters need to be configured. These project full path name and/or project id from CxSAST.Example of Project Full Path: CxServer/team1/projectname", - "groupName": "dependencyScan", - "visibleRule": "enableDependencyScan = true && isEnableScaResolver=false" - }, - { - "name": "CheckmarxServiceForSca", - "type": "connectedService:Checkmarx-Endpoint", - "label": "Checkmarx SAST Endpoint", - "required": false, - "helpMarkDown": "The CX server endpoint.", - "groupName": "dependencyScan", - "visibleRule": "enableDependencyScan = true && scaExploitablePath = true" - }, { "name": "dependencyAccessControlURL", "type": "string", @@ -602,24 +620,6 @@ "groupName": "dependencyScan", "visibleRule": "enableDependencyScan = ignore" }, - { - "name": "scaProjectFullPath", - "type": "string", - "label": "Project Full Path", - "required": false, - "helpMarkDown": "Project Full Path with team value", - "groupName": "dependencyScan", - "visibleRule": "enableDependencyScan = true && scaExploitablePath = true" - }, - { - "name": "scaProjectId", - "type": "string", - "label": "Project ID", - "required": false, - "helpMarkDown": "Project ID", - "groupName": "dependencyScan", - "visibleRule": "enableDependencyScan = true && scaExploitablePath = true " - }, { "name": "scaEnablePolicyViolations", "type": "boolean", @@ -675,6 +675,15 @@ "helpMarkDown": "Abort the scan if exceeds specified timeout in minutes ", "groupName": "dependencyScan", "visibleRule": "enableDependencyScan = true" + }, + { + "name": "waitingTimeBeforeRetrySCAScan", + "type": "number", + "label": "Waiting Time Before Retry SCA Scan In Seconds", + "required": false, + "helpMarkDown": "Wait for specified time before retry SCA scan in seconds.If value is not added then by default waiting time before retry SCA scan in 5 seconds. The maximum value we can add is 60 seconds.", + "groupName": "dependencyScan", + "visibleRule": "enableDependencyScan = true" } ], "execution": { diff --git a/Reports/css/cxreport.css b/Reports/css/cxreport.css index 2629a81b..253cfca7 100644 --- a/Reports/css/cxreport.css +++ b/Reports/css/cxreport.css @@ -120,7 +120,6 @@ td { max-width: 709px; margin-right: auto; margin-left: auto; - /*margin-left: calc(250px + 8%);*/ } .results-report .sast-summary.chart-large .chart li span { @@ -175,21 +174,19 @@ td { animation: draw 1s ease-in-out; } -.results-report .sast-summary.chart-large .chart .bar-count { - /*width: 53px;*/ -} .results-report .chart .bar-count { - margin-left: 4px; + margin-left: 2px; + margin-top: 2px; } .results-report .chart .bar-title { - font-size: 14px; + font-size: 13px; white-space: nowrap; } .results-report .bar-title-icon { - margin-right: 6px; + margin-right: 3px; } .results-report .chart .bar-title-container { @@ -218,6 +215,11 @@ td { background-color: #373050; } +.results-report .chart .bar-4 { + position: relative; + background-color: #373050; +} + .results-report .threshold-exceeded-compliance { } @@ -313,6 +315,18 @@ td { padding-right: 3px; } +.results-report .chart-small .threshold-line { + width: 20px; + border-bottom: dashed white 1px; + padding-right: 3px; +} + +.results-report .sast-summary.chart-large .threshold-line { + width: 50px; + border-bottom: dashed white 1px; + padding-right: 3px; +} + .results-report .threshold-tooltip { display: flex; transform: translate(0, 50%); @@ -396,7 +410,6 @@ td { .main-column { width: 77%; - /*max-width: 709px;*/ min-width: 500px; } @@ -438,7 +451,6 @@ td { font-size: 16px; display: table-cell; vertical-align: middle; - /*width: 75%;*/ } .graph { @@ -455,7 +467,6 @@ td { .detailed-report { margin-top: 12px; display: block; - /*padding: 0 11px;*/ } .detailed-report-ttl { @@ -590,6 +601,7 @@ table.cve-table td { padding: 11px; } +table.cve-table td.sast-cve-table-critical, table.cve-table td.sast-cve-table-high, table.cve-table td.sast-cve-table-med, table.cve-table td.sast-cve-table-low { diff --git a/Reports/cxSummary.html b/Reports/cxSummary.html index 9e48b9df..17bbf295 100644 --- a/Reports/cxSummary.html +++ b/Reports/cxSummary.html @@ -73,6 +73,32 @@