diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5247b99a..6c7d7264 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: CX_BASE_URI: ${{ secrets.CX_BASE_URI }} CX_TENANT: ${{ secrets.CX_TENANT }} CX_SCAN_ID: ${{ secrets.CX_SCAN_ID }} + CX_APIKEY: ${{ secrets.CX_APIKEY }} run: mvn -B test --file pom.xml cx-scan: runs-on: ubuntu-latest diff --git a/src/main/java/com/checkmarx/ast/codebashing/CodeBashing.java b/src/main/java/com/checkmarx/ast/codebashing/CodeBashing.java new file mode 100644 index 00000000..0a8acedd --- /dev/null +++ b/src/main/java/com/checkmarx/ast/codebashing/CodeBashing.java @@ -0,0 +1,74 @@ +package com.checkmarx.ast.codebashing; + +import com.checkmarx.ast.predicate.Predicate; +import com.checkmarx.ast.wrapper.CxBaseObject; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.type.TypeFactory; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +@Value +@JsonDeserialize() +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class CodeBashing { + String path; + String cweId; + String language; + String queryName; + + @JsonCreator + public CodeBashing(@JsonProperty("path") String path, + @JsonProperty("cwe_id") String cweId, + @JsonProperty("lang") String language, + @JsonProperty("cxQueryName") String queryName) { + this.path=path; + this.cweId=cweId; + this.language=language; + this.queryName=queryName; + } + + public static T fromLine(String line) { + return parse(line, TypeFactory.defaultInstance().constructType(Predicate.class)); + } + + public static List listFromLine(String line) { + return parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, CodeBashing.class)); + } + + protected static T parse(String line, JavaType type) { + T result = null; + try { + if (!StringUtils.isBlank(line) && isValidJSON(line)) { + result = new ObjectMapper().readValue(line, type); + + } + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + private static boolean isValidJSON(final String json) { + try { + final ObjectMapper mapper = new ObjectMapper(); + mapper.readTree(json); + return true; + } catch (IOException e) { + return false; + } + } + +} + diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java index e2207aa0..3ddea787 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java @@ -45,14 +45,14 @@ void validate() throws InvalidCLIConfigException { List toArguments() { List commands = new ArrayList<>(); - if (StringUtils.isNotBlank(getClientId()) && StringUtils.isNotBlank(getClientSecret())) { + if (StringUtils.isNotBlank(getApiKey())) { + commands.add(CxConstants.API_KEY); + commands.add(getApiKey()); + } else if (StringUtils.isNotBlank(getClientId()) && StringUtils.isNotBlank(getClientSecret())) { commands.add(CxConstants.CLIENT_ID); commands.add(getClientId()); commands.add(CxConstants.CLIENT_SECRET); commands.add(getClientSecret()); - } else if (StringUtils.isNotBlank(getApiKey())) { - commands.add(CxConstants.API_KEY); - commands.add(getApiKey()); } if (StringUtils.isNotBlank(getTenant())) { diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 49b129e9..15d414c1 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -42,4 +42,8 @@ public final class CxConstants { static final String REPORT_FORMAT = "--report-format"; static final String OUTPUT_NAME = "--output-name"; static final String OUTPUT_PATH = "--output-path"; + static final String SUB_CMD_CODE_BASHING = "codebashing"; + static final String CWE_ID = "--cwe-id"; + static final String LANGUAGE = "--language"; + static final String VULNERABILITY_TYPE = "--vulnerabity-type"; } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index 5a1ed5c1..1c6c3c13 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -1,5 +1,6 @@ package com.checkmarx.ast.wrapper; +import com.checkmarx.ast.codebashing.CodeBashing; import com.checkmarx.ast.predicate.Predicate; import com.checkmarx.ast.project.Project; import com.checkmarx.ast.results.ReportFormat; @@ -201,6 +202,23 @@ public List projectBranches(@NonNull UUID projectId, String filter) line -> CxBaseObject.parse(line, BRANCHES_TYPE)); } + public List codeBashingList(@NonNull String cweId,@NonNull String language,@NonNull String queryName) throws IOException, InterruptedException, CxException { + this.logger.info("Fetching the codebashing link"); + + List arguments = new ArrayList<>(); + arguments.add(CxConstants.CMD_RESULT); + arguments.add(CxConstants.SUB_CMD_CODE_BASHING); + arguments.add(CxConstants.LANGUAGE); + arguments.add(language); + arguments.add(CxConstants.VULNERABILITY_TYPE); + arguments.add(queryName); + arguments.add(CxConstants.CWE_ID); + arguments.add(cweId); + arguments.addAll(jsonArguments()); + + return Execution.executeCommand(withConfigArguments(arguments), logger, CodeBashing::listFromLine); + } + public ResultsSummary resultsSummary(@NonNull UUID scanId) throws IOException, InterruptedException, CxException { return new ObjectMapper() .readerFor(ResultsSummary.class) diff --git a/src/test/java/com/checkmarx/ast/ResultTest.java b/src/test/java/com/checkmarx/ast/ResultTest.java index 34583cf3..d188057d 100644 --- a/src/test/java/com/checkmarx/ast/ResultTest.java +++ b/src/test/java/com/checkmarx/ast/ResultTest.java @@ -1,5 +1,6 @@ package com.checkmarx.ast; +import com.checkmarx.ast.codebashing.CodeBashing; import com.checkmarx.ast.results.ReportFormat; import com.checkmarx.ast.results.Results; import com.checkmarx.ast.results.ResultsSummary; @@ -11,7 +12,9 @@ import java.util.UUID; class ResultTest extends BaseTest { - + private static String CWE_ID = "79"; + private static String LANGUAGE = "PHP"; + private static String QUERY_NAME = "Reflected XSS All Clients"; @Test void testResultsHTML() throws Exception { List scanList = wrapper.scanList(); @@ -48,4 +51,12 @@ void testResultsStructure() throws Exception { results.getResults().stream().filter(result -> "sast".equalsIgnoreCase(result.getType())).findFirst(); Assertions.assertEquals(results.getTotalCount(), results.getResults().size()); } + + @Test() + void testResultsCodeBashing() throws Exception { + List codeBashingList = wrapper.codeBashingList(CWE_ID,LANGUAGE,QUERY_NAME); + Assertions.assertTrue(codeBashingList.size() > 0); + String path = codeBashingList.get(0).getPath(); + Assertions.assertTrue(path.length() > 0); + } }