Skip to content

Commit

Permalink
SECURITY-3144
Browse files Browse the repository at this point in the history
  • Loading branch information
tmoreland-r7 committed Mar 1, 2024
1 parent b62926c commit 1677f09
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 134 deletions.
55 changes: 34 additions & 21 deletions pom.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.40</version>
<version>4.52</version>
<relativePath />
</parent>

Expand All @@ -23,29 +24,30 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.11.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>

<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.0.0</version>
<version>4.8.1.0</version>
<dependencies>
<!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>4.7.0</version>
<version>4.8.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.23</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
Expand Down Expand Up @@ -77,13 +79,14 @@
<connection>scm:git:git://github.com/jenkinsci/appspider-build-scanner-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/appspider-build-scanner-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/appspider-build-scanner-plugin.git</url>
<tag>jenkinsci-appspider-plugin-1.0.12</tag>
<tag>jenkinsci-appspider-plugin-1.0.16</tag>
</scm>

<!-- Turning off doclint -->
<properties>
<additionalparam>-Xdoclint:none</additionalparam>
<jenkins.version>2.348</jenkins.version>
<jenkins.version>2.375.1</jenkins.version>
<maven.compiler.release>11</maven.compiler.release>
</properties>

<repositories>
Expand Down Expand Up @@ -112,13 +115,13 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.3.3</version>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -130,7 +133,7 @@
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
<version>20231013</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
Expand All @@ -147,26 +150,36 @@
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
<artifactId>httpmime</artifactId>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.16</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
Expand Down Expand Up @@ -200,7 +213,7 @@
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
<version>1.16.0</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/com/rapid7/appspider/ApiSerializer.java
Expand Up @@ -8,6 +8,7 @@
import com.rapid7.appspider.datatransferobjects.ScanResult;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import hudson.model.Api;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
Expand All @@ -18,13 +19,17 @@
import java.net.URL;
import java.util.*;

public class ApiSerializer {
public final class ApiSerializer {

private final LoggerFacade logger;

public ApiSerializer(LoggerFacade logger) {
if (logger == null)
public static ApiSerializer createInstanceOrThrow(LoggerFacade logger) {
if (logger == null) {
throw new IllegalArgumentException("logger cannot be null");
}
return new ApiSerializer(logger);
}
private ApiSerializer(LoggerFacade logger) {
this.logger = logger;
}

Expand Down Expand Up @@ -67,7 +72,7 @@ public boolean getIsSuccess(JSONObject jsonObject) {

public ScanResult getScanResult(JSONObject jsonObject) {
try {
return new ScanResult(jsonObject);
return ScanResult.createInstanceFromJsonOrThrow(jsonObject);
} catch (IllegalArgumentException e) {
logger.severe(e.toString());
return new ScanResult(false, "");
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/com/rapid7/appspider/ContentHelper.java
Expand Up @@ -25,18 +25,20 @@
import java.util.Objects;
import java.util.Optional;

import static com.rapid7.appspider.Utility.isSuccessStatusCode;

/**
* parsing and serializing helper methods for handling JSONObject manipulation
*/
public class ContentHelper {

private final LoggerFacade logger;

public ContentHelper(LoggerFacade logger) {
public static ContentHelper createInstanceOrThrow(LoggerFacade logger) {
if (Objects.isNull(logger))
throw new IllegalArgumentException("logger cannot be null");
return new ContentHelper(logger);
}

private ContentHelper(LoggerFacade logger) {
this.logger = logger;
}

Expand Down Expand Up @@ -111,11 +113,11 @@ public NameValuePair pairFrom(String key, String value) {
* @return on success an Optional containing a JSONObject; otherwise, Optional.empty()
*/
public Optional<JSONObject> responseToJSONObject(HttpResponse response, String path) {
if (isSuccessStatusCode(response)) {
if (FunctionalUtility.isSuccessStatusCode(response)) {
return asJson(response.getEntity());
}

logResponseFailure("request failed", response);
logResponseFailure("request failed " + path, response);
return Optional.empty();
}

Expand All @@ -140,8 +142,8 @@ public Optional<JSONObject> asJson(HttpEntity entity) {
* @param key key in the json object to serve as key in the map
* @param value value in the json object to serve as value in the map
* @param optionalJsonObject Optional{JSONObject} to extract key/value pairs from if present
* @return on successs a Map{String, String} of key/value pairs from JSONObject;
* otherwiwse Optional.empty()
* @return on successes a Map{String, String} of key/value pairs from JSONObject;
* otherwise Optional.empty()
*/
public Optional<Map<String, String>> asMapOfStringToString(String key, String value, Optional<JSONObject> optionalJsonObject) {
return optionalJsonObject.flatMap(json ->
Expand Down
Expand Up @@ -13,7 +13,7 @@
import java.util.Optional;
import java.util.concurrent.TimeUnit;

public class Scan {
public class DastScan {
private static final String SUCCESSFUL_SCAN = "Completed|Stopped";
private static final String UNSUCCESSFUL_SCAN = "ReportError";
private static final String FAILED_SCAN = "Failed";
Expand All @@ -25,13 +25,17 @@ public class Scan {
private final LoggerFacade log;
private Optional<String> id;

public Scan(EnterpriseClient client, ScanSettings settings, LoggerFacade log) {
public static DastScan createInstanceOrThrow(EnterpriseClient client, ScanSettings settings, LoggerFacade log) {
if (Objects.isNull(client))
throw new IllegalArgumentException("client cannot be null");
if (Objects.isNull(settings))
throw new IllegalArgumentException("settings cannot be null");
if (Objects.isNull(log))
throw new IllegalArgumentException("log cannot be null");
return new DastScan(client, settings, log);
}

private DastScan(EnterpriseClient client, ScanSettings settings, LoggerFacade log) {
this.client = client;
this.settings = settings;
this.log = log;
Expand All @@ -47,7 +51,7 @@ public Optional<String> getId() {

public boolean process(AuthenticationModel authModel) throws InterruptedException {
Optional<String> maybeAuthToken = client.login(authModel);
if (!maybeAuthToken.isPresent()) {
if (maybeAuthToken.isEmpty()) {
log.println(UNAUTHORIZED_ERROR);
return false;
}
Expand All @@ -71,7 +75,7 @@ public boolean process(AuthenticationModel authModel) throws InterruptedExceptio
waitForScanCompletion(runResult.getScanId(), authModel);

maybeAuthToken = client.login(authModel);
if (!maybeAuthToken.isPresent()) {
if (maybeAuthToken.isEmpty()) {
log.println(UNAUTHORIZED_ERROR);
return false;
}
Expand Down Expand Up @@ -100,7 +104,7 @@ private boolean createScanBeforeRunIfNeeded(String authToken) {
log.println("Value of Scan Config Engine Group name: " + settings.getScanConfigEngineGroupName());

Optional<String> engineGroupId = client.getEngineGroupIdFromName(authToken, settings.getScanConfigEngineGroupName());
if (!engineGroupId.isPresent()) {
if (engineGroupId.isEmpty()) {
log.println(String.format("no engine group matching %s was found.", settings.getScanConfigEngineGroupName()));
return false;
}
Expand Down Expand Up @@ -144,7 +148,7 @@ private void waitForScanCompletion(String scanId, AuthenticationModel authModel)
}
private Optional<String> getStatus(String scanId, AuthenticationModel authModel) {
Optional<String> authToken = client.login(authModel);
if (!authToken.isPresent()) {
if (authToken.isEmpty()) {
log.println(UNAUTHORIZED_ERROR);
return Optional.empty();
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/rapid7/appspider/EnterpriseRestClient.java
Expand Up @@ -125,7 +125,7 @@ public boolean testAuthentication(AuthenticationModel authModel) {
public Optional<String[]> getEngineGroupNamesForClient(String authToken) {
return getEngineGroupsForClient(authToken)
.map(map -> new ArrayList<>(map.keySet()))
.map(Utility::toStringArray);
.map(FunctionalUtility::toStringArray);
}

/**
Expand Down Expand Up @@ -260,7 +260,7 @@ private Optional<JSONArray> getConfigs(String authToken) {
public Optional<String[]> getConfigNames(String authToken) {
return getConfigs(authToken)
.flatMap(apiSerializer::getConfigNames)
.map(Utility::toStringArray);
.map(FunctionalUtility::toStringArray);
}

/**
Expand Down
Expand Up @@ -21,14 +21,14 @@ class FreemarkerConfiguration {
private final Configuration configuration;

/**
* get the singelton instance, initializing it if necessary
* get the singleton instance, initializing it if necessary
*/
public static FreemarkerConfiguration getInstance() {
return Container.INSTANCE;
return InstanceContainer.CONFIGURATION_INSTANCE;
}

private static class Container {
private static final FreemarkerConfiguration INSTANCE = new FreemarkerConfiguration();
private static class InstanceContainer {
private static final FreemarkerConfiguration CONFIGURATION_INSTANCE = new FreemarkerConfiguration();
}

/**
Expand Down
Expand Up @@ -10,11 +10,11 @@
import java.util.Objects;

/**
* various utility merthods that have no better home
* various utility methods that have no better home
*/
public class Utility {
public class FunctionalUtility {

private Utility() {
private FunctionalUtility() {
}

/**
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/com/rapid7/appspider/HttpClientFactory.java
Expand Up @@ -24,21 +24,25 @@ public class HttpClientFactory {
private final SSLConnectionSocketFactory socketFactory;
final SSLContext sslContext;

public HttpClientFactory(boolean allowSelfSignedCertificates) throws SslContextCreationException {
public static HttpClientFactory createInstanceOrThrow(boolean allowSelfSignedCertificates)
throws SslContextCreationException {
try {
// ignore self-signed certs since we have no control over the server setup and as such can't
// enforce proper certificate usage
if (allowSelfSignedCertificates) {
sslContext = new SSLContextBuilder()
return new HttpClientFactory(new SSLContextBuilder()
.loadTrustMaterial(null, (x509CertChain, authType) -> true)
.build();
.build());
} else {
sslContext = SSLContexts.createDefault();
return new HttpClientFactory(SSLContexts.createDefault());
}

} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
throw new SslContextCreationException("Unable to configure SSL Context", e);
}
}

private HttpClientFactory(SSLContext context) {
sslContext = context;
socketFactory = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1.2"},
null, NoopHostnameVerifier.INSTANCE);
Expand Down

0 comments on commit 1677f09

Please sign in to comment.