From 041c0fcaf11d5b2571beb6e489c4d9d8ef3e244d Mon Sep 17 00:00:00 2001 From: Itay Paz Date: Tue, 5 Aug 2025 12:22:55 +0300 Subject: [PATCH] Support ignore in asca iac and contanires plus tests --- src/main/wrapper/CxWrapper.ts | 100 +++++++++++++------ src/tests/ScanTest.test.ts | 72 ++++++++++++- src/tests/data/ignoredIacContainersAsca.json | 17 ++++ 3 files changed, 159 insertions(+), 30 deletions(-) create mode 100644 src/tests/data/ignoredIacContainersAsca.json diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index 34840fa6..32fa485f 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -127,28 +127,39 @@ export class CxWrapper { return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_TYPE); } - async scanAsca(sourceFile: string, updateVersion = false, agent?: string | null): Promise { - const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_ASCA, CxConstants.SOURCE_FILE, sourceFile]; + async scanAsca( + sourceFile: string, + updateVersion = false, + agent?: string | null, + ignoredFilePath?: string +): Promise { + const commands: string[] = [ + CxConstants.CMD_SCAN, + CxConstants.CMD_ASCA, + CxConstants.SOURCE_FILE, + sourceFile + ]; - if (updateVersion) { - commands.push(CxConstants.ASCA_UPDATE_VERSION); - } - if (agent) { - commands.push(CxConstants.AGENT); - commands.push(agent); - } - else { - commands.push(CxConstants.AGENT); - // if we don't send any parameter in the flag - // then in the cli takes the default and this is not true - commands.push('"js-wrapper"'); - } + if (updateVersion) { + commands.push(CxConstants.ASCA_UPDATE_VERSION); + } - commands.push(...this.initializeCommands(false)); - const exec = new ExecutionService(); - return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_ASCA); + if (agent) { + commands.push(CxConstants.AGENT, agent); + } else { + commands.push(CxConstants.AGENT, '"js-wrapper"'); } + if (ignoredFilePath) { + commands.push(CxConstants.IGNORE__FILE_PATH, ignoredFilePath); + } + + commands.push(...this.initializeCommands(false)); + + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_ASCA); +} + async ossScanResults(sourceFile: string, ignoredFilePath?: string): Promise { const commands: string[] = [ CxConstants.CMD_SCAN, @@ -168,20 +179,53 @@ export class CxWrapper { return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_OSS); } - async containersRealtimeScanResults(sourceFile: string): Promise { - const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_CONTAINERS_REALTIME, CxConstants.SOURCE, sourceFile]; - commands.push(...this.initializeCommands(false)); - const exec = new ExecutionService(); - return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_CONTAINERS_REALTIME); + async containersRealtimeScanResults( + sourceFile: string, + ignoredFilePath?: string +): Promise { + const commands: string[] = [ + CxConstants.CMD_SCAN, + CxConstants.CMD_CONTAINERS_REALTIME, + CxConstants.SOURCE, + sourceFile + ]; + + if (ignoredFilePath) { + commands.push(CxConstants.IGNORE__FILE_PATH); + commands.push(ignoredFilePath); } - async iacRealtimeScanResults(sourceFile: string, engine: string): Promise { - const commands: string[] = [CxConstants.CMD_SCAN, CxConstants.CMD_IAC_REALTIME, CxConstants.SOURCE, sourceFile, CxConstants.ENGINE, engine]; - commands.push(...this.initializeCommands(false)); - const exec = new ExecutionService(); - return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_IAC); + commands.push(...this.initializeCommands(false)); + + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_CONTAINERS_REALTIME); +} + + async iacRealtimeScanResults( + sourceFile: string, + engine: string, + ignoredFilePath?: string +): Promise { + const commands: string[] = [ + CxConstants.CMD_SCAN, + CxConstants.CMD_IAC_REALTIME, + CxConstants.SOURCE, + sourceFile, + CxConstants.ENGINE, + engine + ]; + + if (ignoredFilePath) { + commands.push(CxConstants.IGNORE__FILE_PATH); + commands.push(ignoredFilePath); } + commands.push(...this.initializeCommands(false)); + + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.SCAN_IAC); +} + async secretsScanResults(sourceFile: string, ignoredFilePath?: string): Promise { const commands: string[] = [ CxConstants.CMD_SCAN, diff --git a/src/tests/ScanTest.test.ts b/src/tests/ScanTest.test.ts index 2ddd9cda..7ec12696 100644 --- a/src/tests/ScanTest.test.ts +++ b/src/tests/ScanTest.test.ts @@ -3,6 +3,9 @@ import { CxCommandOutput } from "../main/wrapper/CxCommandOutput"; import { CxParamType } from "../main/wrapper/CxParamType"; import { BaseTest } from "./BaseTest"; import {OssPackage} from "./data/ossTypes"; +import CxIacResult from "../main/iacRealtime/CxIac"; +import CxContainerRealtimeResult from "../main/containersRealtime/CxContainerRealtime"; +import CxAsca from '../main/asca/CxAsca'; describe("ScanCreate cases", () => { const cxScanConfig = new BaseTest(); @@ -229,7 +232,7 @@ describe("ScanCreate cases", () => { it('ScanContainersRealtime Successful case', async () => { const wrapper = new CxWrapper(cxScanConfig); - const cxCommandOutput: CxCommandOutput = await wrapper.containersRealtimeScanResults("src/tests/data/Dockerfile"); + const cxCommandOutput: CxCommandOutput = await wrapper.containersRealtimeScanResults("src/tests/data/Dockerfile", ""); console.log("Json object from scanContainersRealtime successful case: " + JSON.stringify(cxCommandOutput)); expect(cxCommandOutput.payload).toBeDefined(); expect(cxCommandOutput.exitCode).toBe(0); @@ -237,11 +240,76 @@ describe("ScanCreate cases", () => { it.skip('ScanIacRealtime Successful case', async () => { const wrapper = new CxWrapper(cxScanConfig); - const cxCommandOutput: CxCommandOutput = await wrapper.iacRealtimeScanResults("src/tests/data/Dockerfile", "docker"); + const cxCommandOutput: CxCommandOutput = await wrapper.iacRealtimeScanResults("src/tests/data/Dockerfile", "docker",""); console.log("Json object from scanIacRealtime successful case: " + JSON.stringify(cxCommandOutput)); expect(cxCommandOutput.payload).toBeDefined(); expect(cxCommandOutput.exitCode).toBe(0); }); + + + it.skip('ScanIacRealtime with ignore file should filter results', async () => { + const wrapper = new CxWrapper(cxScanConfig); + const sourceFile = "src/tests/data/Dockerfile"; + const ignoredFile = "src/tests/data/ignoredIacContainersAsca"; + + const cxCommandOutput: CxCommandOutput = await wrapper.iacRealtimeScanResults(sourceFile, "docker", ignoredFile); + + expect(cxCommandOutput.exitCode).toBe(0); + expect(cxCommandOutput.payload).toBeDefined(); + + const findings = CxIacResult.parseResult(cxCommandOutput.payload); + + console.log("Filtered IAC findings:", findings); + + expect(findings.length).toBe(3); +}); + + +it.skip('ScanContainersRealtime with ignored image should filter result', async () => { + const wrapper = new CxWrapper(cxScanConfig); + const sourceFile = "tsc/tests/data/Dockerfile"; + const ignoredFile = "tsc/tests/data/ignoredIacContainersAsca.json"; + + const cxCommandOutput: CxCommandOutput = await wrapper.containersRealtimeScanResults(sourceFile, ignoredFile); + + expect(cxCommandOutput.exitCode).toBe(0); + expect(cxCommandOutput.payload).toBeDefined(); + + const parsedResults = CxContainerRealtimeResult.parseResult(cxCommandOutput.payload[0]); + + console.log("Filtered container results:", parsedResults); + + expect(parsedResults.length).toBe(0); +}); + +it.skip('ScanAsca with ignore file should filter one result', async () => { + const wrapper = new CxWrapper(cxScanConfig); + + const sourcePath = "tsc/tests/data/python-vul-file.py"; + const ignoreFile = "tsc/tests/data/ignoredIacContainersAsca.json"; + + const cxCommandOutput: CxCommandOutput = await wrapper.scanAsca( + sourcePath, + false, + null, + ignoreFile + ); + + expect(cxCommandOutput.exitCode).toBe(0); + expect(cxCommandOutput.payload).toBeDefined(); + + const parsed = CxAsca.parseScan(cxCommandOutput.payload[0]); + console.log("Filtered ASCA results:", parsed.scanDetails); + + expect(parsed.status).toBe(true); + expect(Array.isArray(parsed.scanDetails)).toBe(true); + + + expect(parsed.scanDetails.length).toBe(5); +}); + + + }); diff --git a/src/tests/data/ignoredIacContainersAsca.json b/src/tests/data/ignoredIacContainersAsca.json new file mode 100644 index 00000000..d3b3725a --- /dev/null +++ b/src/tests/data/ignoredIacContainersAsca.json @@ -0,0 +1,17 @@ +[ + { + "FilePath": "src/tests/data/Dockerfile", + "SimilarityID": "204fc29cbec21db48abe962c6ede10cfeced76de22128c5ffdde928f3a0455d3", + "Title": "APT-GET Missing Flags To Avoid Manual Input" + }, + { + "ImageName": "openjdk", + "ImageTag": "11.0.1-jre-slim-stretch", + "FilePath": "Dockerfile" + }, + { + "FileName": "python-vul-file.py", + "Line": 56, + "RuleID": 4009 + } +] \ No newline at end of file