Skip to content

Commit

Permalink
Merge branch 'master' into ASPL-542
Browse files Browse the repository at this point in the history
  • Loading branch information
mvjainhcl authored Dec 13, 2023
2 parents 0ebae92 + 87bf9f9 commit efa52b9
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 61 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.hcl</groupId>
<artifactId>appscan.sdk</artifactId>
<version>1.0.37-SNAPSHOT</version>
<version>1.0.38-SNAPSHOT</version>

<name>HCL AppScan on Cloud SDK</name>
<description>SDK for interacting with HCL AppScan on Cloud</description>
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/hcl/appscan/sdk/CoreConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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$
Expand All @@ -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$
Expand All @@ -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$
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/hcl/appscan/sdk/http/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<String, String> headerProperties, Map<String, String> params)
throws IOException {
Map<String, Object> 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.
*
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/hcl/appscan/sdk/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
Expand All @@ -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.
error.invalid.details=The job details contain missing or invalid parameters.
Original file line number Diff line number Diff line change
Expand Up @@ -48,50 +48,60 @@ public CloudScanServiceProvider(IProgress progress, IAuthenticationProvider auth
m_progress = progress;
m_authProvider = authProvider;
}

@Override
public String createAndExecuteScan(String type, Map<String, String> 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<String, String> 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<String, String> params) {
if(loginExpired() || !verifyApplication(params.get(APP_ID)))
return null;

m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(EXECUTING_SCAN)));
Map<String, String> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,9 +45,10 @@ public void run() throws ScannerException, InvalidTargetException {
Map<String, String> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,16 @@ private List<String> getClientArgs(Map<String, String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$
Expand All @@ -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$
Expand All @@ -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$
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/com/hcl/appscan/sdk/scanners/sast/SASTScan.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -117,12 +117,16 @@ private void analyzeIR() throws IOException, ScannerException {
throw new ScannerException(Messages.getMessage(ERROR_FILE_UPLOAD, m_irx.getName()));

Map<String, String> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,5 @@ private void initDocumentBuilder() throws ParserConfigurationException {

public abstract String getOutputLocation();

public abstract void visit(List<ISASTTarget> targets, boolean isThirdPartyScanningEnabled, boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled);
public abstract void visit(List<ISASTTarget> targets, boolean isThirdPartyScanningEnabled, boolean isOpenSourceOnlyEnabled, boolean isSourceCodeOnlyEnabled, boolean isStaticAnalysisOnlyEnabled, boolean isSecretsScanningEnabled, boolean isSecretsScanningOnlyEnabled);
}
Loading

0 comments on commit efa52b9

Please sign in to comment.