diff --git a/pom.xml b/pom.xml
index 89528757..5babc530 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
com.hcl
appscan.sdk
- 1.0.37-SNAPSHOT
+ 1.0.38-SNAPSHOT
HCL AppScan on Cloud SDK
SDK for interacting with HCL AppScan on Cloud
diff --git a/src/main/java/com/hcl/appscan/sdk/CoreConstants.java b/src/main/java/com/hcl/appscan/sdk/CoreConstants.java
index 26746c2e..2ebef0be 100644
--- a/src/main/java/com/hcl/appscan/sdk/CoreConstants.java
+++ b/src/main/java/com/hcl/appscan/sdk/CoreConstants.java
@@ -29,7 +29,10 @@ public interface CoreConstants {
String VERSION_NUMBER = "VersionNumber"; //$NON-NLS-1$
String USER_MESSAGE = "UserMessage"; //$NON-NLS-1$
String IS_VALID = "IsValid"; //$NON-NLS-1$
- String SOURCE_CODE_ONLY = "sourceCodeOnly"; //$NON-NLS-1$
+ String SOURCE_CODE_ONLY = "sourceCodeOnly"; //$NON-NLS-1$
+ String SOFTWARE_COMPOSITION_ANALYZER = "Software Composition Analyzer"; //$NON-NLS-1$
+ String SCA = "Sca"; //$NON-NLS-1$
+
String CREATE_IRX = "createIRX"; //$NON-NLS-1$
String UPLOAD_DIRECT = "uploadDirect"; //$NON-NLS-1$
String BINDING_ID = "Bindingid"; //$NON-NLS-1$
@@ -50,6 +53,7 @@ public interface CoreConstants {
String CLIENT_TYPE = "ClientType"; //$NON-NLS-1$
String API_ENV = "/api/v2"; //$NON-NLS-1$
+ String API_ENV_V4 = "/api/v4"; //$NON-NLS-1$
String API_BLUEMIX = "Bluemix"; //$NON-NLS-1$
String API_BLUEMIX_LOGIN = API_ENV + "/Account/BluemixLogin"; //$NON-NLS-1$
String API_KEY_LOGIN = API_ENV + "/Account/ApiKeyLogin"; //$NON-NLS-1$
@@ -63,6 +67,7 @@ public interface CoreConstants {
String API_FILE_UPLOAD = API_ENV + "/FileUpload"; //$NON-NLS-1$
String API_SCAN = API_ENV + "/%s"; //$NON-NLS-1$
String API_SCANNER = API_ENV + "/Scans/%s"; //$NON-NLS-1$
+ String API_SCANNER_V4 = API_ENV_V4 + "/Scans/%s"; //$NON-NLS-1$
String API_SCANS = API_ENV + "/Scans"; //$NON-NLS-1$
String API_NONCOMPLIANT_ISSUES = API_ENV + "/Scans/%s/NonCompliantIssues"; //$NON-NLS-1$
String API_SCANS_REPORT = API_ENV + "/Scans/%s/Report/%s"; //$NON-NLS-1$
diff --git a/src/main/java/com/hcl/appscan/sdk/http/HttpClient.java b/src/main/java/com/hcl/appscan/sdk/http/HttpClient.java
index 8db16a6e..0ba6ed86 100644
--- a/src/main/java/com/hcl/appscan/sdk/http/HttpClient.java
+++ b/src/main/java/com/hcl/appscan/sdk/http/HttpClient.java
@@ -6,6 +6,9 @@
package com.hcl.appscan.sdk.http;
+import org.apache.wink.json4j.JSON;
+import org.apache.wink.json4j.JSONObject;
+
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -16,6 +19,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -105,6 +109,39 @@ public HttpResponse post(String url,
return makeRequest(Method.POST, url, headerProperties, body);
}
+ /**
+ * Submit a post request.
+ *
+ * @param url The URL string.
+ * @param headerProperties An optional Map of header properties.
+ * @param params An optional Map of properties.
+ * @return The response as a byte array.
+ * @throws IOException If an error occurs.
+ */
+ public HttpResponse post(String url, Map headerProperties, Map params)
+ throws IOException {
+ Map objectMap = new HashMap<>();
+ for (String key : params.keySet()) {
+ String value = params.get(key);
+ if (value != null) {
+ if (value.equalsIgnoreCase("true")) {
+ objectMap.put(key, true);
+ } else if (value.equalsIgnoreCase("false")) {
+ objectMap.put(key, false);
+ } else {
+ // If the string is not "true" or "false," keep it as is
+ objectMap.put(key, value);
+ }
+ } else {
+ // If the value is not a string, keep it as is
+ objectMap.put(key, value);
+ }
+ }
+ JSONObject json = new JSONObject(objectMap);
+ String body = json.toString();
+ return post(url, headerProperties, body);
+ }
+
/**
* Submit a put request.
*
diff --git a/src/main/java/com/hcl/appscan/sdk/messages.properties b/src/main/java/com/hcl/appscan/sdk/messages.properties
index 60dcda51..28d71042 100644
--- a/src/main/java/com/hcl/appscan/sdk/messages.properties
+++ b/src/main/java/com/hcl/appscan/sdk/messages.properties
@@ -50,8 +50,8 @@ error.dom.state=Bad DOM state.
error.http=Response Code: {0}\nReason: {1}
error.login.type.deprectated=The specified login type is deprecated. Please use API key and secret.
error.getting.info=An error occurred getting information for {0} with id {1}.
-error.url.validation = An error occurred while validating the URL.
error.getting.scanlog=An error occurred retrieving the scan log.
+error.url.validation = An error occurred while validating the Starting URL: {0}.
#Presence
error.getting.presence.details=An error occurred retrieving details for Presence with id {0}.
@@ -71,4 +71,4 @@ error.update.job=An error occurred updating the job. {0}
message.running.job=Executing job...
message.executed.job=Job executed successfully.
error.execute.job=An error occurred executing the job. {0}
-error.invalid.details=The job details contain missing or invalid parameters.
\ No newline at end of file
+error.invalid.details=The job details contain missing or invalid parameters.
diff --git a/src/main/java/com/hcl/appscan/sdk/scan/CloudScanServiceProvider.java b/src/main/java/com/hcl/appscan/sdk/scan/CloudScanServiceProvider.java
index 0e4438e2..bab842b8 100644
--- a/src/main/java/com/hcl/appscan/sdk/scan/CloudScanServiceProvider.java
+++ b/src/main/java/com/hcl/appscan/sdk/scan/CloudScanServiceProvider.java
@@ -48,50 +48,60 @@ public CloudScanServiceProvider(IProgress progress, IAuthenticationProvider auth
m_progress = progress;
m_authProvider = authProvider;
}
-
- @Override
- public String createAndExecuteScan(String type, Map params) {
- if(loginExpired() || !verifyApplication(params.get(APP_ID)))
- return null;
-
- m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(EXECUTING_SCAN)));
-
- String request_url = m_authProvider.getServer() + String.format(API_SCANNER, type);
- Map request_headers = m_authProvider.getAuthorizationHeader(true);
-
- HttpClient client = new HttpClient(m_authProvider.getProxy(), m_authProvider.getacceptInvalidCerts());
-
- try {
- HttpResponse response = client.postForm(request_url, request_headers, params);
- int status = response.getResponseCode();
-
- JSONObject json = (JSONObject) response.getResponseBodyAsJSON();
-
- if (status == HttpsURLConnection.HTTP_CREATED) {
- m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(CREATE_SCAN_SUCCESS)));
- return json.getString(ID);
- }
- else if (json != null && json.has(MESSAGE)) {
- String errorResponse = json.getString(MESSAGE);
- if(json.has(FORMAT_PARAMS)) {
- JSONArray jsonArray = json.getJSONArray(FORMAT_PARAMS);
- if(jsonArray != null){
- String[] messageParams = new String[jsonArray.size()];
- for (int i = 0; i < jsonArray.size(); i++) {
- messageParams[i] = (String)jsonArray.get(i);
- }
- errorResponse = MessageFormat.format(errorResponse, (Object[]) messageParams);
- }
+
+ @Override
+ public String createAndExecuteScan(String type, Map params) {
+ if(loginExpired() || !verifyApplication(params.get(APP_ID)))
+ return null;
+
+ m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(EXECUTING_SCAN)));
+ Map request_headers = m_authProvider.getAuthorizationHeader(true);
+ HttpClient client = new HttpClient(m_authProvider.getProxy(), m_authProvider.getacceptInvalidCerts());
+
+ try {
+ HttpResponse response;
+ if(shouldUseV4Api(type)) {
+ request_headers.put("Content-Type", "application/json");
+ request_headers.put("accept", "application/json");
+ String request_url = m_authProvider.getServer() + String.format(API_SCANNER_V4, type);
+ response = client.post(request_url,request_headers,params);
+ } else {
+ String request_url = m_authProvider.getServer() + String.format(API_SCANNER, type);
+ response = client.postForm(request_url,request_headers,params);
+ }
+
+ int status = response.getResponseCode();
+
+ JSONObject json = (JSONObject) response.getResponseBodyAsJSON();
+
+ if (status == HttpsURLConnection.HTTP_CREATED || status == HttpsURLConnection.HTTP_OK) {
+ m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(CREATE_SCAN_SUCCESS)));
+ return json.getString(ID);
+ } else if (json != null && json.has(MESSAGE)) {
+ String errorResponse = json.getString(MESSAGE);
+ if(json.has(FORMAT_PARAMS) && !json.isNull(FORMAT_PARAMS)) {
+ JSONArray jsonArray = json.getJSONArray(FORMAT_PARAMS);
+ if(jsonArray != null){
+ String[] messageParams = new String[jsonArray.size()];
+ for (int i = 0; i < jsonArray.size(); i++) {
+ messageParams[i] = (String)jsonArray.get(i);
+ }
+ errorResponse = MessageFormat.format(errorResponse, (Object[]) messageParams);
+ }
}
- m_progress.setStatus(new Message(Message.ERROR, errorResponse));
- }
- else
- m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_SUBMITTING_SCAN, status)));
- } catch(IOException | JSONException e) {
- m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_SUBMITTING_SCAN, e.getLocalizedMessage())));
- }
- return null;
- }
+ m_progress.setStatus(new Message(Message.ERROR, errorResponse));
+ }
+ else
+ m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_SUBMITTING_SCAN, status)));
+ } catch(IOException | JSONException e) {
+ m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_SUBMITTING_SCAN, e.getLocalizedMessage())));
+ }
+ return null;
+ }
+
+ private boolean shouldUseV4Api(String type) {
+ return type.equals(CoreConstants.SCA);
+ }
@Override
public String submitFile(File file) throws IOException {
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTConstants.java b/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTConstants.java
index d797ccd9..70383b5b 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTConstants.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTConstants.java
@@ -13,6 +13,7 @@ public interface DASTConstants {
String DYNAMIC_ANALYZER_WITH_FILE = "DynamicAnalyzerWithFile"; //$NON-NLS-1$
String SCAN_FILE = "ScanFile"; //$NON-NLS-1$
String SCAN_FILE_ID = "ScanFileId"; //$NON-NLS-1$
+ String PRESENCE_ID = "PresenceId"; //$NON-NLS-1$
String STARTING_URL = "StartingUrl"; //$NON-NLS-1$
String TRAFFIC_FILE = "trafficFile";
String TRAFFIC_FILE_ID = "LoginSequenceFileId";
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTScan.java b/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTScan.java
index 2ae76361..cbe808b4 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTScan.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/dynamic/DASTScan.java
@@ -12,6 +12,7 @@
import com.hcl.appscan.sdk.CoreConstants;
import com.hcl.appscan.sdk.Messages;
+import com.hcl.appscan.sdk.auth.IAuthenticationProvider;
import com.hcl.appscan.sdk.error.InvalidTargetException;
import com.hcl.appscan.sdk.error.ScannerException;
import com.hcl.appscan.sdk.logging.DefaultProgress;
@@ -44,9 +45,10 @@ public void run() throws ScannerException, InvalidTargetException {
Map params = getProperties();
params.put(STARTING_URL, target);
- if(!ServiceUtil.isValidUrl(params.get(STARTING_URL),getServiceProvider().getAuthenticationProvider())) {
- throw new ScannerException(Messages.getMessage(CoreConstants.ERROR_URL_VALIDATION));
- }
+ IAuthenticationProvider authProvider = getServiceProvider().getAuthenticationProvider();
+ if(params.get(PRESENCE_ID).isEmpty() && !ServiceUtil.isValidUrl(target, authProvider, authProvider.getProxy())) {
+ throw new ScannerException(Messages.getMessage(CoreConstants.ERROR_URL_VALIDATION, target));
+ }
String scanLoginType = null;
if (params.get(LOGIN_TYPE) != null) {
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SAClient.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SAClient.java
index 4caef49e..da7c92f0 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SAClient.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SAClient.java
@@ -326,12 +326,16 @@ private List getClientArgs(Map properties) {
args.add(OPT_VERBOSE);
if(properties.containsKey(THIRD_PARTY) || System.getProperty(THIRD_PARTY) != null)
args.add(OPT_THIRD_PARTY);
- if (properties.containsKey(OPEN_SOURCE_ONLY) || System.getProperty(OPEN_SOURCE_ONLY) != null)
+ if (properties.containsKey(OPEN_SOURCE_ONLY) || System.getProperty(OPEN_SOURCE_ONLY) != null || properties.get(CoreConstants.SCANNER_TYPE).equals(CoreConstants.SOFTWARE_COMPOSITION_ANALYZER))
args.add(OPT_OPEN_SOURCE_ONLY);
if (properties.containsKey(SOURCE_CODE_ONLY) || System.getProperty(SOURCE_CODE_ONLY) != null)
args.add(OPT_SOURCE_CODE_ONLY);
if(properties.containsKey(SCAN_SPEED)){
args.add(OPT_SCAN_SPEED);
+ if(properties.containsKey(SECRETS_ENABLED) || System.getProperty(SECRETS_ENABLED) != null)
+ args.add(OPT_SECRETS_ENABLED);
+ if(properties.containsKey(SECRETS_ONLY) || System.getProperty(SECRETS_ONLY) != null)
+ args.add(OPT_SECRETS_ONLY);
//it is being used to have the same values in the freestyle & pipeline projects
if(properties.get(SCAN_SPEED).equals(NORMAL)){
args.add(THOROUGH);
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTConstants.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTConstants.java
index d0d81789..553bcf9a 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTConstants.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTConstants.java
@@ -14,7 +14,8 @@ public interface SASTConstants {
String APPSCAN_CLIENT_VERSION = "APPSCAN_CLIENT_VERSION"; //$NON-NLS-1$
String IRGEN_CLIENT_PLUGIN_VERSION = "IRGEN_CLIENT_PLUGIN_VERSION"; //$NON-NLS-1$
String ARSA_FILE_ID = "ARSAFileId"; //$NON-NLS-1$
- String WIN_SCRIPT = "appscan.bat"; //$NON-NLS-1$
+ String FILE_ID = "ApplicationFileId"; //$NON-NLS-1$
+ String WIN_SCRIPT = "appscan.bat"; //$NON-NLS-1$
String UNIX_SCRIPT = "appscan.sh"; //$NON-NLS-1$
String IRX_EXTENSION = ".irx"; //$NON-NLS-1$
@@ -32,6 +33,8 @@ public interface SASTConstants {
String THIRD_PARTY = "thirdParty"; //$NON-NLS-1$
String OPEN_SOURCE_ONLY = "openSourceOnly"; //$NON-NLS-1$
String SOURCE_CODE_ONLY = "sourceCodeOnly"; //$NON-NLS-1$
+ String SECRETS_ENABLED = "enableSecrets"; //$NON-NLS-1$
+ String SECRETS_ONLY = "secretsOnly"; //$NON-NLS-1$
String SCAN_SPEED = "scanSpeed"; //$NON-NLS-1$
String OPT_SCAN_SPEED = "-s"; //$NON-NLS-1$
String OPT_NAME = "-n"; //$NON-NLS-1$
@@ -50,7 +53,10 @@ public interface SASTConstants {
String OPT_VERBOSE = "-v"; //$NON-NLS-1$
String OPT_DEBUG = "-X"; //$NON-NLS-1$
String OPT_OPEN_SOURCE_ONLY = "-oso"; //$NON-NLS-1$
- String OPT_SOURCE_CODE_ONLY = "-sco"; //$NON-NLS-1$
+ String OPT_SOURCE_CODE_ONLY = "-sco"; //$NON-NLS-1$
+ String OPT_SECRETS_ENABLED = "-es"; //$NON-NLS-1$
+ String OPT_SECRETS_ONLY = "-so"; //$NON-NLS-1$
+
//Messages
String DONE = "message.done"; //$NON-NLS-1$
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScan.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScan.java
index 563081b8..bc5e9563 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScan.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScan.java
@@ -73,7 +73,7 @@ public File getIrx() {
return m_irx;
}
- private void generateIR() throws IOException, ScannerException {
+ protected void generateIR() throws IOException, ScannerException {
File targetFile = new File(getTarget());
//If we were given an irx file, don't generate a new one
@@ -108,7 +108,7 @@ private void generateZip() throws IOException,ScannerException {
throw new ScannerException(Messages.getMessage(ERROR_GENERATING_ZIP, getScanLogs().getAbsolutePath()));
}
- private void analyzeIR() throws IOException, ScannerException {
+ protected void analyzeIR() throws IOException, ScannerException {
if(getProperties().containsKey(PREPARE_ONLY))
return;
@@ -117,12 +117,16 @@ private void analyzeIR() throws IOException, ScannerException {
throw new ScannerException(Messages.getMessage(ERROR_FILE_UPLOAD, m_irx.getName()));
Map params = getProperties();
- params.put(ARSA_FILE_ID, fileId);
-
- setScanId(getServiceProvider().createAndExecuteScan(STATIC_ANALYZER, params));
+ params.put(FILE_ID, fileId);
+
+ submitScan();
if(getScanId() == null)
throw new ScannerException(Messages.getMessage(ERROR_SUBMITTING_IRX));
}
+
+ protected void submitScan() {
+ setScanId(getServiceProvider().createAndExecuteScan(STATIC_ANALYZER, getProperties()));
+ }
private File getScanLogs() {
if(m_irx == null) {
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScanManager.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScanManager.java
index 4fef41d6..269b6016 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScanManager.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScanManager.java
@@ -37,6 +37,8 @@ public class SASTScanManager implements IScanManager{
private boolean m_isOpenSourceOnlyEnabled = false;
private boolean m_isSourceCodeOnlyEnabled = false;
private boolean m_isStaticAnalysisOnlyEnabled = false;
+ private boolean m_isSecretsScanningEnabled = false;
+ private boolean m_isSecretsScanningOnlyEnabled = false;
public SASTScanManager(String workingDir) {
m_workingDirectory = workingDir;
@@ -107,6 +109,22 @@ public void setIsThirdPartyScanningEnabled(boolean isThirdPartyScanningEnabled)
m_isThirdPartyScanningEnabled = isThirdPartyScanningEnabled;
}
+ /**
+ * Enables scanning for secrets.
+ * @param isSecretsScanningEnabled - True to scan for secrets vulnerabilities.
+ */
+ public void setIsSecretsScanningEnabled(boolean isSecretsScanningEnabled) {
+ m_isSecretsScanningEnabled = isSecretsScanningEnabled;
+ }
+
+ /**
+ * Only scan for secrets.
+ * @param isSecretsScanningOnlyEnabled - True to only scan for secrets vulnerabilities.
+ */
+ public void setIsSecretsScanningOnlyEnabled(boolean isSecretsScanningOnlyEnabled) {
+ m_isSecretsScanningOnlyEnabled = isSecretsScanningOnlyEnabled;
+ }
+
/**
* Only scan for known vulnerabilities in 3rd party libraries. Disables static analysis.
* @param isOpenSourceOnlyEnabled - True to scan only for known vulnerabilities in 3rd party libraries.
@@ -141,7 +159,7 @@ public void createConfig(boolean useRelativeTargetPaths) throws AppScanException
try {
ModelWriter writer = new XmlWriter(useRelativeTargetPaths);
writer.initWriters(new File(m_workingDirectory));
- writer.visit(m_targets, m_isThirdPartyScanningEnabled, m_isOpenSourceOnlyEnabled, m_isSourceCodeOnlyEnabled, m_isStaticAnalysisOnlyEnabled);
+ writer.visit(m_targets, m_isThirdPartyScanningEnabled, m_isOpenSourceOnlyEnabled, m_isSourceCodeOnlyEnabled, m_isStaticAnalysisOnlyEnabled, m_isSecretsScanningEnabled, m_isSecretsScanningOnlyEnabled);
writer.write();
} catch (IOException | TransformerException e) {
throw new AppScanException(e.getLocalizedMessage(), e);
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/IModelXMLConstants.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/IModelXMLConstants.java
index f3c2c763..a7e86076 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/IModelXMLConstants.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/IModelXMLConstants.java
@@ -24,6 +24,8 @@ public interface IModelXMLConstants {
String A_OPEN_SOURCE_ONLY = "openSourceOnly"; //$NON-NLS-1$
String A_SOURCE_CODE_ONLY = "sourceCodeOnly"; //$NON-NLS-1$
String A_STATIC_ANALYSIS_ONLY = "staticAnalysisOnly"; //$NON-NLS-1$
+ String A_SECRETS_ENABLED = "enableSecrets"; //$NON-NLS-1$
+ String A_SECRETS_ONLY = "secretsOnly"; //$NON-NLS-1$
//Java
String A_PATH = "path"; //$NON-NLS-1$
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/ModelWriter.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/ModelWriter.java
index ff6c2911..8c658f99 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/ModelWriter.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/ModelWriter.java
@@ -120,5 +120,5 @@ private void initDocumentBuilder() throws ParserConfigurationException {
public abstract String getOutputLocation();
- public abstract void visit(List targets, boolean isThirdPartyScanningEnabled, boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled);
+ public abstract void visit(List targets, boolean isThirdPartyScanningEnabled, boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled, boolean isSecretsScanningEnabled, boolean isSecretsScanningOnlyEnabled);
}
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/XmlWriter.java b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/XmlWriter.java
index a3a1eabf..df3d02bb 100644
--- a/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/XmlWriter.java
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sast/xml/XmlWriter.java
@@ -52,7 +52,7 @@ public void initWriters(File directory) throws IOException {
@Override
public void visit(List targets, boolean isThirdPartyScanningEnabled,
- boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled) {
+ boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled, boolean isSecretsScanningEnabled, boolean isSecretsScanningOnlyEnabled) {
m_config.beginElement(E_CONFIGURATION);
if (isThirdPartyScanningEnabled) {
@@ -71,6 +71,14 @@ public void visit(List targets, boolean isThirdPartyScanningEnabled
m_config.setAttribute(A_STATIC_ANALYSIS_ONLY, "true");
}
+ if (isSecretsScanningEnabled) {
+ m_config.setAttribute(A_SECRETS_ENABLED, "true");
+ }
+
+ if (isSecretsScanningOnlyEnabled) {
+ m_config.setAttribute(A_SECRETS_ONLY, "true");
+ }
+
m_config.beginElement(E_TARGETS);
for (ISASTTarget target: targets){
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScan.java b/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScan.java
new file mode 100644
index 00000000..fa779925
--- /dev/null
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScan.java
@@ -0,0 +1,53 @@
+/**
+ * © Copyright HCL Technologies Ltd. 2023.
+ * LICENSE: Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+package com.hcl.appscan.sdk.scanners.sca;
+
+import com.hcl.appscan.sdk.CoreConstants;
+import com.hcl.appscan.sdk.Messages;
+import com.hcl.appscan.sdk.error.InvalidTargetException;
+import com.hcl.appscan.sdk.error.ScannerException;
+import com.hcl.appscan.sdk.logging.IProgress;
+import com.hcl.appscan.sdk.scan.IScanServiceProvider;
+import com.hcl.appscan.sdk.scanners.sast.SASTConstants;
+import com.hcl.appscan.sdk.scanners.sast.SASTScan;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+public class SCAScan extends SASTScan implements SASTConstants {
+ private static final long serialVersionUID = 1L;
+ private static final String REPORT_FORMAT = "html"; //$NON-NLS-1$
+
+ public SCAScan(Map properties, IProgress progress, IScanServiceProvider provider) {
+ super(properties, progress, provider);
+ }
+
+ @Override
+ public void run() throws ScannerException, InvalidTargetException {
+ String target = getTarget();
+
+ if(target == null || !(new File(target).exists()))
+ throw new InvalidTargetException(Messages.getMessage(TARGET_INVALID, target));
+
+ try {
+ generateIR();
+ analyzeIR();
+ } catch(IOException e) {
+ throw new ScannerException(Messages.getMessage(SCAN_FAILED, e.getLocalizedMessage()));
+ }
+ }
+
+ @Override
+ public String getType() {
+ return CoreConstants.SOFTWARE_COMPOSITION_ANALYZER;
+ }
+
+ @Override
+ protected void submitScan() {
+ setScanId(getServiceProvider().createAndExecuteScan(CoreConstants.SCA, getProperties()));
+ }
+}
diff --git a/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScanFactory.java b/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScanFactory.java
new file mode 100644
index 00000000..b6c65743
--- /dev/null
+++ b/src/main/java/com/hcl/appscan/sdk/scanners/sca/SCAScanFactory.java
@@ -0,0 +1,30 @@
+/**
+ * © Copyright HCL Technologies Ltd. 2023.
+ * LICENSE: Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0
+ */
+
+package com.hcl.appscan.sdk.scanners.sca;
+
+import com.hcl.appscan.sdk.CoreConstants;
+import com.hcl.appscan.sdk.auth.IAuthenticationProvider;
+import com.hcl.appscan.sdk.logging.IProgress;
+import com.hcl.appscan.sdk.scan.CloudScanServiceProvider;
+import com.hcl.appscan.sdk.scan.IScan;
+import com.hcl.appscan.sdk.scan.IScanFactory;
+import com.hcl.appscan.sdk.scan.IScanServiceProvider;
+
+import java.util.Map;
+
+public class SCAScanFactory implements IScanFactory {
+
+ @Override
+ public IScan create(Map properties, IProgress progress, IAuthenticationProvider authProvider) {
+ IScanServiceProvider serviceProvider = new CloudScanServiceProvider(progress, authProvider);
+ return new SCAScan(properties, progress, serviceProvider);
+ }
+
+ @Override
+ public String getType() {
+ return CoreConstants.SOFTWARE_COMPOSITION_ANALYZER;
+ }
+}
diff --git a/src/main/resources/META-INF/services/com.hcl.appscan.sdk.scan.IScanFactory b/src/main/resources/META-INF/services/com.hcl.appscan.sdk.scan.IScanFactory
index 787212cc..73000193 100644
--- a/src/main/resources/META-INF/services/com.hcl.appscan.sdk.scan.IScanFactory
+++ b/src/main/resources/META-INF/services/com.hcl.appscan.sdk.scan.IScanFactory
@@ -1,3 +1,4 @@
com.hcl.appscan.sdk.scanners.sast.SASTScanFactory
com.hcl.appscan.sdk.scanners.dynamic.DASTScanFactory
com.hcl.appscan.sdk.scanners.ase.ASEScanFactory
+com.hcl.appscan.sdk.scanners.sca.SCAScanFactory