diff --git a/src/main/java/com/jfrog/ide/idea/inspections/JFrogSecurityWarning.java b/src/main/java/com/jfrog/ide/idea/inspections/JFrogSecurityWarning.java index 37e8b60e..110b6bda 100644 --- a/src/main/java/com/jfrog/ide/idea/inspections/JFrogSecurityWarning.java +++ b/src/main/java/com/jfrog/ide/idea/inspections/JFrogSecurityWarning.java @@ -62,7 +62,7 @@ public JFrogSecurityWarning(SarifResult result, SourceCodeScanType reporter, Rul result.getRuleId(), getFirstRegion(result).getSnippet().getText(), reporter, - (!result.getKind().equals("pass") && (rule.getRuleProperties().map(properties -> !properties.getApplicability().equals("not_applicable")).orElse(true))), + (!result.getKind().equals("pass") && (rule.getRuleProperties().map(properties -> properties.getApplicability().equals("applicable")).orElse(true))), Severity.fromSarif(result.getSeverity()), convertCodeFlowsToFindingInfo(result.getCodeFlows()) ); @@ -114,3 +114,4 @@ private static String uriToPath(String path) { return Paths.get(URI.create(path)).toString(); } } + diff --git a/src/main/java/com/jfrog/ide/idea/scan/data/Driver.java b/src/main/java/com/jfrog/ide/idea/scan/data/Driver.java index 74a1dcf7..22a4347b 100644 --- a/src/main/java/com/jfrog/ide/idea/scan/data/Driver.java +++ b/src/main/java/com/jfrog/ide/idea/scan/data/Driver.java @@ -48,4 +48,12 @@ public boolean equals(Object other) { return (Objects.equals(this.name, rhs.name) && (CollectionUtils.isEqualCollection(this.rules, rhs.rules))); } + public Rule getRuleById(String ruleId) { + return rules.stream() + .filter(rule -> rule.getId().equals(ruleId)) + .findFirst() + .orElseThrow(() -> new IndexOutOfBoundsException("Rule not found")); + } + + } diff --git a/src/main/java/com/jfrog/ide/idea/scan/data/Run.java b/src/main/java/com/jfrog/ide/idea/scan/data/Run.java index 683fec56..71b32e76 100644 --- a/src/main/java/com/jfrog/ide/idea/scan/data/Run.java +++ b/src/main/java/com/jfrog/ide/idea/scan/data/Run.java @@ -40,12 +40,7 @@ public List getResults() { } public Rule getRuleFromRunById(String ruleId) { - List rules = this.getTool().getDriver().getRules(); - return rules.stream() - .filter(rule -> rule.getId().equals(ruleId)) - .findFirst() - .orElseThrow(() -> new NoSuchElementException("No rule found with id: " + ruleId)); - + return this.getTool().getDriver().getRuleById(ruleId); } public void setResults(List results) { diff --git a/src/test/java/com/jfrog/ide/idea/scan/ScanBinaryExecutorTest.java b/src/test/java/com/jfrog/ide/idea/scan/ScanBinaryExecutorTest.java index d3d92125..918ab813 100644 --- a/src/test/java/com/jfrog/ide/idea/scan/ScanBinaryExecutorTest.java +++ b/src/test/java/com/jfrog/ide/idea/scan/ScanBinaryExecutorTest.java @@ -23,7 +23,7 @@ public class ScanBinaryExecutorTest extends TestCase { private final ScanBinaryExecutor scanner = new ApplicabilityScannerExecutor(new NullLog()); private final Path SIMPLE_OUTPUT = new File("src/test/resources/sourceCode/simple_output.sarif").toPath(); private final Path NOT_APPLIC_OUTPUT = new File("src/test/resources/sourceCode/not_applic_output.sarif").toPath(); - private final Path NOT_APPLIC_KIND_PASS_OUTPUT = new File("src/test/resources/sourceCode/not_applic_kind_pass.sarif").toPath(); + private final Path APPLIC_KIND_PASS_OUTPUT = new File("src/test/resources/sourceCode/applicable_kind_pass_output.sarif").toPath(); public void testInputBuilder() throws IOException { ScanConfig.Builder inputFileBuilder = new ScanConfig.Builder(); Path inputPath = null; @@ -85,12 +85,14 @@ public void testSarifParserNotApplicResults() throws IOException { assertFalse(parsedOutput.get(3).isApplicable()); } - public void testSarifParserNotApplicResultsButKindPass() throws IOException { - List parsedOutput = scanner.parseOutputSarif(NOT_APPLIC_KIND_PASS_OUTPUT); - assertEquals(5, parsedOutput.size()); - // 1 known applicable results (code evidence returned) + public void testSarifParserApplicResultsWithKindPass() throws IOException { + List parsedOutput = scanner.parseOutputSarif(APPLIC_KIND_PASS_OUTPUT); + assertEquals(4, parsedOutput.size()); + // 2 known applicable results (code evidence returned) assertEquals("applic_CVE-2022-25878", parsedOutput.get(0).getRuleID()); - assertTrue(parsedOutput.get(0).isApplicable()); + assertFalse(parsedOutput.get(0).isApplicable()); + assertEquals("CVE-2022-25978", parsedOutput.get(1).getRuleID()); + assertTrue(parsedOutput.get(1).isApplicable()); // 2 known no-applicable results (have a scanner but no code evidence returned) assertEquals("applic_CVE-2021-25878", parsedOutput.get(2).getRuleID()); assertFalse(parsedOutput.get(2).isApplicable()); @@ -98,6 +100,8 @@ public void testSarifParserNotApplicResultsButKindPass() throws IOException { assertFalse(parsedOutput.get(3).isApplicable()); } + + public void testGetBinaryDownloadURL() { final String externalRepoName = "test-releases-repo"; final String expectedExternalRepoUrl = "test-releases-repo/artifactory/xsc-gen-exe-analyzer-manager-local/"; diff --git a/src/test/resources/sourceCode/applicable_kind_pass_output.sarif b/src/test/resources/sourceCode/applicable_kind_pass_output.sarif new file mode 100644 index 00000000..97b8094a --- /dev/null +++ b/src/test/resources/sourceCode/applicable_kind_pass_output.sarif @@ -0,0 +1,140 @@ +{ + "runs": [ + { + "tool": { + "driver": { + "name": "JFrog Applicability Scanner", + "rules": [ + { + "id": "applic_CVE-2022-25878", + "properties": { + "conclusion": "positive", + "applicability": "not_applicable" + }, + "fullDescription": { + "text": "The scanner checks whether the vulnerable function `pem.Decode` is called.", + "markdown": "The scanner checks whether the vulnerable function `pem.Decode` is called." + }, + "shortDescription": { + "text": "Scanner for CVE-2020-28502" + } + }, + { + "id": "CVE-2022-25978", + "properties": { + "conclusion": "negative", + "applicability": "applicable" + }, + "fullDescription": { + "text": "The scanner checks whether the vulnerable function `org.apache.xmlbeans.XmlObject.Factory.parse` is called or an interface that extends `org.apache.xmlbeans.XmlObject` is used.", + "markdown": "The scanner checks whether the vulnerable function `org.apache.xmlbeans.XmlObject.Factory.parse` is called or an interface that extends `org.apache.xmlbeans.XmlObject` is used." + }, + "shortDescription": { + "text": "Scanner for CVE-2020-5310" + } + }, + { + "id": "applic_CVE-2021-25878", + "fullDescription": { + "text": "The scanner checks whether the vulnerable function `pem.Decode` is called.", + "markdown": "The scanner checks whether the vulnerable function `pem.Decode` is called." + }, + "shortDescription": { + "text": "Scanner for CVE-2020-28502" + } + }, + { + "id": "applic_CVE-2022-29019", + "fullDescription": { + "text": "The scanner checks whether the vulnerable function `org.apache.xmlbeans.XmlObject.Factory.parse` is called or an interface that extends `org.apache.xmlbeans.XmlObject` is used.", + "markdown": "The scanner checks whether the vulnerable function `org.apache.xmlbeans.XmlObject.Factory.parse` is called or an interface that extends `org.apache.xmlbeans.XmlObject` is used." + }, + "shortDescription": { + "text": "Scanner for CVE-2020-5310" + } + } + + ], + "version": "APPLIC_SCANNERv0.2.0" + } + }, + "invocations": [ + { + "executionSuccessful": true, + "arguments": [ + "scan" + ], + "workingDirectory": { + "uri": "" + } + } + ], + "results": [ + { + "message": { + "text": "The vulnerable function protobufjs.load is called" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///examples/applic-demo/index.js" + }, + "region": { + "endColumn": 17, + "endLine": 20, + "snippet": { + "text": "protobuf.parse(p)" + }, + "startColumn": 0, + "startLine": 20 + } + } + } + ], + "ruleId": "applic_CVE-2022-25878" + }, + { + "message": { + "text": "The vulnerable function protobufjs.parse is called." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///examples/applic-demo/index.js" + }, + "region": { + "endColumn": 73, + "endLine": 22, + "snippet": { + "text": "protobuf.load(\"/path/to/untrusted.proto\", function(err, root) { return })" + }, + "startColumn": 0, + "startLine": 18 + } + } + } + ], + "ruleId": "CVE-2022-25978" + }, + { + "message": { + "text": "The scanner checks whether the vulnerable function `ansi-regex` is called." + }, + "kind": "pass", + "ruleId": "applic_CVE-2021-25878" + }, + { + "message": { + "text": "The scanner checks whether the vulnerable function `ansi-regex` is called." + }, + "kind": "pass", + "ruleId": "applic_CVE-2022-29019" + } + ] + } + ], + "version": "2.1.0", + "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json" +} \ No newline at end of file diff --git a/src/test/resources/sourceCode/not_applic_kind_pass.sarif b/src/test/resources/sourceCode/not_applic_kind_pass.sarif deleted file mode 100644 index 5bcd82ab..00000000 --- a/src/test/resources/sourceCode/not_applic_kind_pass.sarif +++ /dev/null @@ -1,165 +0,0 @@ -{ - "runs": [ - { - "tool": { - "driver": { - "name": "JFrog Applicability Scanner", - "rules": [ - { - "id": "applic_CVE-2021-3807", - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `ansi-regex` is called.", - "markdown": "The scanner checks whether the vulnerable function `ansi-regex` is called." - }, - "name": "CVE-2021-3807", - "shortDescription": { - "text": "Scanner for CVE-2021-3807" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2021-3918", - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `util.setProperty` with external input to its 2nd (`path`) or 3rd (`value`) arguments.\n* `ReflectionObject.setParsedOption` with external input to its 2nd (`name`) or 3rd (`value`) arguments.\n* `parse` with external input to its 1st (`source`) argument.\n* `load`\n* `loadSync`\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `util.setProperty` with external input to its 2nd (`path`) or 3rd (`value`) arguments.\n* `ReflectionObject.setParsedOption` with external input to its 2nd (`name`) or 3rd (`value`) arguments.\n* `parse` with external input to its 1st (`source`) argument.\n* `load`\n* `loadSync`\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - }, - "name": "CVE-2021-3918", - "shortDescription": { - "text": "Scanner for CVE-2021-3918" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2022-25878", - "name": "CVE-2022-25878", - "shortDescription": { - "text": "Scanner for CVE-2022-25878" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `util.setProperty` with external input to its 2nd (`path`) or 3rd (`value`) arguments.\n* `ReflectionObject.setParsedOption` with external input to its 2nd (`name`) or 3rd (`value`) arguments.\n* `parse` with external input to its 1st (`source`) argument.\n* `load`\n* `loadSync`\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `util.setProperty` with external input to its 2nd (`path`) or 3rd (`value`) arguments.\n* `ReflectionObject.setParsedOption` with external input to its 2nd (`name`) or 3rd (`value`) arguments.\n* `parse` with external input to its 1st (`source`) argument.\n* `load`\n* `loadSync`\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - }, - "properties": { - "applicability": "applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - } - ], - "version": "APPLIC_SCANNERv0.2.3" - } - }, - "invocations": [ - { - "executionSuccessful": true, - "arguments": [ - "ca_scanner/applicability_scanner", - "scan", - "aplic_config.yaml" - ], - "workingDirectory": { - "uri": "file:///Users/user/.jfrog-vscode-extension/issues/analyzerManager" - } - } - ], - "results": [ - { - "message": { - "text": "Prototype pollution `Object.freeze` remediation was not detected, The vulnerable function protobufjs.parse is called with external input, The vulnerable function protobufjs.load(Sync) is called" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///examples/applic-demo/../applic-demo/index.js" - }, - "region": { - "endColumn": 18, - "endLine": 21, - "snippet": { - "text": "protobuf.parse(p)" - }, - "startColumn": 1, - "startLine": 21 - } - } - } - ], - "ruleId": "applic_CVE-2022-25878" - }, - { - "message": { - "text": "Prototype pollution `Object.freeze` remediation was not detected, The vulnerable function protobufjs.parse is called with external input, The vulnerable function protobufjs.load(Sync) is called" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///examples/applic-demo/../applic-demo/index.js" - }, - "region": { - "endColumn": 74, - "endLine": 23, - "snippet": { - "text": "protobuf.load(\"/path/to/untrusted.proto\", function(err, root) { return })" - }, - "startColumn": 1, - "startLine": 23 - } - } - } - ], - "ruleId": "applic_CVE-2022-25878" - }, - { - "message": { - "text": "Some remediation for not applicable issue." - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///examples/applic-demo/../applic-demo/index.js" - }, - "region": { - "endColumn": 1, - "endLine": 23, - "snippet": { - "text": "protobuf.load(\"/path/to/untrusted.proto\", function(err, root) { return })" - }, - "startColumn": 1, - "startLine": 1 - } - } - } - ], - "ruleId": "applic_CVE-2021-3807" - }, - { - "message": { - "text": "The scanner checks whether the vulnerable function `ansi-regex` is called." - }, - "kind": "pass", - "ruleId": "applic_CVE-2021-3807" - }, - { - "message": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `json-schema.validate` with external input to its 1st (`instance`) argument.\n* `json-schema.checkPropertyChange` with external input to its 2nd (`schema`) argument." - }, - "kind": "pass", - "ruleId": "applic_CVE-2021-3918" - } - ] - } - ], - "version": "2.1.0", - "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json" -} \ No newline at end of file