-
Notifications
You must be signed in to change notification settings - Fork 87
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
Pr orly ast support #356
Pr orly ast support #356
Changes from all commits
a670d2b
50b4551
a7b5cde
9eeb9ab
8366a25
05f2570
7cbfa12
8bddd95
9b5da7d
c440184
d3603db
2baaab6
71b2541
a5b60ff
f38fa21
0f9c4b5
82d23f6
5c29398
0bb5683
a8aa339
a514f55
76ead43
ebc2186
5d6ecae
59495d8
0c2be79
e039ca4
745e1b1
07fd7aa
e176e48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,8 @@ public class CxFlowRunner implements ApplicationRunner { | |
public static final String BATCH_OPTION = "batch"; | ||
private static final String SAST_SCANNER = "sast"; | ||
private static final String SCA_SCANNER = "sca"; | ||
|
||
private static final String AST_SCANNER = "ast"; | ||
|
||
private final FlowProperties flowProperties; | ||
private final CxProperties cxProperties; | ||
private final JiraProperties jiraProperties; | ||
|
@@ -52,6 +53,7 @@ public class CxFlowRunner implements ApplicationRunner { | |
private final HelperService helperService; | ||
private final SastScanner sastScanner; | ||
private final SCAScanner scaScanner; | ||
private final ASTScanner astScanner; | ||
private final List<ThreadPoolTaskExecutor> executors; | ||
private final ResultsService resultsService; | ||
private final OsaScannerService osaScannerService; | ||
|
@@ -451,8 +453,7 @@ private String getOptionValues(ApplicationArguments arg, String option){ | |
} | ||
|
||
private void cxScan(ScanRequest request, String gitUrl, String gitAuthUrl, String branch, ScanRequest.Repository repoType) throws ExitThrowable { | ||
ScanResults sastScanResults = null; | ||
ScanResults scaScanResults = null; | ||
|
||
log.info("Initiating scan using Checkmarx git clone"); | ||
request.setRepoType(repoType); | ||
log.info("Git url: {}", gitUrl); | ||
|
@@ -461,33 +462,66 @@ private void cxScan(ScanRequest request, String gitUrl, String gitAuthUrl, Strin | |
request.setRepoUrlWithAuth(gitAuthUrl); | ||
request.setRefs(Constants.CX_BRANCH_PREFIX.concat(branch)); | ||
|
||
if(flowProperties.getEnabledVulnerabilityScanners() == null || | ||
flowProperties.getEnabledVulnerabilityScanners().contains(SAST_SCANNER)) { | ||
ScanResults scanResults = scan(request); | ||
processResults(request, scanResults); | ||
} | ||
|
||
private ScanResults scan(ScanRequest request) throws ExitThrowable { | ||
ScanResults sastScanResults = null; | ||
ScanResults scaScanResults = null; | ||
ScanResults astScanResults = null; | ||
|
||
if(isSastEnabled()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use a 'for' loop here or reuse the existing one? |
||
sastScanResults = sastScanner.cxFullScan(request); | ||
} | ||
if(flowProperties.getEnabledVulnerabilityScanners().contains(SCA_SCANNER)) { | ||
if(isScaEnabled()) { | ||
scaScanResults = scaScanner.scan(request); | ||
} | ||
ScanResults scanResults = resultsService.joinResults(sastScanResults, scaScanResults); | ||
processResults(request, scanResults); | ||
if(isAstEnabled()) { | ||
astScanResults = astScanner.scan(request); | ||
} | ||
return resultsService.joinResults(sastScanResults, scaScanResults, astScanResults); | ||
} | ||
|
||
private boolean isScaEnabled() { | ||
return flowProperties.getEnabledVulnerabilityScanners().contains(SCA_SCANNER); | ||
} | ||
|
||
private boolean isAstEnabled() { | ||
return flowProperties.getEnabledVulnerabilityScanners().contains(AST_SCANNER); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are there cases when getEnabledVulnerabilityScanners() returns null? |
||
} | ||
|
||
private void cxScan(ScanRequest request, String path) throws ExitThrowable { | ||
ScanResults sastScanResults = null; | ||
ScanResults scaScanResults = null; | ||
|
||
if(ScanUtils.empty(request.getProject())){ | ||
log.error("Please provide --cx-project to define the project in Checkmarx"); | ||
exit(2); | ||
} | ||
if(flowProperties.getEnabledVulnerabilityScanners() == null || | ||
flowProperties.getEnabledVulnerabilityScanners().contains(SAST_SCANNER)) { | ||
ScanResults scanResults = scan(request, path); | ||
processResults(request, scanResults); | ||
} | ||
|
||
private ScanResults scan(ScanRequest request, String path) throws ExitThrowable { | ||
|
||
ScanResults sastScanResults = null; | ||
ScanResults scaScanResults = null; | ||
ScanResults astScanResults = null; | ||
|
||
if(isSastEnabled()) { | ||
sastScanResults = sastScanner.cxFullScan(request, path); | ||
} | ||
if(flowProperties.getEnabledVulnerabilityScanners().contains(SCA_SCANNER)) { | ||
if(isScaEnabled()) { | ||
scaScanResults = scaScanner.scan(request, path); | ||
} | ||
ScanResults scanResults = resultsService.joinResults(sastScanResults, scaScanResults); | ||
processResults(request, scanResults); | ||
if(isAstEnabled()) { | ||
astScanResults = astScanner.scan(request, path); | ||
} | ||
return resultsService.joinResults(sastScanResults, scaScanResults, astScanResults); | ||
} | ||
|
||
private boolean isSastEnabled() { | ||
return flowProperties.getEnabledVulnerabilityScanners() == null || | ||
flowProperties.getEnabledVulnerabilityScanners().contains(SAST_SCANNER); | ||
} | ||
|
||
private void cxOsaParse(ScanRequest request, File file, File libs) throws ExitThrowable { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.checkmarx.flow.service; | ||
|
||
import com.checkmarx.flow.config.FlowProperties; | ||
|
||
import com.checkmarx.sdk.config.AstProperties; | ||
|
||
import com.checkmarx.sdk.dto.ScanResults; | ||
|
||
import com.checkmarx.sdk.dto.ast.ASTResultsWrapper; | ||
|
||
|
||
import com.cx.restclient.AstClientImpl; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
|
||
|
||
@Service | ||
|
||
@Slf4j | ||
public class ASTScanner extends AbstractASTScanner { | ||
|
||
public ASTScanner(AstClientImpl astClient, FlowProperties flowProperties) { | ||
super(astClient, flowProperties, AstProperties.CONFIG_PREFIX); | ||
} | ||
|
||
@Override | ||
protected ScanResults toScanResults(ASTResultsWrapper internalResults) { | ||
return ScanResults.builder() | ||
.astResults(internalResults.getAstResults()) | ||
.build(); | ||
} | ||
|
||
@Override | ||
protected String getScanId(ASTResultsWrapper internalResults) { | ||
return internalResults.getAstResults().getScanId(); | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package com.checkmarx.flow.service; | ||
|
||
import com.checkmarx.flow.config.FlowProperties; | ||
import com.checkmarx.flow.dto.OperationResult; | ||
import com.checkmarx.flow.dto.OperationStatus; | ||
import com.checkmarx.flow.dto.ScanRequest; | ||
import com.checkmarx.flow.dto.report.ScanReport; | ||
import com.checkmarx.flow.exception.ExitThrowable; | ||
import com.checkmarx.flow.exception.MachinaRuntimeException; | ||
import com.checkmarx.flow.utils.ZipUtils; | ||
import com.checkmarx.sdk.dto.ScanResults; | ||
import com.checkmarx.sdk.dto.ast.ASTResults; | ||
import com.checkmarx.sdk.dto.ast.ASTResultsWrapper; | ||
import com.checkmarx.sdk.dto.ast.SCAResults; | ||
import com.checkmarx.sdk.dto.ast.ScanParams; | ||
import com.checkmarx.sdk.service.AstClient; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
|
||
import java.io.File; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
|
||
@Slf4j | ||
public abstract class AbstractASTScanner implements VulnerabilityScanner{ | ||
|
||
private String scanType ; | ||
private com.checkmarx.sdk.service.AstClient client; | ||
private FlowProperties flowProperties; | ||
|
||
public AbstractASTScanner() { | ||
} | ||
|
||
public AbstractASTScanner(AstClient astClient, FlowProperties flowProperties, String scanType) { | ||
this.client = astClient; | ||
this.flowProperties = flowProperties; | ||
this.scanType = scanType; | ||
} | ||
|
||
public ScanResults scan(ScanRequest scanRequest) { | ||
ScanResults result = null; | ||
log.info("--------------------- Initiating new {} scan ---------------------", scanType); | ||
ScanParams internalScaParams = toParams(scanRequest); | ||
ASTResultsWrapper internalResults = new ASTResultsWrapper(new SCAResults(), new ASTResults()); | ||
try { | ||
internalResults = client.scanRemoteRepo(internalScaParams); | ||
logRequest(scanRequest, getScanId(internalResults), OperationResult.successful()); | ||
result = toScanResults(internalResults); | ||
} catch (Exception e) { | ||
final String message = "SCA scan failed."; | ||
log.error(message, e); | ||
OperationResult scanCreationFailure = new OperationResult(OperationStatus.FAILURE, e.getMessage()); | ||
logRequest(scanRequest, getScanId(internalResults), scanCreationFailure); | ||
throw new MachinaRuntimeException(message); | ||
Comment on lines
+56
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please resolve this code duplication. |
||
} | ||
return result; | ||
} | ||
|
||
public ScanResults scan(ScanRequest scanRequest, String path) throws ExitThrowable { | ||
ScanResults result; | ||
log.info("--------------------- Initiating new {} scan ---------------------", scanType); | ||
ASTResultsWrapper internalResults = new ASTResultsWrapper(new SCAResults(), new ASTResults()); | ||
|
||
try { | ||
String cxZipFile = FileSystems.getDefault().getPath("cx.".concat(UUID.randomUUID().toString()).concat(".zip")).toAbsolutePath().toString(); | ||
ZipUtils.zipFile(path, cxZipFile, flowProperties.getZipExclude()); | ||
File f = new File(cxZipFile); | ||
log.debug("Creating temp file {}", f.getPath()); | ||
log.debug("free space {}", f.getFreeSpace()); | ||
log.debug("total space {}", f.getTotalSpace()); | ||
log.debug(f.getAbsolutePath()); | ||
ScanParams internalScaParams = toParams(scanRequest, cxZipFile); | ||
|
||
internalResults = client.scanLocalSource(internalScaParams); | ||
logRequest(scanRequest, getScanId(internalResults), OperationResult.successful()); | ||
result = toScanResults(internalResults); | ||
|
||
log.debug("Deleting temp file {}", f.getPath()); | ||
Files.deleteIfExists(Paths.get(cxZipFile)); | ||
|
||
} catch (Exception e) { | ||
final String message = "SCA scan failed."; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like 'scanType' should be used here instead of SCA. |
||
log.error(message, e); | ||
OperationResult scanCreationFailure = new OperationResult(OperationStatus.FAILURE, e.getMessage()); | ||
logRequest(scanRequest, getScanId(internalResults), scanCreationFailure); | ||
throw new MachinaRuntimeException(message); | ||
} | ||
return result; | ||
} | ||
|
||
protected abstract String getScanId(ASTResultsWrapper internalResults) ; | ||
|
||
private ScanParams toParams(ScanRequest scanRequest, String zipPath) { | ||
return ScanParams.builder() | ||
.projectName(scanRequest.getProject()) | ||
.zipPath(zipPath) | ||
.build(); | ||
} | ||
|
||
protected abstract ScanResults toScanResults(ASTResultsWrapper internalResults); | ||
|
||
|
||
protected ScanParams toParams(ScanRequest scanRequest) { | ||
URL parsedUrl = getRepoUrl(scanRequest); | ||
|
||
return ScanParams.builder() | ||
.projectName(scanRequest.getProject()) | ||
.remoteRepoUrl(parsedUrl) | ||
.build(); | ||
} | ||
|
||
|
||
|
||
|
||
private URL getRepoUrl(ScanRequest scanRequest) { | ||
URL parsedUrl; | ||
try { | ||
parsedUrl = new URL(scanRequest.getRepoUrlWithAuth()); | ||
} catch (MalformedURLException e) { | ||
log.error("Failed to parse repository URL: '{}'", scanRequest.getRepoUrl()); | ||
throw new MachinaRuntimeException("Invalid repository URL."); | ||
} | ||
return parsedUrl; | ||
} | ||
|
||
@Override | ||
public boolean isEnabled() { | ||
List<String> enabledScanners = flowProperties.getEnabledVulnerabilityScanners(); | ||
|
||
return enabledScanners != null | ||
&& enabledScanners.stream().anyMatch(scanner -> scanner.equalsIgnoreCase(scanType)); | ||
|
||
} | ||
|
||
private void logRequest(ScanRequest request, String scanId, OperationResult scanCreationResult) { | ||
ScanReport report = new ScanReport(scanId, request,request.getRepoUrl(), scanCreationResult, ScanReport.SCA); | ||
report.log(); | ||
} | ||
|
||
|
||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a more meaningful name instead of cxScan()? It's not clear by looking at the code what is the difference between cxScan() and scan().