Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -21,22 +21,22 @@
@JsonDeserialize()
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class kicsRealtimeResults {
public class KicsRealtimeResults {

int totalCount;
String version;
List<KicsResult> results;
KicsSummary kicsSummary;

@JsonCreator
public kicsRealtimeResults(@JsonProperty("total_counter") int totalCount, @JsonProperty("queries") List<KicsResult> results,@JsonProperty("kics_version") String version, @JsonProperty("severity_counters") KicsSummary kicsSummary) {
public KicsRealtimeResults(@JsonProperty("total_counter") int totalCount, @JsonProperty("queries") List<KicsResult> results, @JsonProperty("kics_version") String version, @JsonProperty("severity_counters") KicsSummary kicsSummary) {
this.totalCount = totalCount;
this.version = version;
this.results = results;
this.kicsSummary = kicsSummary;
}
public static <T> T fromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructType(kicsRealtimeResults.class));
return parse(line, TypeFactory.defaultInstance().constructType(KicsRealtimeResults.class));
}

private static <T> T parse(String line, JavaType type) {
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/com/checkmarx/ast/remediation/KicsRemediation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.checkmarx.ast.remediation;

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.Value;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;

@Value
@JsonDeserialize()
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class KicsRemediation {
String availableRemediation;
String appliedRemediation;

@JsonCreator
public KicsRemediation(@JsonProperty("available_remediation_count") String availableRemediation, @JsonProperty("applied_remediation_count") String appliedRemediation) {
this.availableRemediation = availableRemediation;
this.appliedRemediation = appliedRemediation;
}

public static <T> T fromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructType(KicsRemediation.class));
}

private static <T> 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;
}
}
}
32 changes: 29 additions & 3 deletions src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.checkmarx.ast.wrapper;

import com.checkmarx.ast.codebashing.CodeBashing;
import com.checkmarx.ast.kicsRealtimeResults.kicsRealtimeResults;
import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults;
import com.checkmarx.ast.predicate.Predicate;
import com.checkmarx.ast.project.Project;
import com.checkmarx.ast.remediation.KicsRemediation;
import com.checkmarx.ast.results.ReportFormat;
import com.checkmarx.ast.results.Results;
import com.checkmarx.ast.results.ResultsSummary;
Expand Down Expand Up @@ -304,7 +305,7 @@ public int getResultsBfl(@NonNull UUID scanId, @NonNull String queryId, List<Nod

}

public kicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String engine, String additionalParams)
public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String engine, String additionalParams)
throws IOException, InterruptedException, CxException {
this.logger.info("Executing 'scan kics-realtime' command using the CLI.");
this.logger.info("Fetching the results for fileSources {} and additionalParams {}", fileSources, additionalParams);
Expand All @@ -320,9 +321,34 @@ public kicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String
arguments.add(CxConstants.ENGINE);
arguments.add(engine);
}
kicsRealtimeResults kicsResults = Execution.executeCommand(withConfigArguments(arguments), logger, kicsRealtimeResults::fromLine);
KicsRealtimeResults kicsResults = Execution.executeCommand(withConfigArguments(arguments), logger, KicsRealtimeResults::fromLine);
return kicsResults;
}

public KicsRemediation kicsRemediate(@NonNull String resultsFile, String kicsFile, String engine,String similarityIds)
throws IOException, InterruptedException, CxException {
this.logger.info("Executing 'remediation kics' command using the CLI.");
this.logger.info("Applying remediation for resultsFile {} and resultsFile {}", resultsFile, kicsFile);

List<String> arguments = new ArrayList<>();
arguments.add(this.executable);
arguments.add("utils");
arguments.add("remediation");
arguments.add("kics");
arguments.add("--results-file");
arguments.add(resultsFile);
arguments.add("--kics-files");
arguments.add(kicsFile);
if (engine.length() > 0) {
arguments.add(CxConstants.ENGINE);
arguments.add(engine);
}
if (similarityIds.length() > 0) {
arguments.add("--similarity-ids");
arguments.add(similarityIds);
}
KicsRemediation remediation = Execution.executeCommand(arguments, logger, KicsRemediation::fromLine);
return remediation;
}

private int getIndexOfBfLNode(List<Node> bflNodes, List<Node> resultNodes) {
Expand Down
31 changes: 31 additions & 0 deletions src/test/java/com/checkmarx/ast/RemediationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.checkmarx.ast;

import com.checkmarx.ast.remediation.KicsRemediation;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.nio.file.Path;
import java.nio.file.Paths;

class RemediationTest extends BaseTest {
private static String RESULTS_FILE = "target/test-classes/results.json";

private static Path path = Paths.get("target/test-classes/");
private static String KICS_FILE = path.toAbsolutePath().toString();
private static String QUERY_ID = "9574288c118e8c87eea31b6f0b011295a39ec5e70d83fb70e839b8db4a99eba8";
private static String ENGINE = "docker";

@Test
void testKicsRemediation() throws Exception {
KicsRemediation remediation = wrapper.kicsRemediate(RESULTS_FILE,KICS_FILE,"","");
Assertions.assertTrue(remediation.getAppliedRemediation() != "");
Assertions.assertTrue(remediation.getAvailableRemediation() != "");
}

@Test
void testKicsRemediationSimilarityFilter() throws Exception {
KicsRemediation remediation = wrapper.kicsRemediate(RESULTS_FILE,KICS_FILE,ENGINE,QUERY_ID);
Assertions.assertTrue(remediation.getAppliedRemediation() != "");
Assertions.assertTrue(remediation.getAvailableRemediation() != "");
}

}
4 changes: 2 additions & 2 deletions src/test/java/com/checkmarx/ast/ScanTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.checkmarx.ast;

import com.checkmarx.ast.kicsRealtimeResults.kicsRealtimeResults;
import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults;
import com.checkmarx.ast.scan.Scan;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -34,7 +34,7 @@ void testScanCreate() throws Exception {

@Test
void testKicsRealtimeScan() throws Exception {
kicsRealtimeResults scan = wrapper.kicsRealtimeScan("target/test-classes/Dockerfile","","v");
KicsRealtimeResults scan = wrapper.kicsRealtimeScan("target/test-classes/Dockerfile","","v");
Assertions.assertTrue(scan.getResults().size() >= 1);
}

Expand Down
20 changes: 20 additions & 0 deletions src/test/resources/positive1.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "aws_lb_listener" "listener5" {
load_balancer_arn = aws_lb.test3.arn
port = 80
default_action {
type = "redirect"

redirect {
port = "80"
protocol = "HTTP"
status_code = "HTTP_301"
}
}
}

resource "aws_lb" "test3" {
name = "test123"
load_balancer_type = "application"
subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
internal = true
}
1 change: 1 addition & 0 deletions src/test/resources/results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"kics_version":"v1.5.12","total_counter":6,"queries":[{"query_name":"ALB Listening on HTTP","query_id":"de7f5e83-da88-4046-871f-ea18504b1d43","severity":"HIGH","platform":"Terraform","category":"Networking and Firewall","description":"AWS Application Load Balancer (alb) should not listen on HTTP","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener","files":[{"file_name":"../../path/positive1.tf","similarity_id":"b42a19486a8e18324a9b2c06147b1c49feb3ba39a0e4aeafec5665e60f98d047","line":9,"issue_type":"IncorrectValue","search_key":"aws_lb_listener[listener5].default_action.redirect.protocol","search_line":0,"search_value":"","expected_value":"'default_action.redirect.protocol' is equal to 'HTTPS'","actual_value":"'default_action.redirect.protocol' is equal 'HTTP'","remediation":"{\"after\":\"HTTPS\",\"before\":\"HTTP\"}","remediation_type":"replacement"}]},{"query_name":"ALB Not Dropping Invalid Headers","query_id":"6e3fd2ed-5c83-4c68-9679-7700d224d379","severity":"MEDIUM","platform":"Terraform","category":"Best Practices","description":"It's considered a best practice when using Application Load Balancers to drop invalid header fields","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb#drop_invalid_header_fields","files":[{"file_name":"../../path/positive1.tf","similarity_id":"9574288c118e8c87eea31b6f0b011295a39ec5e70d83fb70e839b8db4a99eba8","line":15,"issue_type":"MissingAttribute","search_key":"aws_lb[{{test3}}]","search_line":0,"search_value":"","expected_value":"aws_lb[{{test3}}].drop_invalid_header_fields is set to true","actual_value":"aws_lb[{{test3}}].drop_invalid_header_fields is missing","remediation":"drop_invalid_header_fields = true","remediation_type":"addition"}]},{"query_name":"ALB Deletion Protection Disabled","query_id":"afecd1f1-6378-4f7e-bb3b-60c35801fdd4","severity":"LOW","platform":"Terraform","category":"Insecure Configurations","description":"Application Load Balancer should have deletion protection enabled","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb#enable_deletion_protection","files":[{"file_name":"../../path/positive1.tf","similarity_id":"cc22618d82eee56de73a07a558bf689f2efe1ddc42393323d14f77b0c37c29a8","line":15,"issue_type":"MissingAttribute","search_key":"aws_lb[test3]","search_line":0,"search_value":"","expected_value":"'enable_deletion_protection' is defined and set to true","actual_value":"'enable_deletion_protection' is undefined or null","remediation":"enable_deletion_protection = true","remediation_type":"addition"}]},{"query_name":"IAM Access Analyzer Not Enabled","query_id":"e592a0c5-5bdb-414c-9066-5dba7cdea370","severity":"LOW","platform":"Terraform","category":"Best Practices","description":"IAM Access Analyzer should be enabled and configured to continuously monitor resource permissions","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/accessanalyzer_analyzer","files":[{"file_name":"../../path/positive1.tf","similarity_id":"23486f3c10caaa350ec4e2a26d49de0969a585e7df6ec7814fe44466c8e1ff9e","line":1,"issue_type":"MissingAttribute","search_key":"resource","search_line":0,"search_value":"","expected_value":"'aws_accessanalyzer_analyzer' is set","actual_value":"'aws_accessanalyzer_analyzer' is undefined","remediation":"","remediation_type":""}]},{"query_name":"Shield Advanced Not In Use","query_id":"084c6686-2a70-4710-91b1-000393e54c12","severity":"LOW","platform":"Terraform","category":"Networking and Firewall","description":"AWS Shield Advanced should be used for Amazon Route 53 hosted zone, AWS Global Accelerator accelerator, Elastic IP Address, Elastic Load Balancing, and Amazon CloudFront Distribution to protect these resources against robust DDoS attacks","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/shield_protection#resource_arn","files":[{"file_name":"../../path/positive1.tf","similarity_id":"069aa314d2934c4c50746ec0045e0802e3c6f8f803ea5528c60d92917cc4d318","line":15,"issue_type":"MissingAttribute","search_key":"aws_lb[test3]","search_line":0,"search_value":"","expected_value":"aws_lb has shield advanced associated","actual_value":"aws_lb does not have shield advanced associated","remediation":"","remediation_type":""}]},{"query_name":"Resource Not Using Tags","query_id":"e38a8e0a-b88b-4902-b3fe-b0fcb17d5c10","severity":"INFO","platform":"Terraform","category":"Best Practices","description":"AWS services resource tags are an essential part of managing components. As a best practice, the field 'tags' should have additional tags defined other than 'Name'","query_url":"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/resource-tagging","files":[{"file_name":"../../path/positive1.tf","similarity_id":"e9119956188af27eb6b095cf0fadbf0d784270d9238e4650390e3b3d9a9756f5","line":15,"issue_type":"MissingAttribute","search_key":"aws_lb[{{test3}}]","search_line":0,"search_value":"","expected_value":"aws_lb[{{test3}}].tags is defined and not null","actual_value":"aws_lb[{{test3}}].tags is undefined or null","remediation":"","remediation_type":""}]}],"severity_counters":{"HIGH":1,"INFO":1,"LOW":3,"MEDIUM":1}}