Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded the AM version #477

Merged
merged 10 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
}
}

5 changes: 3 additions & 2 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 @@ -260,7 +260,8 @@ protected boolean isPackageTypeSupported(PackageManagerType type) {
protected List<JFrogSecurityWarning> parseOutputSarif(Path outputFile) throws IOException {
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) {
eyalk007 marked this conversation as resolved.
Show resolved Hide resolved
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;
eyalk007 marked this conversation as resolved.
Show resolved Hide resolved

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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import junit.framework.TestCase;
import org.apache.commons.io.FileUtils;
import org.jfrog.build.api.util.NullLog;
import org.junit.Assert;

import java.io.File;
import java.io.IOException;
Expand All @@ -15,6 +16,7 @@
import java.util.List;

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

/**
* @author tala
Expand All @@ -23,7 +25,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 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;
Expand Down Expand Up @@ -85,6 +87,30 @@ public void testSarifParserNotApplicResults() throws IOException {
assertFalse(parsedOutput.get(3).isApplicable());
}

public void testSarifParserApplicResultsWithKindPass() throws IOException {
List<JFrogSecurityWarning> parsedOutput = scanner.parseOutputSarif(APPLIC_KIND_PASS_OUTPUT);
assertEquals(6, parsedOutput.size());
//Not Applicable with kind pass
assertEquals("applic_CVE-2022-25878", parsedOutput.get(0).getRuleID());
assertFalse(parsedOutput.get(0).isApplicable());
//Applicable with kind pass
assertEquals("applic_CVE-2022-25978", parsedOutput.get(1).getRuleID());
assertTrue(parsedOutput.get(1).isApplicable());
//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());
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 @@
{
eyalk007 marked this conversation as resolved.
Show resolved Hide resolved
"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