Skip to content

Commit

Permalink
Upgraded the AM version (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
eyalk007 authored Sep 9, 2024
1 parent 9021c13 commit 8915a4d
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,30 @@ public JFrogSecurityWarning(
this.codeFlows = codeFlows;
}

public JFrogSecurityWarning(SarifResult result, SourceCodeScanType reporter) {
public JFrogSecurityWarning(SarifResult result, SourceCodeScanType reporter, Rule rule) {
this(getFirstRegion(result).getStartLine() - 1,
getFirstRegion(result).getStartColumn() - 1,
getFirstRegion(result).getEndLine() - 1,
getFirstRegion(result).getEndColumn() - 1,
result.getMessage().getText(),
!result.getLocations().isEmpty() ? uriToPath(result.getLocations().get(0).getPhysicalLocation().getArtifactLocation().getUri()) : "",
getFilePath(result),
result.getRuleId(),
getFirstRegion(result).getSnippet().getText(),
reporter,
!result.getKind().equals("pass"),
isWarningApplicable(result,rule),
Severity.fromSarif(result.getSeverity()),
convertCodeFlowsToFindingInfo(result.getCodeFlows())
);
}

private static boolean isWarningApplicable(SarifResult result,Rule rule){
return !result.getKind().equals("pass") && (rule.getRuleProperties().map(properties -> properties.getApplicability().equals("applicable")).orElse(true));
}

private static String getFilePath(SarifResult result){
return !result.getLocations().isEmpty() ? uriToPath(result.getLocations().get(0).getPhysicalLocation().getArtifactLocation().getUri()) : "";
}

private static FindingInfo[][] convertCodeFlowsToFindingInfo(List<CodeFlow> codeFlows) {
if (codeFlows == null || codeFlows.isEmpty()) {
return null;
Expand Down Expand Up @@ -114,3 +122,4 @@ private static String uriToPath(String path) {
return Paths.get(URI.create(path)).toString();
}
}

7 changes: 4 additions & 3 deletions src/main/java/com/jfrog/ide/idea/scan/ScanBinaryExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public abstract class ScanBinaryExecutor {
private static final int USER_NOT_ENTITLED = 31;
private static final int NOT_SUPPORTED = 13;
private static final String SCANNER_BINARY_NAME = "analyzerManager";
private static final String SCANNER_BINARY_VERSION = "1.6.3";
private static final String SCANNER_BINARY_VERSION = "1.8.14";
private static final String BINARY_DOWNLOAD_URL = "xsc-gen-exe-analyzer-manager-local/v1/" + SCANNER_BINARY_VERSION;
private static final String DOWNLOAD_SCANNER_NAME = "analyzerManager.zip";
private static final String MINIMAL_XRAY_VERSION_SUPPORTED_FOR_ENTITLEMENT = "3.66.0";
Expand Down Expand Up @@ -257,10 +257,11 @@ protected boolean isPackageTypeSupported(PackageManagerType type) {
return type != null && supportedPackageTypes.contains(type);
}

protected List<JFrogSecurityWarning> parseOutputSarif(Path outputFile) throws IOException {
protected List<JFrogSecurityWarning> parseOutputSarif(Path outputFile) throws IOException,IndexOutOfBoundsException {
Output output = getOutputObj(outputFile);
List<JFrogSecurityWarning> warnings = new ArrayList<>();
output.getRuns().forEach(run -> run.getResults().stream().filter(SarifResult::isNotSuppressed).forEach(result -> warnings.add(new JFrogSecurityWarning(result, scanType))));

output.getRuns().forEach(run -> run.getResults().stream().filter(SarifResult::isNotSuppressed).forEach(result -> warnings.add(new JFrogSecurityWarning(result, scanType, run.getRuleFromRunById(result.getRuleId())))));

Optional<Run> run = output.getRuns().stream().findFirst();
if (run.isPresent()) {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/jfrog/ide/idea/scan/data/Driver.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) throws IndexOutOfBoundsException {
return rules.stream()
.filter(rule -> rule.getId().equals(ruleId))
.findFirst()
.orElseThrow(() -> new IndexOutOfBoundsException("Rule not found"));
}


}
12 changes: 11 additions & 1 deletion src/main/java/com/jfrog/ide/idea/scan/data/Rule.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.jfrog.ide.idea.scan.data;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Objects;
import java.util.Optional;

public class Rule {

Expand All @@ -15,6 +15,9 @@ public class Rule {
@JsonProperty("fullDescription")
private Message fullDescription;

@JsonProperty("properties")
private RuleProperties properties;

public String getId() {
return id;
}
Expand Down Expand Up @@ -43,11 +46,16 @@ public void setFullDescription(Message fullDescription) {
this.fullDescription = fullDescription;
}

public Optional<RuleProperties> getRuleProperties() {
return Optional.ofNullable(properties);
}

@Override
public int hashCode() {
return Objects.hash(id);
}


@Override
public boolean equals(Object other) {
if (other == this) {
Expand All @@ -60,3 +68,5 @@ public boolean equals(Object other) {
return Objects.equals(this.id, rhs.id);
}
}


15 changes: 15 additions & 0 deletions src/main/java/com/jfrog/ide/idea/scan/data/RuleProperties.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.jfrog.ide.idea.scan.data;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;

@Getter
public class RuleProperties {

@JsonProperty("conclusion")
private String conclusion;

@JsonProperty("applicability")
private String applicability;

}
4 changes: 4 additions & 0 deletions src/main/java/com/jfrog/ide/idea/scan/data/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public List<SarifResult> getResults() {
return results;
}

public Rule getRuleFromRunById(String ruleId) {
return this.getTool().getDriver().getRuleById(ruleId);
}

public void setResults(List<SarifResult> results) {
this.results = results;
}
Expand Down
34 changes: 24 additions & 10 deletions src/test/java/com/jfrog/ide/idea/scan/ScanBinaryExecutorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
import java.util.List;

import static com.jfrog.ide.common.utils.Utils.createYAMLMapper;
import static org.junit.Assert.assertThrows;

/**
* @author tala
**/
public class ScanBinaryExecutorTest extends TestCase {
private final ScanBinaryExecutor scanner = new ApplicabilityScannerExecutor(new NullLog());
private final Path FAULTY_OUTPUT = new File("src/test/resources/sourceCode/faulty_output.sarif").toPath();
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 APPLIC_KIND_PASS_AND_FAIL_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;
Expand Down Expand Up @@ -70,21 +71,34 @@ public void testSarifParser() throws IOException {
assertEquals(73, parsedOutput.get(1).getColEnd());
}

public void testSarifParserNotApplicResults() throws IOException {
List<JFrogSecurityWarning> parsedOutput = scanner.parseOutputSarif(NOT_APPLIC_OUTPUT);
assertEquals(4, parsedOutput.size());
// 2 known applicable results (code evidence returned)
public void testSarifParserWithMissingRole() throws IndexOutOfBoundsException {
assertThrows(IndexOutOfBoundsException.class,() -> scanner.parseOutputSarif(FAULTY_OUTPUT));
}

public void testSarifParserApplicResultsWithKindPassAndFail() throws IOException {
List<JFrogSecurityWarning> parsedOutput = scanner.parseOutputSarif(APPLIC_KIND_PASS_AND_FAIL_OUTPUT);
assertEquals(6, parsedOutput.size());
//Not Applicable with kind pass
assertEquals("applic_CVE-2022-25878", parsedOutput.get(0).getRuleID());
assertTrue(parsedOutput.get(0).isApplicable());
assertEquals("CVE-2022-25978", parsedOutput.get(1).getRuleID());
assertFalse(parsedOutput.get(0).isApplicable());
//Applicable with kind pass
assertEquals("applic_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)
//Not applicable with kind pass and no properties
assertEquals("applic_CVE-2021-25878", parsedOutput.get(2).getRuleID());
assertFalse(parsedOutput.get(2).isApplicable());
//Applicable with kind fail
assertEquals("applic_CVE-2022-29019", parsedOutput.get(3).getRuleID());
assertFalse(parsedOutput.get(3).isApplicable());
assertTrue(parsedOutput.get(3).isApplicable());
//Not applicable as its not_covered
assertEquals("applic_CVE-2022-29004", parsedOutput.get(4).getRuleID());
assertFalse(parsedOutput.get(4).isApplicable());
//Not applicable as its undetermined
assertEquals("applic_CVE-2022-29014", parsedOutput.get(5).getRuleID());
assertFalse(parsedOutput.get(5).isApplicable());
}


public void testGetBinaryDownloadURL() {
final String externalRepoName = "test-releases-repo";
final String expectedExternalRepoUrl = "test-releases-repo/artifactory/xsc-gen-exe-analyzer-manager-local/";
Expand Down
178 changes: 178 additions & 0 deletions src/test/resources/sourceCode/applicable_kind_pass_output.sarif
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{
"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 applic_CVE-2022-25878"
}
},
{
"id": "applic_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 applic_CVE-2022-25978"
}
},
{
"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 applic_CVE-2021-25878"
}
},
{
"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 applic_CVE-2022-29019"
}
},
{
"id": "applic_CVE-2022-29004",
"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 applic_CVE-2022-29004"
}, "properties": {
"conclusion": "positive",
"applicability": "not_covered"
}
},
{
"id": "applic_CVE-2022-29014",
"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 applic_CVE-2022-29014"
}, "properties": {
"conclusion": "positive",
"applicability": "undetermined"
}
}
],
"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": "applic_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": "fail",
"ruleId": "applic_CVE-2022-29019"
},
{
"message": {
"text": "The scanner checks whether the vulnerable function `call-all-ansi` is called."
},
"kind": "pass",
"ruleId": "applic_CVE-2022-29004"
},
{"message": {
"text": "The scanner checks whether the vulnerable function `not-call-all-ansi` is called."
},
"kind": "pass",
"ruleId": "applic_CVE-2022-29014"
}
]
}
],
"version": "2.1.0",
"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json"
}
Loading

0 comments on commit 8915a4d

Please sign in to comment.