From 33583e01944529daffc9a3bf0f81ec522b927205 Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:12:28 +0300 Subject: [PATCH 1/6] Add secrets-realtime command and corresponding scan results method --- src/main/wrapper/CxConstants.ts | 1 + src/main/wrapper/CxWrapper.ts | 7 +++++++ src/tests/ScanTest.test.ts | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index 487723ff..a7f1a617 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -73,6 +73,7 @@ export enum CxConstants { SOURCE_FILE = "--file-source", ASCA_UPDATE_VERSION = "--asca-latest-version", CMD_OSS = "oss-realtime", + CMD_SECRETS = "secrets-realtime", PROJECT_ID = "--project-id", SIMILARITY_ID = "--similarity-id", QUERY_ID = "--query-id", diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index b8c645b2..8be06d58 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -150,6 +150,13 @@ export class CxWrapper { } async ossScanResults(sourceFile: string): Promise { + const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_SECRETS, CxConstants.SOURCE, sourceFile]; + commands.push(...this.initializeCommands(false)); + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_OSS); + } + + async secretsScanResults(sourceFile: string): Promise { const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_OSS, CxConstants.SOURCE, sourceFile]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); diff --git a/src/tests/ScanTest.test.ts b/src/tests/ScanTest.test.ts index 6c6f8f51..725c6dff 100644 --- a/src/tests/ScanTest.test.ts +++ b/src/tests/ScanTest.test.ts @@ -182,4 +182,12 @@ describe("ScanCreate cases", () => { expect(cxCommandOutput.exitCode).toBe(0); }); + it.skip('ScanSecrets Successful case', async () => { + const wrapper = new CxWrapper(cxScanConfig); + const cxCommandOutput: CxCommandOutput = await wrapper.secretsScanResults("tsc/tests/data/package.json"); + console.log("Json object from scanOSS successful case: " + JSON.stringify(cxCommandOutput)); + expect(cxCommandOutput.payload).toBeDefined(); + expect(cxCommandOutput.exitCode).toBe(0); + }); + }); From c9384a059c630d5f0e91822abac197334744efe9 Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:23:43 +0300 Subject: [PATCH 2/6] Add support for secrets scanning with new CxSecretsResult class and update execution commands --- src/main/secrets/CxSecrets.ts | 43 ++++++ src/main/wrapper/CxConstants.ts | 1 + src/main/wrapper/CxWrapper.ts | 2 +- src/main/wrapper/ExecutionService.ts | 222 ++++++++++++++------------- 4 files changed, 158 insertions(+), 110 deletions(-) create mode 100644 src/main/secrets/CxSecrets.ts diff --git a/src/main/secrets/CxSecrets.ts b/src/main/secrets/CxSecrets.ts new file mode 100644 index 00000000..593b3799 --- /dev/null +++ b/src/main/secrets/CxSecrets.ts @@ -0,0 +1,43 @@ +export default class CxSecretsResult { + title: string; + description: string; + filepath: string; + severity: string; + locations: { line: number, startIndex: number, endIndex: number }[]; + + static parseResult(resultObject: any): CxSecretsResult[] { + const results = resultObject.Packages; + let secretsResults: CxSecretsResult[] = []; + if (results instanceof Array) { + secretsResults = results.map((member: any) => { + const secretsResult = new CxSecretsResult(); + secretsResult.title = member.Title; + secretsResult.description = member.Description; + secretsResult.filepath = member.FilePath; + secretsResult.locations = Array.isArray(member.Locations) + ? member.Locations.map((l: any) => ({ + line: l.Line, + startIndex: l.StartIndex, + endIndex: l.EndIndex, + })) + : []; + return secretsResult; + }); + } else { + const secretsResult = new CxSecretsResult(); + secretsResult.title = results.Title; + secretsResult.description = results.Description; + secretsResult.filepath = results.FilePath; + secretsResult.filepath = results.FilePath; + secretsResult.locations = Array.isArray(results.Locations) + ? results.Locations.map((l: any) => ({ + line: l.Line, + startIndex: l.StartIndex, + endIndex: l.EndIndex, + })) + : []; + secretsResults.push(secretsResult); + } + return secretsResults; + } +} diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index a7f1a617..9174ea4f 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -90,6 +90,7 @@ export enum CxConstants { SCAN_TYPE = "CxScan", SCAN_ASCA = "CxAsca", SCAN_OSS = "CxOss", + SCAN_SECRETS = "CxSecrets", PROJECT_TYPE = "CxProject", PREDICATE_TYPE = "CxPredicate", CODE_BASHING_TYPE = "CxCodeBashing", diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index 8be06d58..c814a09d 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -160,7 +160,7 @@ export class CxWrapper { const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_OSS, CxConstants.SOURCE, sourceFile]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); - return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_OSS); + return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_SECRETS); } async scanCancel(id: string): Promise { diff --git a/src/main/wrapper/ExecutionService.ts b/src/main/wrapper/ExecutionService.ts index f16e1bfd..a9ab197b 100644 --- a/src/main/wrapper/ExecutionService.ts +++ b/src/main/wrapper/ExecutionService.ts @@ -1,6 +1,6 @@ import {CxCommandOutput} from "./CxCommandOutput"; import CxScan from "../scan/CxScan"; -import { logger } from "./loggerConfig"; +import {logger} from "./loggerConfig"; import * as fs from "fs" import * as os from "os"; import * as path from "path"; @@ -24,6 +24,7 @@ import CxChat from "../chat/CxChat"; import CxMask from "../mask/CxMask"; import CxAsca from "../asca/CxAsca"; import CxOssResult from "../oss/CxOss"; +import CxSecretsResult from "../secrets/CxSecrets"; let skipValue = false; const fileSourceFlag = "--file-source" @@ -44,13 +45,13 @@ function transformation(commands: string[]): string[] { return result; } -function transform(n:string) { +function transform(n: string) { // in case the file name looks like this: 'var express require('express');.js' we won't delete "'" if (skipValue) { skipValue = false; let r = ""; - if(n) r = n.replace(/["]/g, "").replace("/[, ]/g",","); + if (n) r = n.replace(/["]/g, "").replace("/[, ]/g", ","); return r; } // If the current string is "--file-source", set the flag @@ -59,17 +60,17 @@ function transform(n:string) { } let r = ""; - if(n) r = n.replace(/["']/g, "").replace("/[, ]/g",","); + if (n) r = n.replace(/["']/g, "").replace("/[, ]/g", ","); return r; } export class ExecutionService { - private fsObject : any = undefined + private fsObject: any = undefined - executeCommands(pathToExecutable: string, commands: string[], output? : string ): Promise { - return (new Promise( (resolve, reject)=> { + executeCommands(pathToExecutable: string, commands: string[], output?: string): Promise { + return (new Promise((resolve, reject) => { let stderr = ""; - let stdout =""; + let stdout = ""; this.fsObject = spawner.spawn(pathToExecutable, transformation(commands)); this.fsObject.on('error', (data: { toString: () => string; }) => { @@ -79,33 +80,33 @@ export class ExecutionService { } reject() }); - this.fsObject.on('exit',(code: number) => { + this.fsObject.on('exit', (code: number) => { logger.info("Exit code received from AST-CLI: " + code); - if(code==1){ + if (code == 1) { stderr = stdout } resolve(ExecutionService.onCloseCommand(code, stderr, stdout, output)); }); this.fsObject.stdout.on('data', (data: { toString: () => string; }) => { if (data) { - logger.info(data.toString().replace('\n', '')); - stdout += data.toString(); + logger.info(data.toString().replace('\n', '')); + stdout += data.toString(); } }); this.fsObject.stderr.on('data', (data: { toString: () => string; }) => { - if (data) { - logger.error(data.toString().replace('\n', '')); - stderr += data.toString(); - } + if (data) { + logger.error(data.toString().replace('\n', '')); + stderr += data.toString(); + } }); })); } - executeKicsCommands(pathToExecutable: string, commands: string[], output? : string ): [Promise,any] { - return [new Promise( (resolve, reject)=> { + executeKicsCommands(pathToExecutable: string, commands: string[], output?: string): [Promise, any] { + return [new Promise((resolve, reject) => { let stderr = ""; - let stdout =""; + let stdout = ""; this.fsObject = spawner.spawn(pathToExecutable, transformation(commands)); this.fsObject.on('error', (data: { toString: () => string; }) => { @@ -115,9 +116,9 @@ export class ExecutionService { } reject() }); - this.fsObject.on('exit',(code: number) => { + this.fsObject.on('exit', (code: number) => { logger.info("Exit code received from AST-CLI: " + code); - if(code==1){ + if (code == 1) { stderr = stdout } resolve(ExecutionService.onCloseCommand(code, stderr, stdout, output)); @@ -137,10 +138,10 @@ export class ExecutionService { }), this.fsObject]; } - executeMapTenantOutputCommands(pathToExecutable: string, commands: string[]): Promise> { - return (new Promise( (resolve, reject)=> { + executeMapTenantOutputCommands(pathToExecutable: string, commands: string[]): Promise> { + return (new Promise((resolve, reject) => { let stderr = ""; - let stdout =""; + let stdout = ""; this.fsObject = spawner.spawn(pathToExecutable, transformation(commands)); this.fsObject.on('error', (data: { toString: () => string; }) => { @@ -150,9 +151,9 @@ export class ExecutionService { } reject() }); - this.fsObject.on('exit',(code: number) => { + this.fsObject.on('exit', (code: number) => { logger.info("Exit code received from AST-CLI: " + code); - if(code==1){ + if (code == 1) { stderr = stdout reject(stderr) } @@ -173,12 +174,12 @@ export class ExecutionService { })); } - private static onCloseMapTenantOutputCommand(code: number, stderr: string, stdout: string): Map { - const result = new Map(); + private static onCloseMapTenantOutputCommand(code: number, stderr: string, stdout: string): Map { + const result = new Map(); if (code == 0) { const tenantSettingsList = stdout.split('\n'); tenantSettingsList.forEach(tenantSetting => { - tenantSetting.includes('Key') ? result.set(tenantSetting.split(':')[1],tenantSettingsList[tenantSettingsList.indexOf(tenantSetting) +1].split(':')[1]) : null; + tenantSetting.includes('Key') ? result.set(tenantSetting.split(':')[1], tenantSettingsList[tenantSettingsList.indexOf(tenantSetting) + 1].split(':')[1]) : null; }); } else { logger.error("Error occurred while executing command: " + stderr); @@ -186,73 +187,77 @@ export class ExecutionService { return result; } - private static onCloseCommand(code: number, stderr: string, stdout: string, output: string) : CxCommandOutput { - const cxCommandOutput = new CxCommandOutput(); - cxCommandOutput.exitCode = code; - if (stderr) { - cxCommandOutput.status = stderr; - } - if (stdout) { + private static onCloseCommand(code: number, stderr: string, stdout: string, output: string): CxCommandOutput { + const cxCommandOutput = new CxCommandOutput(); + cxCommandOutput.exitCode = code; + if (stderr) { + cxCommandOutput.status = stderr; + } + if (stdout) { const stdoutSplit = stdout.split('\n'); const data = stdoutSplit.find(isJsonString); if (data) { - const resultObject = JSON.parse(data); - switch (output) { - case CxConstants.SCAN_TYPE: - const scans = CxScan.parseProject(resultObject); - cxCommandOutput.payload = scans; - break; - case CxConstants.SCAN_ASCA: - const asca = CxAsca.parseScan(resultObject); - cxCommandOutput.payload = [asca]; - break; - case CxConstants.SCAN_OSS: - const oss = CxOssResult.parseResult(resultObject); - cxCommandOutput.payload = [oss]; - break; - case CxConstants.PROJECT_TYPE: - const projects = CxProject.parseProject(resultObject); - cxCommandOutput.payload = projects; - break; - case CxConstants.CODE_BASHING_TYPE: - const codeBashing = CxCodeBashing.parseCodeBashing(resultObject); - cxCommandOutput.payload = codeBashing; - break; - case CxConstants.BFL_TYPE: - const bflNode = CxBFL.parseBFLResponse(resultObject); - cxCommandOutput.payload = bflNode; - break; - case CxConstants.KICS_REALTIME_TYPE: - const kicsResults = CxKicsRealTime.parseKicsRealTimeResponse(resultObject); - cxCommandOutput.payload = [kicsResults]; - break; - case CxConstants.SCA_REALTIME_TYPE: - const scaRealtimeResponse = CxScaRealTime.parseScaRealTimeResponse(resultObject); - cxCommandOutput.payload = [scaRealtimeResponse]; - break; - case CxConstants.LEARN_MORE_DESCRIPTIONS_TYPE: - const learnMore = CxLearnMoreDescriptions.parseLearnMoreDescriptionsResponse(resultObject); - cxCommandOutput.payload = learnMore; - break; - case CxConstants.KICS_REMEDIATION_TYPE: - const kicsRemediationOutput = CxKicsRemediation.parseKicsRemediation(resultObject); - cxCommandOutput.payload = [kicsRemediationOutput]; - break; - case CxConstants.CHAT_TYPE: - const chatOutput = CxChat.parseChat(resultObject); - cxCommandOutput.payload = [chatOutput]; - break; - case CxConstants.MASK_TYPE: - const maskOutput = CxMask.parseMask(resultObject); - cxCommandOutput.payload = [maskOutput]; - break; - default: - cxCommandOutput.payload = resultObject; - } + const resultObject = JSON.parse(data); + switch (output) { + case CxConstants.SCAN_TYPE: + const scans = CxScan.parseProject(resultObject); + cxCommandOutput.payload = scans; + break; + case CxConstants.SCAN_ASCA: + const asca = CxAsca.parseScan(resultObject); + cxCommandOutput.payload = [asca]; + break; + case CxConstants.SCAN_OSS: + const oss = CxOssResult.parseResult(resultObject); + cxCommandOutput.payload = [oss]; + break; + case CxConstants.SCAN_SECRETS: + const secrets = CxSecretsResult.parseResult(resultObject); + cxCommandOutput.payload = [secrets]; + break; + case CxConstants.PROJECT_TYPE: + const projects = CxProject.parseProject(resultObject); + cxCommandOutput.payload = projects; + break; + case CxConstants.CODE_BASHING_TYPE: + const codeBashing = CxCodeBashing.parseCodeBashing(resultObject); + cxCommandOutput.payload = codeBashing; + break; + case CxConstants.BFL_TYPE: + const bflNode = CxBFL.parseBFLResponse(resultObject); + cxCommandOutput.payload = bflNode; + break; + case CxConstants.KICS_REALTIME_TYPE: + const kicsResults = CxKicsRealTime.parseKicsRealTimeResponse(resultObject); + cxCommandOutput.payload = [kicsResults]; + break; + case CxConstants.SCA_REALTIME_TYPE: + const scaRealtimeResponse = CxScaRealTime.parseScaRealTimeResponse(resultObject); + cxCommandOutput.payload = [scaRealtimeResponse]; + break; + case CxConstants.LEARN_MORE_DESCRIPTIONS_TYPE: + const learnMore = CxLearnMoreDescriptions.parseLearnMoreDescriptionsResponse(resultObject); + cxCommandOutput.payload = learnMore; + break; + case CxConstants.KICS_REMEDIATION_TYPE: + const kicsRemediationOutput = CxKicsRemediation.parseKicsRemediation(resultObject); + cxCommandOutput.payload = [kicsRemediationOutput]; + break; + case CxConstants.CHAT_TYPE: + const chatOutput = CxChat.parseChat(resultObject); + cxCommandOutput.payload = [chatOutput]; + break; + case CxConstants.MASK_TYPE: + const maskOutput = CxMask.parseMask(resultObject); + cxCommandOutput.payload = [maskOutput]; + break; + default: + cxCommandOutput.payload = resultObject; + } } - } + } - return cxCommandOutput; + return cxCommandOutput; } executeResultsCommands(pathToExecutable: string, commands: string[]): Promise { @@ -278,37 +283,36 @@ export class ExecutionService { }); } - async executeResultsCommandsFile(scanId: string, resultType: string, fileExtension: string,commands: string[], pathToExecutable: string,fileName:string): Promise { + async executeResultsCommandsFile(scanId: string, resultType: string, fileExtension: string, commands: string[], pathToExecutable: string, fileName: string): Promise { const filePath = path.join(os.tmpdir(), fileName + fileExtension) - const read = fs.readFileSync(filePath,'utf8'); + const read = fs.readFileSync(filePath, 'utf8'); const cxCommandOutput = new CxCommandOutput(); // Need to check if file output is json or html - if(fileExtension.includes("json")){ + if (fileExtension.includes("json")) { const read_json = JSON.parse(read.replace(/:([0-9]{15,}),/g, ':"$1",')); - if (read_json.results){ - const r : CxResult[] = read_json.results.map((member:any)=>{ - const cxScaPackageData = new CxScaPackageData(member.data.scaPackageData?.id,member.data.scaPackageData?.locations,member.data.scaPackageData?.dependencyPaths,member.data.scaPackageData?.outdated,member.data.scaPackageData?.fixLink,member.data.scaPackageData?.supportsQuickFix,member.data.scaPackageData?.typeOfDependency); - const cvss = new CxCvss(member.vulnerabilityDetails.cvss.version,member.vulnerabilityDetails.cvss.attackVector,member.vulnerabilityDetails.cvss.availability,member.vulnerabilityDetails.cvss.confidentiality,member.vulnerabilityDetails.cvss.attackComplexity,member.vulnerabilityDetails.cvss.integrityImpact,member.vulnerabilityDetails.cvss.scope,member.vulnerabilityDetails.cvss.privilegesRequired,member.vulnerabilityDetails.cvss.userInteraction); - const cxVulnerabilityDetails = new CxVulnerabilityDetails(member.vulnerabilityDetails.cweId,cvss,member.vulnerabilityDetails.compliances,member.vulnerabilityDetails.cvssScore,member.vulnerabilityDetails.cveName); - const nodes:CxNode[]=member.data.nodes?.map((node:any)=>{ - return new CxNode(node.id,node.line,node.name,node.column,node.length,node.method,node.nodeID,node.domType,node.fileName,node.fullName,node.typeName,node.methodLine,node.definitions) + if (read_json.results) { + const r: CxResult[] = read_json.results.map((member: any) => { + const cxScaPackageData = new CxScaPackageData(member.data.scaPackageData?.id, member.data.scaPackageData?.locations, member.data.scaPackageData?.dependencyPaths, member.data.scaPackageData?.outdated, member.data.scaPackageData?.fixLink, member.data.scaPackageData?.supportsQuickFix, member.data.scaPackageData?.typeOfDependency); + const cvss = new CxCvss(member.vulnerabilityDetails.cvss.version, member.vulnerabilityDetails.cvss.attackVector, member.vulnerabilityDetails.cvss.availability, member.vulnerabilityDetails.cvss.confidentiality, member.vulnerabilityDetails.cvss.attackComplexity, member.vulnerabilityDetails.cvss.integrityImpact, member.vulnerabilityDetails.cvss.scope, member.vulnerabilityDetails.cvss.privilegesRequired, member.vulnerabilityDetails.cvss.userInteraction); + const cxVulnerabilityDetails = new CxVulnerabilityDetails(member.vulnerabilityDetails.cweId, cvss, member.vulnerabilityDetails.compliances, member.vulnerabilityDetails.cvssScore, member.vulnerabilityDetails.cveName); + const nodes: CxNode[] = member.data.nodes?.map((node: any) => { + return new CxNode(node.id, node.line, node.name, node.column, node.length, node.method, node.nodeID, node.domType, node.fileName, node.fullName, node.typeName, node.methodLine, node.definitions) }); - const cxPackageData:CxPackageData[]=member.data.packageData?.map((packages:any)=>{ - return new CxPackageData(packages.comment,packages.type,packages.url); + const cxPackageData: CxPackageData[] = member.data.packageData?.map((packages: any) => { + return new CxPackageData(packages.comment, packages.type, packages.url); }); - const data = new CxData(cxPackageData,member.data.packageIdentifier,cxScaPackageData,member.data.queryId,member.data.queryName,member.data.group,member.data.resultHash,member.data.languageName,nodes,member.data.recommendedVersion); - return new CxResult(member.type,member.label,member.id,member.status,member.alternateId,member.similarityId,member.state,member.severity,member.created,member.firstFoundAt,member.foundAt,member.firstScanId,member.description,data,member.comments,cxVulnerabilityDetails, member.descriptionHTML); + const data = new CxData(cxPackageData, member.data.packageIdentifier, cxScaPackageData, member.data.queryId, member.data.queryName, member.data.group, member.data.resultHash, member.data.languageName, nodes, member.data.recommendedVersion); + return new CxResult(member.type, member.label, member.id, member.status, member.alternateId, member.similarityId, member.state, member.severity, member.created, member.firstFoundAt, member.foundAt, member.firstScanId, member.description, data, member.comments, cxVulnerabilityDetails, member.descriptionHTML); }); cxCommandOutput.payload = r; - } - else{ + } else { cxCommandOutput.exitCode = 1; cxCommandOutput.status = "Error in the json file." } } // In case of html output - else{ - const html_arrray:string[] = [] + else { + const html_arrray: string[] = [] html_arrray.push(read) cxCommandOutput.payload = html_arrray; } From f4cba6420d644f4e936f3f0196979af726e2166b Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:27:02 +0300 Subject: [PATCH 3/6] Add severity property to CxSecretsResult for enhanced secrets scanning details --- src/main/secrets/CxSecrets.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/secrets/CxSecrets.ts b/src/main/secrets/CxSecrets.ts index 593b3799..513b9f53 100644 --- a/src/main/secrets/CxSecrets.ts +++ b/src/main/secrets/CxSecrets.ts @@ -14,6 +14,7 @@ export default class CxSecretsResult { secretsResult.title = member.Title; secretsResult.description = member.Description; secretsResult.filepath = member.FilePath; + secretsResult.severity = member.Severity; secretsResult.locations = Array.isArray(member.Locations) ? member.Locations.map((l: any) => ({ line: l.Line, @@ -27,6 +28,7 @@ export default class CxSecretsResult { const secretsResult = new CxSecretsResult(); secretsResult.title = results.Title; secretsResult.description = results.Description; + secretsResult.severity = results.Severity; secretsResult.filepath = results.FilePath; secretsResult.filepath = results.FilePath; secretsResult.locations = Array.isArray(results.Locations) From 34d0cf26fe0b22489a5ee46f14b70e0f5e39b6cd Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:35:49 +0300 Subject: [PATCH 4/6] Refactor CxSecrets parsing logic to handle resultObject directly for improved clarity --- src/main/secrets/CxSecrets.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/secrets/CxSecrets.ts b/src/main/secrets/CxSecrets.ts index 513b9f53..3c1dd557 100644 --- a/src/main/secrets/CxSecrets.ts +++ b/src/main/secrets/CxSecrets.ts @@ -6,10 +6,9 @@ export default class CxSecretsResult { locations: { line: number, startIndex: number, endIndex: number }[]; static parseResult(resultObject: any): CxSecretsResult[] { - const results = resultObject.Packages; let secretsResults: CxSecretsResult[] = []; - if (results instanceof Array) { - secretsResults = results.map((member: any) => { + if (resultObject instanceof Array) { + secretsResults = resultObject.map((member: any) => { const secretsResult = new CxSecretsResult(); secretsResult.title = member.Title; secretsResult.description = member.Description; @@ -26,13 +25,13 @@ export default class CxSecretsResult { }); } else { const secretsResult = new CxSecretsResult(); - secretsResult.title = results.Title; - secretsResult.description = results.Description; - secretsResult.severity = results.Severity; - secretsResult.filepath = results.FilePath; - secretsResult.filepath = results.FilePath; - secretsResult.locations = Array.isArray(results.Locations) - ? results.Locations.map((l: any) => ({ + secretsResult.title = resultObject.Title; + secretsResult.description = resultObject.Description; + secretsResult.severity = resultObject.Severity; + secretsResult.filepath = resultObject.FilePath; + secretsResult.filepath = resultObject.FilePath; + secretsResult.locations = Array.isArray(resultObject.Locations) + ? resultObject.Locations.map((l: any) => ({ line: l.Line, startIndex: l.StartIndex, endIndex: l.EndIndex, From ac938ed18b677443155f6960c94a57ac671e9362 Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 15:05:44 +0300 Subject: [PATCH 5/6] Fix command constants in ossScanResults and secretsScanResults methods; update test case for secrets scanning --- src/main/wrapper/CxWrapper.ts | 4 ++-- src/tests/ScanTest.test.ts | 4 ++-- src/tests/data/secret-exposed.txt | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 src/tests/data/secret-exposed.txt diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index c814a09d..2ab25729 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -150,14 +150,14 @@ export class CxWrapper { } async ossScanResults(sourceFile: string): Promise { - const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_SECRETS, CxConstants.SOURCE, sourceFile]; + const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_OSS, CxConstants.SOURCE, sourceFile]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_OSS); } async secretsScanResults(sourceFile: string): Promise { - const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_OSS, CxConstants.SOURCE, sourceFile]; + const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_SECRETS, CxConstants.SOURCE, sourceFile]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_SECRETS); diff --git a/src/tests/ScanTest.test.ts b/src/tests/ScanTest.test.ts index 725c6dff..412431e9 100644 --- a/src/tests/ScanTest.test.ts +++ b/src/tests/ScanTest.test.ts @@ -182,9 +182,9 @@ describe("ScanCreate cases", () => { expect(cxCommandOutput.exitCode).toBe(0); }); - it.skip('ScanSecrets Successful case', async () => { + it('ScanSecrets Successful case', async () => { const wrapper = new CxWrapper(cxScanConfig); - const cxCommandOutput: CxCommandOutput = await wrapper.secretsScanResults("tsc/tests/data/package.json"); + const cxCommandOutput: CxCommandOutput = await wrapper.secretsScanResults("tsc/tests/data/secret-exposed.txt"); console.log("Json object from scanOSS successful case: " + JSON.stringify(cxCommandOutput)); expect(cxCommandOutput.payload).toBeDefined(); expect(cxCommandOutput.exitCode).toBe(0); diff --git a/src/tests/data/secret-exposed.txt b/src/tests/data/secret-exposed.txt new file mode 100644 index 00000000..95be79fb --- /dev/null +++ b/src/tests/data/secret-exposed.txt @@ -0,0 +1,5 @@ +package data + +const ( + pat = "ghp_1234567890abcdef1234567890abcdef12345678" +) From 3f65619b71b2294d82e7f6d6dde4c59c89040e7b Mon Sep 17 00:00:00 2001 From: cx-ben-alvo <144705560+cx-ben-alvo@users.noreply.github.com> Date: Mon, 9 Jun 2025 15:11:07 +0300 Subject: [PATCH 6/6] Skip successful case test for ScanSecrets in ScanTest --- src/tests/ScanTest.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/ScanTest.test.ts b/src/tests/ScanTest.test.ts index 412431e9..0c9221d7 100644 --- a/src/tests/ScanTest.test.ts +++ b/src/tests/ScanTest.test.ts @@ -182,7 +182,7 @@ describe("ScanCreate cases", () => { expect(cxCommandOutput.exitCode).toBe(0); }); - it('ScanSecrets Successful case', async () => { + it.skip('ScanSecrets Successful case', async () => { const wrapper = new CxWrapper(cxScanConfig); const cxCommandOutput: CxCommandOutput = await wrapper.secretsScanResults("tsc/tests/data/secret-exposed.txt"); console.log("Json object from scanOSS successful case: " + JSON.stringify(cxCommandOutput));