Skip to content

Commit 09bebed

Browse files
Devassist: Realtime scanners (OSS, Secrets, Containers, IaC) with unified wrapper and enhanced parsing(AST-115438) (#451)
* aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Changed variable from id to CVE as per OSS response * Add maskedResult for secret remediation and change log level from INFO to DEBUG * Remove masked secrets functionality from codebase * Implemented mask cmd in java wrapper --------- Co-authored-by: cx-anand-nandeshwar <[email protected]>
1 parent e78d852 commit 09bebed

23 files changed

+1650
-7
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.checkmarx.ast.containersrealtime;
2+
3+
import com.checkmarx.ast.realtime.RealtimeLocation;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
import lombok.Value;
10+
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
@Value
15+
@JsonDeserialize
16+
@JsonInclude(JsonInclude.Include.NON_NULL)
17+
@JsonIgnoreProperties(ignoreUnknown = true)
18+
public class ContainersRealtimeImage {
19+
@JsonProperty("ImageName") String imageName;
20+
@JsonProperty("ImageTag") String imageTag;
21+
@JsonProperty("FilePath") String filePath;
22+
@JsonProperty("Locations") List<RealtimeLocation> locations;
23+
@JsonProperty("Status") String status;
24+
@JsonProperty("Vulnerabilities") List<ContainersRealtimeVulnerability> vulnerabilities;
25+
26+
@JsonCreator
27+
public ContainersRealtimeImage(@JsonProperty("ImageName") String imageName,
28+
@JsonProperty("ImageTag") String imageTag,
29+
@JsonProperty("FilePath") String filePath,
30+
@JsonProperty("Locations") List<RealtimeLocation> locations,
31+
@JsonProperty("Status") String status,
32+
@JsonProperty("Vulnerabilities") List<ContainersRealtimeVulnerability> vulnerabilities) {
33+
this.imageName = imageName;
34+
this.imageTag = imageTag;
35+
this.filePath = filePath;
36+
this.locations = locations == null ? Collections.emptyList() : locations;
37+
this.status = status;
38+
this.vulnerabilities = vulnerabilities == null ? Collections.emptyList() : vulnerabilities;
39+
}
40+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.checkmarx.ast.containersrealtime;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
import lombok.Value;
10+
import org.apache.commons.lang3.StringUtils;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import java.io.IOException;
15+
import java.util.List;
16+
17+
@Value
18+
@JsonDeserialize
19+
@JsonInclude(JsonInclude.Include.NON_NULL)
20+
@JsonIgnoreProperties(ignoreUnknown = true)
21+
public class ContainersRealtimeResults {
22+
private static final Logger log = LoggerFactory.getLogger(ContainersRealtimeResults.class);
23+
24+
@JsonProperty("Images") List<ContainersRealtimeImage> images;
25+
26+
@JsonCreator
27+
public ContainersRealtimeResults(@JsonProperty("Images") List<ContainersRealtimeImage> images) {
28+
this.images = images;
29+
}
30+
31+
public static ContainersRealtimeResults fromLine(String line) {
32+
if (StringUtils.isBlank(line)) {
33+
return null;
34+
}
35+
try {
36+
if (line.contains("\"Images\"") && isValidJSON(line)) {
37+
return new ObjectMapper().readValue(line, ContainersRealtimeResults.class);
38+
}
39+
} catch (IOException e) {
40+
log.debug("Failed to parse containers realtime line: {}", line, e);
41+
}
42+
return null;
43+
}
44+
45+
private static boolean isValidJSON(String json) {
46+
try {
47+
new ObjectMapper().readTree(json);
48+
return true;
49+
} catch (IOException e) {
50+
return false;
51+
}
52+
}
53+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.checkmarx.ast.containersrealtime;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
8+
import lombok.Value;
9+
10+
@Value
11+
@JsonDeserialize
12+
@JsonInclude(JsonInclude.Include.NON_NULL)
13+
@JsonIgnoreProperties(ignoreUnknown = true)
14+
public class ContainersRealtimeVulnerability {
15+
@JsonProperty("CVE") String cve;
16+
@JsonProperty("Severity") String severity;
17+
18+
@JsonCreator
19+
public ContainersRealtimeVulnerability(@JsonProperty("CVE") String cve,
20+
@JsonProperty("Severity") String severity) {
21+
this.cve = cve;
22+
this.severity = severity;
23+
}
24+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.checkmarx.ast.iacrealtime;
2+
3+
import com.checkmarx.ast.realtime.RealtimeLocation;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
10+
import lombok.Value;
11+
import org.apache.commons.lang3.StringUtils;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
15+
import java.io.IOException;
16+
import java.util.Collections;
17+
import java.util.List;
18+
19+
@Value
20+
@JsonDeserialize
21+
@JsonInclude(JsonInclude.Include.NON_NULL)
22+
@JsonIgnoreProperties(ignoreUnknown = true)
23+
public class IacRealtimeResults {
24+
private static final Logger log = LoggerFactory.getLogger(IacRealtimeResults.class);
25+
@JsonProperty("Results") List<Issue> results; // Normalized list (array or single object)
26+
27+
@JsonCreator
28+
public IacRealtimeResults(@JsonProperty("Results") List<Issue> results) {
29+
this.results = results == null ? Collections.emptyList() : results;
30+
}
31+
32+
@Value
33+
@JsonDeserialize
34+
@JsonInclude(JsonInclude.Include.NON_NULL)
35+
@JsonIgnoreProperties(ignoreUnknown = true)
36+
public static class Issue {
37+
@JsonProperty("Title") String title;
38+
@JsonProperty("Description") String description;
39+
@JsonProperty("SimilarityID") String similarityId;
40+
@JsonProperty("FilePath") String filePath;
41+
@JsonProperty("Severity") String severity;
42+
@JsonProperty("ExpectedValue") String expectedValue;
43+
@JsonProperty("ActualValue") String actualValue;
44+
@JsonProperty("Locations") List<RealtimeLocation> locations;
45+
46+
@JsonCreator
47+
public Issue(@JsonProperty("Title") String title,
48+
@JsonProperty("Description") String description,
49+
@JsonProperty("SimilarityID") String similarityId,
50+
@JsonProperty("FilePath") String filePath,
51+
@JsonProperty("Severity") String severity,
52+
@JsonProperty("ExpectedValue") String expectedValue,
53+
@JsonProperty("ActualValue") String actualValue,
54+
@JsonProperty("Locations") List<RealtimeLocation> locations) {
55+
this.title = title;
56+
this.description = description;
57+
this.similarityId = similarityId;
58+
this.filePath = filePath;
59+
this.severity = severity;
60+
this.expectedValue = expectedValue;
61+
this.actualValue = actualValue;
62+
this.locations = locations == null ? Collections.emptyList() : locations;
63+
}
64+
}
65+
66+
public static IacRealtimeResults fromLine(String line) {
67+
if (StringUtils.isBlank(line)) {
68+
return null;
69+
}
70+
try {
71+
if (!isValidJSON(line)) {
72+
return null;
73+
}
74+
ObjectMapper mapper = new ObjectMapper();
75+
String trimmed = line.trim();
76+
if (trimmed.startsWith("[")) {
77+
List<Issue> list = mapper.readValue(trimmed, mapper.getTypeFactory().constructCollectionType(List.class, Issue.class));
78+
return new IacRealtimeResults(list == null ? Collections.emptyList() : list);
79+
}
80+
if (trimmed.startsWith("{")) {
81+
Issue single = mapper.readValue(trimmed, Issue.class);
82+
return new IacRealtimeResults(Collections.singletonList(single));
83+
}
84+
} catch (IOException e) {
85+
log.debug("Failed to parse iac realtime JSON line: {}", line, e);
86+
}
87+
return null;
88+
}
89+
90+
private static boolean isValidJSON(String json) {
91+
try {
92+
new ObjectMapper().readTree(json);
93+
return true;
94+
} catch (IOException e) {
95+
return false;
96+
}
97+
}
98+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.checkmarx.ast.mask;
2+
3+
import com.checkmarx.ast.utils.JsonParser;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
import com.fasterxml.jackson.databind.type.TypeFactory;
10+
import lombok.EqualsAndHashCode;
11+
import lombok.ToString;
12+
import lombok.Value;
13+
14+
import java.util.List;
15+
16+
@Value
17+
@EqualsAndHashCode()
18+
@JsonDeserialize()
19+
@ToString(callSuper = true)
20+
@JsonInclude(JsonInclude.Include.NON_NULL)
21+
@JsonIgnoreProperties(ignoreUnknown = true)
22+
public class MaskResult {
23+
24+
List<MaskedSecret> maskedSecrets;
25+
String maskedFile;
26+
27+
@JsonCreator
28+
public MaskResult(@JsonProperty("maskedSecrets") List<MaskedSecret> maskedSecrets,
29+
@JsonProperty("maskedFile") String maskedFile) {
30+
this.maskedSecrets = maskedSecrets;
31+
this.maskedFile = maskedFile;
32+
}
33+
34+
public static MaskResult fromLine(String line) {
35+
return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(MaskResult.class));
36+
}
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.checkmarx.ast.mask;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
8+
import lombok.EqualsAndHashCode;
9+
import lombok.ToString;
10+
import lombok.Value;
11+
12+
@Value
13+
@EqualsAndHashCode()
14+
@JsonDeserialize()
15+
@ToString(callSuper = true)
16+
@JsonInclude(JsonInclude.Include.NON_NULL)
17+
@JsonIgnoreProperties(ignoreUnknown = true)
18+
public class MaskedSecret {
19+
20+
String masked;
21+
String secret;
22+
int line;
23+
24+
@JsonCreator
25+
public MaskedSecret(@JsonProperty("masked") String masked,
26+
@JsonProperty("secret") String secret,
27+
@JsonProperty("line") int line) {
28+
this.masked = masked;
29+
this.secret = secret;
30+
this.line = line;
31+
}
32+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.checkmarx.ast.ossrealtime;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
import lombok.Value;
10+
import org.apache.commons.lang3.StringUtils;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import java.io.IOException;
15+
import java.util.Collections;
16+
import java.util.List;
17+
18+
@Value
19+
@JsonDeserialize
20+
@JsonInclude(JsonInclude.Include.NON_NULL)
21+
@JsonIgnoreProperties(ignoreUnknown = true)
22+
public class OssRealtimeResults {
23+
private static final Logger log = LoggerFactory.getLogger(OssRealtimeResults.class);
24+
25+
@JsonProperty("Packages") List<OssRealtimeScanPackage> packages;
26+
27+
@JsonCreator
28+
public OssRealtimeResults(@JsonProperty("Packages") List<OssRealtimeScanPackage> packages) {
29+
this.packages = packages == null ? Collections.emptyList() : packages;
30+
}
31+
32+
public static OssRealtimeResults fromLine(String line) {
33+
if (StringUtils.isBlank(line)) {
34+
return null;
35+
}
36+
try {
37+
if (isValidJSON(line) && line.contains("\"Packages\"")) {
38+
return new ObjectMapper().readValue(line, OssRealtimeResults.class);
39+
}
40+
} catch (IOException e) {
41+
log.debug("Failed to parse oss realtime line: {}", line, e);
42+
}
43+
return null;
44+
}
45+
46+
private static boolean isValidJSON(String json) {
47+
try {
48+
new ObjectMapper().readTree(json);
49+
return true;
50+
} catch (IOException e) {
51+
return false;
52+
}
53+
}
54+
}
55+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.checkmarx.ast.ossrealtime;
2+
3+
import com.checkmarx.ast.realtime.RealtimeLocation;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonProperty;
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
import lombok.Value;
10+
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
@Value
15+
@JsonDeserialize
16+
@JsonInclude(JsonInclude.Include.NON_NULL)
17+
@JsonIgnoreProperties(ignoreUnknown = true)
18+
public class OssRealtimeScanPackage {
19+
@JsonProperty("PackageManager") String packageManager;
20+
@JsonProperty("PackageName") String packageName;
21+
@JsonProperty("PackageVersion") String packageVersion;
22+
@JsonProperty("FilePath") String filePath;
23+
@JsonProperty("Locations") List<RealtimeLocation> locations;
24+
@JsonProperty("Status") String status;
25+
@JsonProperty("Vulnerabilities") List<OssRealtimeVulnerability> vulnerabilities;
26+
27+
@JsonCreator
28+
public OssRealtimeScanPackage(@JsonProperty("PackageManager") String packageManager,
29+
@JsonProperty("PackageName") String packageName,
30+
@JsonProperty("PackageVersion") String packageVersion,
31+
@JsonProperty("FilePath") String filePath,
32+
@JsonProperty("Locations") List<RealtimeLocation> locations,
33+
@JsonProperty("Status") String status,
34+
@JsonProperty("Vulnerabilities") List<OssRealtimeVulnerability> vulnerabilities) {
35+
this.packageManager = packageManager;
36+
this.packageName = packageName;
37+
this.packageVersion = packageVersion;
38+
this.filePath = filePath;
39+
this.locations = locations == null ? Collections.emptyList() : locations;
40+
this.status = status;
41+
this.vulnerabilities = vulnerabilities == null ? Collections.emptyList() : vulnerabilities;
42+
}
43+
}
44+

0 commit comments

Comments
 (0)