Skip to content

Commit 2621bf4

Browse files
authored
adding kics remediate command
adding kics remediate command
2 parents 0ac2b82 + f133112 commit 2621bf4

File tree

8 files changed

+88
-1
lines changed

8 files changed

+88
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
},
1414
"scripts": {
1515
"build": "tsc",
16-
"postbuild": "copyfiles -u 1 src/main/wrapper/resources/cx* dist/",
16+
"postbuild": "copyfiles -u 1 src/main/wrapper/resources/cx* dist/;copyfiles -u 1 src/tests/data/* dist/;",
1717
"lint": "eslint . --ext .ts",
1818
"lint-and-fix": "eslint . --ext .ts --fix",
1919
"test": "copyfiles -u 1 src/tests/data/* dist/; tsc && jest --runInBand --coverage"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export default class CxKicsRemediation {
2+
availableRemediation: string;
3+
appliedRemediation: string;
4+
5+
constructor(availableRemediation: string,appliedRemediation: string) {
6+
this.availableRemediation = availableRemediation;
7+
this.appliedRemediation = appliedRemediation;
8+
}
9+
10+
static parseKicsRemediation(resultObject: any): CxKicsRemediation {
11+
const output: CxKicsRemediation = new CxKicsRemediation(resultObject.available_remediation_count,resultObject.applied_remediation_count);
12+
return output;
13+
}
14+
}

src/main/wrapper/CxConstants.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ export enum CxConstants {
1515
TENANT = "--tenant",
1616
BASE_URI = "--base-uri",
1717
BASE_AUTH_URI = "--base-auth-uri",
18+
CMD_UTILS = "utils",
19+
CMD_REMEDIATION = "remediation",
20+
SUB_CMD_REMEDIATION_KICS = "kics",
21+
KICS_REMEDIATION_RESULTS_FILE = "--results-file",
22+
KICS_REMEDIATION_KICS_FILE = "--kics-files",
23+
KICS_REMEDIATION_SIMILARITY_IDS = "--similarity-ids",
1824
CMD_AUTH = "auth",
1925
SUB_CMD_VALIDATE = "validate",
2026
CMD_PROJECT = "project",
@@ -56,6 +62,7 @@ export enum CxConstants {
5662
PREDICATE_TYPE = "CxPredicate",
5763
CODE_BASHING_TYPE = "CxCodeBashing",
5864
KICS_REALTIME_TYPE = "CxKicsRealTime",
65+
KICS_REMEDIATION_TYPE = "CxKicsRemediation",
5966
BFL_TYPE = "CxBFL",
6067
SAST = "sast",
6168
LANGUAGE = "--language",

src/main/wrapper/CxWrapper.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,19 @@ export class CxWrapper {
247247
return exec.executeKicsCommands(this.config.pathToExecutable, commands, CxConstants.KICS_REALTIME_TYPE);
248248
}
249249

250+
async kicsRemediation(resultsFile: string, kicsFile:string, engine:string,similarityIds?: string):Promise<[Promise<CxCommandOutput>,any]> {
251+
const commands: string[] = [CxConstants.CMD_UTILS, CxConstants.CMD_REMEDIATION,CxConstants.SUB_CMD_REMEDIATION_KICS,CxConstants.KICS_REMEDIATION_RESULTS_FILE, resultsFile, CxConstants.KICS_REMEDIATION_KICS_FILE, kicsFile];
252+
if(engine.length>0){
253+
commands.push(CxConstants.ENGINE,engine)
254+
}
255+
if(similarityIds){
256+
commands.push(CxConstants.KICS_REMEDIATION_SIMILARITY_IDS,similarityIds)
257+
}
258+
commands.push(...this.initializeCommands(false));
259+
const exec = new ExecutionService();
260+
return exec.executeKicsCommands(this.config.pathToExecutable, commands, CxConstants.KICS_REMEDIATION_TYPE);
261+
}
262+
250263
getIndexOfBflNode(bflNodes: CxBFL[], resultNodes: any[]): number {
251264

252265
const bflNodeNotFound = -1;

src/main/wrapper/ExecutionService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import CxCodeBashing from "../codebashing/CxCodeBashing";
1010
import CxBFL from "../bfl/CxBFL";
1111
import spawner = require('child_process');
1212
import CxKicsRealTime from "../kicsRealtime/CxKicsRealTime";
13+
import CxKicsRemediation from "../remediation/CxKicsRemediation";
1314

1415

1516

@@ -140,6 +141,10 @@ export class ExecutionService {
140141
const kicsResults = CxKicsRealTime.parseKicsRealTimeResponse(resultObject);
141142
cxCommandOutput.payload = [kicsResults];
142143
break;
144+
case "CxKicsRemediation":
145+
const kicsRemediationOutput = CxKicsRemediation.parseKicsRemediation(resultObject)
146+
cxCommandOutput.payload = [kicsRemediationOutput]
147+
break;
143148
default:
144149
cxCommandOutput.payload = resultObject;
145150
}

src/tests/RemediationTest.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {CxWrapper} from '../main/wrapper/CxWrapper';
2+
import {BaseTest} from "./BaseTest";
3+
import {CxCommandOutput} from "../main/wrapper/CxCommandOutput";
4+
import CxKicsRemediation from "../main/remediation/CxKicsRemediation";
5+
6+
describe("Kics Remediation cases",() => {
7+
const cxScanConfig = new BaseTest();
8+
it('Kics Remediation Successful case', async () => {
9+
const auth = new CxWrapper(cxScanConfig);
10+
const e:[Promise<CxCommandOutput>,any] = await auth.kicsRemediation("dist/tests/data/results.json",__dirname+"/data","docker")
11+
const output = await e[0];
12+
const remediation: CxKicsRemediation = output.payload[0];
13+
expect(remediation.availableRemediation).toBeDefined();
14+
expect(remediation.appliedRemediation).toBeDefined();
15+
});
16+
17+
it('Kics Remediation Successful case with filter', async () => {
18+
const auth = new CxWrapper(cxScanConfig);
19+
const e:[Promise<CxCommandOutput>,any] = await auth.kicsRemediation("dist/tests/data/results.json",__dirname+"/data/","","9574288c118e8c87eea31b6f0b011295a39ec5e70d83fb70e839b8db4a99eba8")
20+
const output = await e[0];
21+
const remediation: CxKicsRemediation = output.payload[0];
22+
expect(remediation.availableRemediation).toBeDefined();
23+
expect(remediation.appliedRemediation).toBeDefined();
24+
});
25+
});

src/tests/data/positive1.tf

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
resource "aws_lb_listener" "listener5" {
2+
load_balancer_arn = aws_lb.test3.arn
3+
port = 80
4+
default_action {
5+
type = "redirect"
6+
7+
redirect {
8+
port = "80"
9+
protocol = "HTTPSSSSSSSSSSSSSSSSSSSSSSSSS"
10+
status_code = "HTTP_301"
11+
}
12+
}
13+
}
14+
15+
resource "aws_lb" "test3" {
16+
enable_deletion_protection = true
17+
drop_invalid_header_fields = true
18+
name = "test123"
19+
load_balancer_type = "application"
20+
subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
21+
internal = true
22+
}

src/tests/data/results.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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}}

0 commit comments

Comments
 (0)