diff --git a/scanners/angularjs-csti-scanner/parser/__testFiles__/acstis-test-empty-findings.txt.license b/scanners/angularjs-csti-scanner/parser/__testFiles__/acstis-test-empty-findings.txt.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/angularjs-csti-scanner/parser/__testFiles__/acstis-test-empty-findings.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/angularjs-csti-scanner/parser/parser.js b/scanners/angularjs-csti-scanner/parser/parser.js index c6bf7d1ab5..74e4d007b8 100644 --- a/scanners/angularjs-csti-scanner/parser/parser.js +++ b/scanners/angularjs-csti-scanner/parser/parser.js @@ -43,7 +43,6 @@ function parseMethod(line) { } function parseUrl(line) { - console.log(line) return line.match(/http[s]?:\/\/[^\n ]+/g)[0] } diff --git a/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json b/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json @@ -0,0 +1,2 @@ +[ +] diff --git a/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json.license b/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/git-repo-scanner/parser/__testFiles__/empty-findings.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/git-repo-scanner/parser/parser.test.js b/scanners/git-repo-scanner/parser/parser.test.js index ffde867b80..066ab2138f 100644 --- a/scanners/git-repo-scanner/parser/parser.test.js +++ b/scanners/git-repo-scanner/parser/parser.test.js @@ -13,6 +13,18 @@ const readFile = util.promisify(fs.readFile); const { parse } = require("./parser"); +test("should properly parse empty json file", async () => { + const fileContent = await readFile( + __dirname + "/__testFiles__/empty-findings.json", + { + encoding: "utf8", + } + ); + const findings = await parse(JSON.parse(fileContent)); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot(`Array []`); +}); + test("should properly parse git-scanner json file", async () => { const fileContent = await readFile( __dirname + "/__testFiles__/git-scanner-test-findings.json", diff --git a/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json b/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json.license b/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/kube-hunter/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/kube-hunter/parser/parser.test.js b/scanners/kube-hunter/parser/parser.test.js index eb58277299..2f1233c9de 100644 --- a/scanners/kube-hunter/parser/parser.test.js +++ b/scanners/kube-hunter/parser/parser.test.js @@ -26,3 +26,15 @@ test("parses result from kind-1.18-in-cluster-scan correctly", async () => { await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchSnapshot(); }); + +test("should properly parse empty kube-hunter json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/kubeaudit/parser/__snapshots__/parser.test.js.snap b/scanners/kubeaudit/parser/__snapshots__/parser.test.js.snap index ab3b0171b7..1c08ee311f 100644 --- a/scanners/kubeaudit/parser/__snapshots__/parser.test.js.snap +++ b/scanners/kubeaudit/parser/__snapshots__/parser.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`example parser parses empty json to zero findings 1`] = ` +exports[`should properly parse kubeaudit juice-shop results 1`] = ` Array [ Object { "attributes": Object {}, diff --git a/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl b/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl @@ -0,0 +1 @@ +[] diff --git a/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl.license b/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/kubeaudit/parser/__testFiles__/test-empty-report.jsonl.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/kubeaudit/parser/parser.test.js b/scanners/kubeaudit/parser/parser.test.js index 297cabfe30..528fd3deea 100644 --- a/scanners/kubeaudit/parser/parser.test.js +++ b/scanners/kubeaudit/parser/parser.test.js @@ -13,7 +13,7 @@ const readFile = util.promisify(fs.readFile); const { parse } = require("./parser"); -test("example parser parses empty json to zero findings", async () => { +test("should properly parse kubeaudit juice-shop results", async () => { const fileContent = await readFile( __dirname + "/__testFiles__/juice-shop.jsonl", { @@ -25,3 +25,15 @@ test("example parser parses empty json to zero findings", async () => { expect(findings).toMatchSnapshot(); }); + +test("should properly parse empty kubeaudit jsonl file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.jsonl", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/nikto/parser/__testFiles__/test-empty-report.json b/scanners/nikto/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/nikto/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/nikto/parser/__testFiles__/test-empty-report.json.license b/scanners/nikto/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/nikto/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/nikto/parser/parser.js b/scanners/nikto/parser/parser.js index f0b0c776f6..07095903ee 100644 --- a/scanners/nikto/parser/parser.js +++ b/scanners/nikto/parser/parser.js @@ -44,6 +44,9 @@ function categorize({ id }) { async function parse({ host, ip, port: portString, banner, vulnerabilities }) { const port = parseInt(portString, 10); + if (!vulnerabilities) // empty file + return []; + return vulnerabilities.filter(Boolean).map(({ id, method, url, msg }) => { const niktoId = parseInt(id, 10); diff --git a/scanners/nikto/parser/parser.test.js b/scanners/nikto/parser/parser.test.js index 7bfe10e237..1e16e5179f 100644 --- a/scanners/nikto/parser/parser.test.js +++ b/scanners/nikto/parser/parser.test.js @@ -34,3 +34,15 @@ test("parses OWASP Juice Shop result file into findings", async () => { await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchSnapshot(); }); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/screenshooter/parser/parser.test.js b/scanners/screenshooter/parser/parser.test.js index dae94854f5..75f31f1ae9 100644 --- a/scanners/screenshooter/parser/parser.test.js +++ b/scanners/screenshooter/parser/parser.test.js @@ -47,7 +47,7 @@ test("should create finding correctly", async () => { test("should not create finding if image is empty", async () => { scan.spec.parameters = ["https://www.iteratec.de"]; - findings = await parse("", scan) + const findings = await parse("", scan) await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchInlineSnapshot(`Array []`); }); diff --git a/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json b/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json.license b/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/ssh-scan/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/ssh-scan/parser/parser.js b/scanners/ssh-scan/parser/parser.js index e7336b3c18..5c70e9e1bf 100644 --- a/scanners/ssh-scan/parser/parser.js +++ b/scanners/ssh-scan/parser/parser.js @@ -138,6 +138,9 @@ function transformRecommendationToFinding( async function parse(fileContent) { const hosts = fileContent; + if (typeof(hosts) === "string") // empty file + return []; + return hosts .flatMap(host => { if (host.error) { diff --git a/scanners/ssh-scan/parser/parser.test.js b/scanners/ssh-scan/parser/parser.test.js index ff5926d31e..68eaa7884e 100644 --- a/scanners/ssh-scan/parser/parser.test.js +++ b/scanners/ssh-scan/parser/parser.test.js @@ -272,3 +272,15 @@ test("ssh-scan parser parses a result of a network without ssh hosts correctly", await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchInlineSnapshot(`Array []`); }); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/sslyze/parser/__testFiles__/test-empty-report.json b/scanners/sslyze/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/sslyze/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/sslyze/parser/__testFiles__/test-empty-report.json.license b/scanners/sslyze/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/sslyze/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/sslyze/parser/parser.js b/scanners/sslyze/parser/parser.js index 16178952a0..9a1209d8a0 100644 --- a/scanners/sslyze/parser/parser.js +++ b/scanners/sslyze/parser/parser.js @@ -4,7 +4,7 @@ function parse(fileContent) { // Only 0 when the target wasn't reachable - if (fileContent.server_scan_results.length === 0) { + if (!fileContent.server_scan_results || fileContent.server_scan_results.length === 0) { return []; } diff --git a/scanners/sslyze/parser/parser.test.js b/scanners/sslyze/parser/parser.test.js index 9768619c15..9f905f4325 100644 --- a/scanners/sslyze/parser/parser.test.js +++ b/scanners/sslyze/parser/parser.test.js @@ -423,3 +423,15 @@ test("parses an result file with mixed connectivity correctly", async () => { await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toEqual([]); }); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/trivy/parser/__testFiles__/test-empty-report.json b/scanners/trivy/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/trivy/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/trivy/parser/__testFiles__/test-empty-report.json.license b/scanners/trivy/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/trivy/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/trivy/parser/parser.js b/scanners/trivy/parser/parser.js index 0218f11ae4..5a09d75212 100644 --- a/scanners/trivy/parser/parser.js +++ b/scanners/trivy/parser/parser.js @@ -5,24 +5,17 @@ async function parse(scanResults) { // The first scan always contains the image id a similar format to: "bkimminich/juice-shop:v10.2.0 (alpine 3.11.5)" const [imageScanResult] = scanResults; + + if (typeof(imageScanResult) === "string") // empty file + return []; + const [imageId] = imageScanResult.Target.split(" ", 2); const findings = []; for (const { Target: target, Vulnerabilities } of scanResults) { const vulnerabilities = Vulnerabilities || []; - let category = "Image Vulnerability"; - if (target.endsWith("package-lock.json")) { - category = "NPM Package Vulnerability"; - } else if (target.endsWith("Gemfile.lock")) { - category = "Ruby Package Vulnerability"; - } else if (target.endsWith("Pipfile.lock")) { - category = "Python Package Vulnerability"; - } else if (target.endsWith("Cargo.lock")) { - category = "Python Package Vulnerability"; - } else if (target.endsWith("Composer.lock")) { - category = "PHP Package Vulnerability"; - } + const category = getCategory(target); for (const vulnerability of vulnerabilities) { let reference = null; @@ -57,10 +50,25 @@ async function parse(scanResults) { }); } } - return findings; } +function getCategory(target) { + let category = "Image Vulnerability"; + if (target.endsWith("package-lock.json")) { + category = "NPM Package Vulnerability"; + } else if (target.endsWith("Gemfile.lock")) { + category = "Ruby Package Vulnerability"; + } else if (target.endsWith("Pipfile.lock")) { + category = "Python Package Vulnerability"; + } else if (target.endsWith("Cargo.lock")) { + category = "Python Package Vulnerability"; + } else if (target.endsWith("Composer.lock")) { + category = "PHP Package Vulnerability"; + } + return category; +} + function getAdjustedSeverity(severity){ return severity === "CRITICAL" ? "HIGH" diff --git a/scanners/trivy/parser/parser.test.js b/scanners/trivy/parser/parser.test.js index 83e43bb058..4418e9fdf9 100644 --- a/scanners/trivy/parser/parser.test.js +++ b/scanners/trivy/parser/parser.test.js @@ -85,3 +85,15 @@ test("parses mediawiki:1.27.3 result file into findings", async () => { await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchSnapshot(); }); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +}); diff --git a/scanners/typo3scan/parser/__testFiles__/test-empty-report.json b/scanners/typo3scan/parser/__testFiles__/test-empty-report.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/scanners/typo3scan/parser/__testFiles__/test-empty-report.json @@ -0,0 +1 @@ +[] diff --git a/scanners/typo3scan/parser/__testFiles__/test-empty-report.json.license b/scanners/typo3scan/parser/__testFiles__/test-empty-report.json.license new file mode 100644 index 0000000000..c59b85a5b5 --- /dev/null +++ b/scanners/typo3scan/parser/__testFiles__/test-empty-report.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2021 iteratec GmbH + +SPDX-License-Identifier: Apache-2.0 diff --git a/scanners/typo3scan/parser/parser.js b/scanners/typo3scan/parser/parser.js index 87916ed93f..f340e12239 100644 --- a/scanners/typo3scan/parser/parser.js +++ b/scanners/typo3scan/parser/parser.js @@ -10,6 +10,8 @@ async function parse(findings) { const domain_findings = findings[domain] const vulns = domain_findings.Vulnerabilities + if(!vulns) // empty file + return []; // Parsing Vulnerabilities const parsed_vulnerabilities = vulns.map((vuln) => { return { @@ -60,4 +62,4 @@ async function parse(findings) { }); return results } -module.exports.parse = parse; \ No newline at end of file +module.exports.parse = parse; diff --git a/scanners/typo3scan/parser/parser.test.js b/scanners/typo3scan/parser/parser.test.js index 23737e38d4..b450621275 100644 --- a/scanners/typo3scan/parser/parser.test.js +++ b/scanners/typo3scan/parser/parser.test.js @@ -20,7 +20,6 @@ test("parser parses large json result without vulnerable extensions successfully encoding: "utf8", } ); - const findings = await parse(JSON.parse(fileContent)); await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchSnapshot(); @@ -33,8 +32,19 @@ test("parser parses large json result with vulnerable extensions successfully", encoding: "utf8", } ); - const findings = await parse(JSON.parse(fileContent)); await expect(validateParser(findings)).resolves.toBeUndefined(); expect(findings).toMatchSnapshot(); -}); \ No newline at end of file +}); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/test-empty-report.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot(`Array []`); +}); diff --git a/scanners/wpscan/parser/parser.js b/scanners/wpscan/parser/parser.js index 284952b69d..0a1bb23147 100644 --- a/scanners/wpscan/parser/parser.js +++ b/scanners/wpscan/parser/parser.js @@ -6,6 +6,9 @@ * Convert the WPScan file / json into secureCodeBox Findings */ async function parse(scanResults) { + if (typeof(scanResults) === "string") // empty file + return []; + const wpscanVersion = scanResults.banner.version; const wpscanRequestsDone = scanResults.requests_done; diff --git a/scanners/wpscan/parser/parser.test.js b/scanners/wpscan/parser/parser.test.js index fec9160e25..3c4067651f 100644 --- a/scanners/wpscan/parser/parser.test.js +++ b/scanners/wpscan/parser/parser.test.js @@ -262,3 +262,15 @@ test("WPScan parser parses a scan result file without a detected wp version corr ] `); }); + +test("should properly parse empty json file", async () => { + const jsonContent = await readFile( + __dirname + "/__testFiles__/empty-localhost.json", + { + encoding: "utf8", + } + ); + const findings = await parse(jsonContent); + await expect(validateParser(findings)).resolves.toBeUndefined(); + expect(findings).toMatchInlineSnapshot("Array []"); +});