From cbd99a68962cef6c00870d4351388a4441949465 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Wed, 21 Aug 2024 14:58:37 +0200 Subject: [PATCH 01/10] Replace trustAll with verifyCertificate in config #3375 #3371 #3374 - introduce field to config and change implementation of web requests - update tests and methods - udpate README.adoc documentation - improved logging while requests are performed - only use fallback default when all requests for a finding failed --- sechub-wrapper-secretvalidation/README.adoc | 7 +- .../execution/SecretValidationService.java | 2 +- .../SecretValidationServiceImpl.java | 4 +- .../SecretValidatorExecutionContext.java | 14 +- ...ecretValidatorExecutionContextFactory.java | 2 +- .../SecretValidatorExecutionService.java | 3 +- .../SecretValidatorWebRequestService.java | 61 +++++---- ...rationTestSecretValidationServiceImpl.java | 2 +- .../model/SecretValidatorRequest.java | 9 ++ .../properties/SecretValidatorProperties.java | 11 +- .../SecretValidatorHttpClientFactory.java | 85 ------------ .../SecretValidatorHttpClientWrapper.java | 124 ++++++++++++++++++ .../src/main/resources/application.properties | 4 + .../resources/gitleaks-github-config.json | 21 +++ .../SecretValidationServiceImplTest.java | 28 ++-- ...tValidatorExecutionContextFactoryTest.java | 4 +- .../SecretValidatorExecutionServiceTest.java | 27 ++-- .../SecretValidatorWebRequestServiceTest.java | 80 +++++------ ...etValidatorConfigurationModelListTest.java | 3 +- ...tValidatorConfigurationSpringBootTest.java | 4 +- .../SecretValidatorPropertiesTest.java | 10 +- .../SecretValidatorHttpClientFactoryTest.java | 35 ----- 22 files changed, 286 insertions(+), 254 deletions(-) delete mode 100644 sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactory.java create mode 100644 sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java create mode 100644 sechub-wrapper-secretvalidation/src/main/resources/application.properties create mode 100644 sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json delete mode 100644 sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactoryTest.java diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index e4876885f3..f1ca7ee8c0 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -41,6 +41,7 @@ only the `PDS_JOB_RESULT_FILE` is mandatory because without a valid SARIF report }, "requests" : [ { <4> "proxyRequired" : true, + "verifyCertificate": false, "url" : "https://api.example.com", "headers" : [ { "name" : "Authorization", @@ -67,6 +68,7 @@ only the `PDS_JOB_RESULT_FILE` is mandatory because without a valid SARIF report This is an array because for some secrets it might be necessary to validate against multiple servers e.g. when a company uses multiple AWS instances. It might be necessary to perform validation requests to all possible AWS instances to check if a secret is valid for any of them: - `proxyRequired` specifies if the URL can only be accessed using a proxy server. +- `verifyCertificate` specifies if the certificate for this URL shall be verified or ignored. The default value is `true`, meaning the certificate will be verified and certificate errors are not ignored. - `url` specifies the URL the request will be performed to. - `headers` specifies the header `name` and `valuePrefix` if necessary for the secret found. It is an array because it could be useful in the future. Currently the header is used for the secret because it is assumed to be a token send via HTTP header. @@ -78,12 +80,13 @@ like a specific `httpStatus` code or the response body should contain `allOf` or There exists also some optional variables: ---- -SECRET_VALIDATOR_TRUSTALLCERTIFICATES +SECRET_VALIDATOR_CONNECTIONRETRIES ---- [TIP] ==== -When `SECRET_VALIDATOR_TRUSTALLCERTIFICATES` set to `true`, certificate errors on validation web requests will be ignored. +The property `secret.validator.connection-retries`or the corresponding environment variable `SECRET_VALIDATOR_CONNECTIONRETRIES` can be set to specify the number of retries for each of the request, to be more resistant to network issues. +The default value is `3` meaning in the worst case `4` requests will be performed on connection issues. This can be useful, in certain situations or setups. ==== diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java index 81d07ed578..9a25f5b55f 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java @@ -9,6 +9,6 @@ public interface SecretValidationService { - SecretValidationResult validateFindingByRegion(Region findingRegion, List requests, boolean trustAllCertificates); + SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests); } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java index e38f6d6f7f..678bbe1a37 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java @@ -24,7 +24,7 @@ public class SecretValidationServiceImpl implements SecretValidationService { SecretValidatorWebRequestService webRequestService; @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, List requests, boolean trustAllCertificates) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests) { ArtifactContent snippet = findingRegion.getSnippet(); SecretValidationResult validationResult = new SecretValidationResult(); if (snippet == null) { @@ -39,7 +39,7 @@ public SecretValidationResult validateFindingByRegion(Region findingRegion, List validationResult.setValidationStatus(SecretValidationStatus.SARIF_SNIPPET_NOT_SET); return validationResult; } - return webRequestService.validateFinding(snippetText, requests, trustAllCertificates); + return webRequestService.validateFinding(snippetText, ruleId, requests); } } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java index a2c6a4589a..8b98a4f265 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java @@ -15,7 +15,7 @@ public class SecretValidatorExecutionContext { private Map validatorConfiguration = new HashMap<>(); - private boolean trustAllCertificates; + private long connectionRetries; private SecretValidatorExecutionContext() { } @@ -28,8 +28,8 @@ public Map getValidatorConfiguration( return Collections.unmodifiableMap(validatorConfiguration); } - public boolean isTrustAllCertificates() { - return trustAllCertificates; + public long getConnectionRetries() { + return connectionRetries; } public static SecretValidatorExecutionContextBuilder builder() { @@ -42,7 +42,7 @@ public static class SecretValidatorExecutionContextBuilder { private Map validatorConfiguration = new HashMap<>(); - private boolean trustAllCertificates; + private long connectionRetries; public SecretValidatorExecutionContextBuilder setSarifReport(SarifSchema210 report) { this.sarifReport = report; @@ -54,8 +54,8 @@ public SecretValidatorExecutionContextBuilder setValidatorConfiguration(Map requests, boolean trustAllCertificates) { + public SecretValidatorWebRequestService(ResponseValidationService responseValidationService, SecretValidatorHttpClientWrapper httpClientWrapper) { + + this.responseValidationService = responseValidationService; + this.httpClientWrapper = httpClientWrapper; + } + + public SecretValidationResult validateFinding(String snippetText, String ruleId, List requests) { SecretValidationResult validationResult = assertValidParams(snippetText, requests); if (validationResult != null) { return validationResult; } - HttpClient proxyHttpClient = httpClientFactory.createProxyHttpClient(trustAllCertificates); - HttpClient directHttpClient = httpClientFactory.createDirectHttpClient(trustAllCertificates); - HttpResponse response = null; + int failedRequests = 0; for (SecretValidatorRequest request : requests) { + HttpResponse response = null; if (isRequestValid(request)) { - response = createAndExecuteHttpRequest(snippetText, proxyHttpClient, directHttpClient, request); + response = createAndExecuteHttpRequest(snippetText, request); if (responseValidationService.isValidResponse(response, request.getExpectedResponse())) { - LOG.info("Finding is valid!"); + LOG.info("Finding of type: {} is valid!", ruleId); return createValidationResult(SecretValidationStatus.VALID, request.getUrl()); } } + if (response == null) { + failedRequests += 1; + } } - if (response == null) { + // all requests failed + if (failedRequests == requests.size()) { + LOG.warn("All requests for finding of type: {} seem to have failed", ruleId); return createValidationResult(SecretValidationStatus.ALL_VALIDATION_REQUESTS_FAILED); } return createValidationResult(SecretValidationStatus.INVALID); @@ -81,20 +86,22 @@ private boolean isRequestValid(SecretValidatorRequest request) { return true; } - private HttpResponse createAndExecuteHttpRequest(String snippetText, HttpClient proxyHttpClient, HttpClient directHttpClient, - SecretValidatorRequest request) { - HttpResponse response = null; - try { - HttpRequest httpRequest = createHttpRequest(snippetText, request); - if (request.isProxyRequired()) { - response = proxyHttpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - } else { - response = directHttpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + private HttpResponse createAndExecuteHttpRequest(String snippetText, SecretValidatorRequest request) { + HttpRequest httpRequest = createHttpRequest(snippetText, request); + boolean proxyRequired = request.isProxyRequired(); + boolean verifyCertificate = request.isVerifyCertificate(); + if (proxyRequired) { + if (verifyCertificate) { + return httpClientWrapper.sendProxiedRequestVerifyCertificate(httpRequest); + } + return httpClientWrapper.sendProxiedRequestIgnoreCertificate(httpRequest); + + } else { + if (verifyCertificate) { + return httpClientWrapper.sendDirectRequestVerifyCertificate(httpRequest); } - } catch (IOException | InterruptedException e) { - LOG.error("Performing validation request failed!", e); + return httpClientWrapper.sendDirectRequestIgnoreCertificate(httpRequest); } - return response; } private HttpRequest createHttpRequest(String snippetText, SecretValidatorRequest request) { diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java index 2250eacfbc..a53ac6c34d 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java @@ -28,7 +28,7 @@ public class IntegrationTestSecretValidationServiceImpl implements SecretValidationService { @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, List requests, boolean trustAllCertificates) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests) { if (requests == null || requests.isEmpty()) { SecretValidationResult validationResult = new SecretValidationResult(); validationResult.setValidationStatus(SecretValidationStatus.INVALID); diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorRequest.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorRequest.java index b5a6a837dd..bb23326343 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorRequest.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorRequest.java @@ -13,6 +13,7 @@ public class SecretValidatorRequest { private URL url; private boolean proxyRequired; + private boolean verifyCertificate = true; private List headers = new ArrayList<>(); private SecretValidatorResponse expectedResponse; @@ -59,4 +60,12 @@ public void setExpectedResponse(SecretValidatorResponse expectedResponse) { this.expectedResponse = expectedResponse; } + public void setVerifyCertificate(boolean verifyCertificate) { + this.verifyCertificate = verifyCertificate; + } + + public boolean isVerifyCertificate() { + return verifyCertificate; + } + } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java index 7e3112eb88..e970694658 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java @@ -10,10 +10,10 @@ public class SecretValidatorProperties { private final File configFile; - private final boolean trustAllCertificates; + private long connectionRetries; @ConstructorBinding - public SecretValidatorProperties(File configFile, boolean trustAllCertificates) { + public SecretValidatorProperties(File configFile, long connectionRetries) { if (configFile == null) { throw new IllegalArgumentException("The secret validator configuration file is null!"); } @@ -27,15 +27,14 @@ public SecretValidatorProperties(File configFile, boolean trustAllCertificates) throw new IllegalArgumentException("The secret validator configuration file " + configFile + " is not readable!"); } - this.trustAllCertificates = trustAllCertificates; + this.connectionRetries = connectionRetries; } public File getConfigFile() { return configFile; } - public boolean isTrustAllCertificates() { - return trustAllCertificates; + public long getConnectionRetries() { + return connectionRetries; } - } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactory.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactory.java deleted file mode 100644 index 7b1f5ac56f..0000000000 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MIT -package com.mercedesbenz.sechub.wrapper.secret.validator.support; - -import java.net.ProxySelector; -import java.net.http.HttpClient; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.springframework.stereotype.Component; - -@Component -public class SecretValidatorHttpClientFactory { - private static final String TLS = "TLS"; - - public HttpClient createProxyHttpClient(boolean trustAllCertificates) { - if (trustAllCertificates) { - TrustManager pseudoTrustManager = createTrustManagerWhichTrustsEveryBody(); - SSLContext sslContext = createSSLContextForTrustManager(pseudoTrustManager); - /* @formatter:off */ - return HttpClient.newBuilder() - .proxy(ProxySelector.getDefault()) - .sslContext(sslContext) - .build(); - /* @formatter:on */ - } else { - /* @formatter:off */ - return HttpClient.newBuilder() - .proxy(ProxySelector.getDefault()) - .build(); - /* @formatter:on */ - } - } - - public HttpClient createDirectHttpClient(boolean trustAllCertificates) { - if (trustAllCertificates) { - TrustManager pseudoTrustManager = createTrustManagerWhichTrustsEveryBody(); - SSLContext sslContext = createSSLContextForTrustManager(pseudoTrustManager); - /* @formatter:off */ - return HttpClient.newBuilder() - .sslContext(sslContext) - .build(); - /* @formatter:on */ - } else { - return HttpClient.newBuilder().build(); - } - } - - private X509TrustManager createTrustManagerWhichTrustsEveryBody() { - return new X509TrustManager() { - - private X509Certificate[] emptyCertificatesArray = new X509Certificate[] {}; - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - /* we do not check the client - we trust all */ - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - /* we do not check the server - we trust all */ - } - - public X509Certificate[] getAcceptedIssuers() { - return emptyCertificatesArray; - } - }; - } - - private SSLContext createSSLContextForTrustManager(TrustManager trustManager) { - SSLContext sslContext = null; - try { - sslContext = SSLContext.getInstance(TLS); - sslContext.init(null, new TrustManager[] { trustManager }, null); - - return sslContext; - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new IllegalStateException("Was not able to create trust all context", e); - } - - } -} diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java new file mode 100644 index 0000000000..eef38663fd --- /dev/null +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +package com.mercedesbenz.sechub.wrapper.secret.validator.support; + +import java.io.IOException; +import java.net.ProxySelector; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class SecretValidatorHttpClientWrapper { + + private static final Logger LOG = LoggerFactory.getLogger(SecretValidatorHttpClientWrapper.class); + + private static final String TLS = "TLS"; + + private HttpClient proxiedHttpClientVerifyCertificate; + private HttpClient proxiedHttpClientIgnoreCertificate; + + private HttpClient directHttpClientVerifyCertificate; + private HttpClient directHttpClientIgnoreCertificate; + + public SecretValidatorHttpClientWrapper() { + TrustManager pseudoTrustManager = createTrustManagerWhichTrustsEveryBody(); + SSLContext sslContext = createSSLContextForTrustManager(pseudoTrustManager); + /* @formatter:off */ + proxiedHttpClientVerifyCertificate = HttpClient.newBuilder() + .proxy(ProxySelector.getDefault()) + .build(); + + proxiedHttpClientIgnoreCertificate = HttpClient.newBuilder() + .proxy(ProxySelector.getDefault()) + .sslContext(sslContext) + .build(); + + directHttpClientVerifyCertificate = HttpClient.newBuilder() + .build(); + + directHttpClientIgnoreCertificate = HttpClient.newBuilder() + .sslContext(sslContext) + .build(); + /* @formatter:on */ + } + + public HttpResponse sendProxiedRequestVerifyCertificate(HttpRequest httpRequest) { + try { + return proxiedHttpClientVerifyCertificate.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException | InterruptedException e) { + LOG.warn("Performing validation request via proxy with verifying certificate enabled to URL: {} failed!", httpRequest.uri()); + } + return null; + } + + public HttpResponse sendProxiedRequestIgnoreCertificate(HttpRequest httpRequest) { + try { + return proxiedHttpClientIgnoreCertificate.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException | InterruptedException e) { + LOG.warn("Performing validation request via proxy with verifying certificate disabled to URL: {} failed!", httpRequest.uri()); + } + return null; + } + + public HttpResponse sendDirectRequestVerifyCertificate(HttpRequest httpRequest) { + try { + return directHttpClientVerifyCertificate.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException | InterruptedException e) { + LOG.warn("Performing validation request directly without proxy with verifying certificate enabled to URL: {} failed!", httpRequest.uri()); + } + return null; + } + + public HttpResponse sendDirectRequestIgnoreCertificate(HttpRequest httpRequest) { + try { + return directHttpClientIgnoreCertificate.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + } catch (IOException | InterruptedException e) { + LOG.warn("Performing validation request directly without proxy with verifying certificate disabled to URL: {} failed!", httpRequest.uri()); + } + return null; + } + + private X509TrustManager createTrustManagerWhichTrustsEveryBody() { + return new X509TrustManager() { + + private X509Certificate[] emptyCertificatesArray = new X509Certificate[] {}; + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + /* we do not check the client - we trust all */ + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + /* we do not check the server - we trust all */ + } + + public X509Certificate[] getAcceptedIssuers() { + return emptyCertificatesArray; + } + }; + } + + private SSLContext createSSLContextForTrustManager(TrustManager trustManager) { + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance(TLS); + sslContext.init(null, new TrustManager[] { trustManager }, null); + + return sslContext; + } catch (NoSuchAlgorithmException | KeyManagementException e) { + throw new IllegalStateException("Was not able to create trust all context", e); + } + + } +} diff --git a/sechub-wrapper-secretvalidation/src/main/resources/application.properties b/sechub-wrapper-secretvalidation/src/main/resources/application.properties new file mode 100644 index 0000000000..54fd930f98 --- /dev/null +++ b/sechub-wrapper-secretvalidation/src/main/resources/application.properties @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: MIT + +secret.validator.config-file=src/main/resources/gitleaks-github-config.json +secret.validator.connection-retries=3 \ No newline at end of file diff --git a/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json b/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json new file mode 100644 index 0000000000..0ff864f637 --- /dev/null +++ b/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json @@ -0,0 +1,21 @@ +{ + "validatorConfigList" : [ { + "ruleId" : "github-pat", + "categorization" : { + "defaultSeverity" : "high", + "validationFailedSeverity" : "medium", + "validationSuccessSeverity" : "critical" + }, + "requests" : [ { + "proxyRequired" : true, + "url" : "https://api.github.com", + "headers" : [ { + "name" : "Authorization", + "valuePrefix" : "Bearer" + } ], + "expectedResponse" : { + "httpStatus" : 200 + } + } ] + } ] +} \ No newline at end of file diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java index 1a1c2fd76b..ae5ad717fb 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java @@ -37,15 +37,16 @@ void beforeEach() { @Test void region_snippet_is_null_returns_expected_validation_result() { /* prepare */ + String ruleId = "rule-id"; Region region = new Region(); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(null, requests, true)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(null, ruleId, requests)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, requests, true); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); /* test */ - verify(webRequestService, never()).validateFinding(null, requests, true); + verify(webRequestService, never()).validateFinding(null, ruleId, requests); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -53,16 +54,17 @@ void region_snippet_is_null_returns_expected_validation_result() { @Test void region_snippet_text_is_null_returns_expected_validation_result() { /* prepare */ + String ruleId = "rule-id"; Region region = new Region(); region.setSnippet(new ArtifactContent()); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), requests, true)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, requests, true); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), requests, true); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -70,18 +72,19 @@ void region_snippet_text_is_null_returns_expected_validation_result() { @Test void region_snippet_text_is_blank_returns_expected_validation_result() { /* prepare */ + String ruleId = "rule-id"; Region region = new Region(); ArtifactContent snippet = new ArtifactContent(); snippet.setText(" "); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), requests, true)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, requests, true); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), requests, true); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -89,18 +92,19 @@ void region_snippet_text_is_blank_returns_expected_validation_result() { @Test void region_snippet_text_is_set_results_in_web_request_service_called_once() { /* prepare */ + String ruleId = "rule-id"; Region region = new Region(); ArtifactContent snippet = new ArtifactContent(); snippet.setText("secret"); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), requests, true)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, requests, true); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); /* test */ - verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), requests, true); + verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), ruleId, requests); assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validateFindingByRegion.getValidationStatus()); } diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java index 1e2bc60bda..8f7a702f6a 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java @@ -33,11 +33,11 @@ void beforeEach() { invalidsecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(invalidSarifFile); - invalidProperties = new SecretValidatorProperties(invalidConfigFile, false); + invalidProperties = new SecretValidatorProperties(invalidConfigFile, 5L); validSecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(validSarifFile); - validProperties = new SecretValidatorProperties(validConfigFile, false); + validProperties = new SecretValidatorProperties(validConfigFile, 5L); } @Test diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java index 11d9ed2184..f61a0839ec 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java @@ -2,7 +2,6 @@ package com.mercedesbenz.sechub.wrapper.secret.validator.execution; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -64,7 +63,7 @@ void finding_cannot_be_validated_results_in_validation_and_categorization_never_ when(ruleConfigurations.get(any())).thenReturn(null); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setTrustAllCertificates(true).build(); + .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(false); @@ -74,7 +73,7 @@ void finding_cannot_be_validated_results_in_validation_and_categorization_never_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -89,7 +88,7 @@ void empty_config_map_results_in_validation_and_categorization_never_being_calle when(ruleConfigurations.get(any())).thenReturn(null); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setTrustAllCertificates(true).build(); + .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -99,7 +98,7 @@ void empty_config_map_results_in_validation_and_categorization_never_being_calle /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -116,7 +115,7 @@ void categorization_of_config_is_null_results_in_validation_and_categorization_n when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setTrustAllCertificates(true).build(); + .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -126,7 +125,7 @@ void categorization_of_config_is_null_results_in_validation_and_categorization_n /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -144,7 +143,7 @@ void categorization_of_config_is_empty_results_in_validation_and_categorization_ when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setTrustAllCertificates(true).build(); + .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -154,7 +153,7 @@ void categorization_of_config_is_empty_results_in_validation_and_categorization_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -173,7 +172,7 @@ void finding_location_cannot_be_validated_results_in_validation_and_categorizati when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setTrustAllCertificates(true).build(); + .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -184,7 +183,7 @@ void finding_location_cannot_be_validated_results_in_validation_and_categorizati /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(1)).findingLocationCanBeValidated(any()); @@ -197,7 +196,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio when(contextFactory.create()).thenReturn(executionContext); SecretValidationResult secretValidationResult = new SecretValidationResult(); - when(validationService.validateFindingByRegion(any(), any(), anyBoolean())).thenReturn(secretValidationResult); + when(validationService.validateFindingByRegion(any(), any(), any())).thenReturn(secretValidationResult); doNothing().when(sarifEnhancementService).addSerecoSeverityInfo(any(), any(), any()); @@ -209,7 +208,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, times(6)).validateFindingByRegion(any(), any(), anyBoolean()); + verify(validationService, times(6)).validateFindingByRegion(any(), any(), any()); verify(sarifEnhancementService, times(6)).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(6)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(6)).findingLocationCanBeValidated(any()); @@ -223,7 +222,7 @@ private SecretValidatorExecutionContext createValidExecutionContext() { /* @formatter:off */ return SecretValidatorExecutionContext.builder() - .setTrustAllCertificates(true) + .setConnectionRetries(5L) .setSarifReport(report) .setValidatorConfiguration(ruleConfigurations) .build(); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java index 3c951cbd2a..56c7687ab4 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java @@ -3,14 +3,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.net.http.HttpClient; import java.net.http.HttpResponse; import java.util.ArrayList; import java.util.List; @@ -19,34 +16,29 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mockito; import com.mercedesbenz.sechub.wrapper.secret.validator.model.SecretValidatorRequest; import com.mercedesbenz.sechub.wrapper.secret.validator.model.SecretValidatorRequestHeader; -import com.mercedesbenz.sechub.wrapper.secret.validator.support.SecretValidatorHttpClientFactory; +import com.mercedesbenz.sechub.wrapper.secret.validator.support.SecretValidatorHttpClientWrapper; class SecretValidatorWebRequestServiceTest { private SecretValidatorWebRequestService serviceTotest; - private SecretValidatorHttpClientFactory httpClientFactory; - private ResponseValidationService responseValidationService; + private static final SecretValidatorHttpClientWrapper httpClientWrapper = mock(); + private static final ResponseValidationService responseValidationService = mock(); @BeforeEach void beforeEach() { - serviceTotest = new SecretValidatorWebRequestService(); - httpClientFactory = new SecretValidatorHttpClientFactory(); - - httpClientFactory = mock(SecretValidatorHttpClientFactory.class); - responseValidationService = mock(ResponseValidationService.class); - - serviceTotest.httpClientFactory = httpClientFactory; - serviceTotest.responseValidationService = responseValidationService; + Mockito.reset(responseValidationService, httpClientWrapper); + serviceTotest = new SecretValidatorWebRequestService(responseValidationService, httpClientWrapper); } @Test void no_finding_snippet_text_available_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding(null, new ArrayList<>(), true); + SecretValidationResult validationResult = serviceTotest.validateFinding(null, "example-rule-id", new ArrayList<>()); /* test */ assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validationResult.getValidationStatus()); @@ -55,27 +47,12 @@ void no_finding_snippet_text_available_results_in_finding_being_skipped_from_val @Test void no_requests_defined_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", new ArrayList<>(), true); + SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", "example-rule-id", new ArrayList<>()); /* test */ assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validationResult.getValidationStatus()); } - @Test - void request_config_inside_list_is_null_results_request_will_be_skipped() { - /* prepare */ - ArrayList requests = new ArrayList<>(); - requests.add(null); - - /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", requests, true); - - /* test */ - // no validation request was performed ends up with the following status, only - // if at least 1 request was performed, the finding could be marked as invalid. - assertEquals(SecretValidationStatus.ALL_VALIDATION_REQUESTS_FAILED, validationResult.getValidationStatus()); - } - @Test void request_url_is_null_results_request_will_be_skipped() { /* prepare */ @@ -83,7 +60,7 @@ void request_url_is_null_results_request_will_be_skipped() { requests.add(new SecretValidatorRequest()); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", requests, true); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); /* test */ // no validation request was performed ends up with the following status, only @@ -93,27 +70,30 @@ void request_url_is_null_results_request_will_be_skipped() { @ParameterizedTest @ValueSource(booleans = { true, false }) - void proxy_required_calls_the_correct_http_client_results_validation_result(boolean expectedValidation) throws IOException, InterruptedException { + void proxy_required_calls_the_correct_http_client_returns_expected_validation_result(boolean expectedValidation) throws IOException, InterruptedException { /* prepare */ List requests = createListOfRequests(true); - - HttpClient proxyHttpClient = mock(HttpClient.class); - when(proxyHttpClient.send(any(), any())).thenReturn(null); - - when(httpClientFactory.createProxyHttpClient(anyBoolean())).thenReturn(proxyHttpClient); - + @SuppressWarnings("unchecked") + HttpResponse response = mock(HttpResponse.class); + when(httpClientWrapper.sendProxiedRequestVerifyCertificate(any())).thenReturn(response); when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", requests, true); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); /* test */ if (expectedValidation) { assertEquals(SecretValidationStatus.VALID, validationResult.getValidationStatus()); assertEquals("http://example.com", validationResult.getValidatedByUrl()); } else { - assertEquals(SecretValidationStatus.ALL_VALIDATION_REQUESTS_FAILED, validationResult.getValidationStatus()); + assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); } + + verify(httpClientWrapper, times(1)).sendProxiedRequestVerifyCertificate(any()); + + verify(httpClientWrapper, never()).sendProxiedRequestIgnoreCertificate(any()); + verify(httpClientWrapper, never()).sendDirectRequestVerifyCertificate(any()); + verify(httpClientWrapper, never()).sendDirectRequestIgnoreCertificate(any()); } @ParameterizedTest @@ -122,17 +102,13 @@ void no_proxy_required_calls_the_correct_http_client_results_validation_result(b /* prepare */ List requests = createListOfRequests(false); - HttpClient directHttpClient = mock(HttpClient.class); @SuppressWarnings("unchecked") - HttpResponse response = mock(HttpResponse.class); - when(directHttpClient.send(any(), any())).thenReturn(response); - - when(httpClientFactory.createDirectHttpClient(anyBoolean())).thenReturn(directHttpClient); - + HttpResponse response = mock(HttpResponse.class); + when(httpClientWrapper.sendDirectRequestVerifyCertificate(any())).thenReturn(response); when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", requests, true); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); /* test */ if (expectedValidation) { @@ -141,6 +117,12 @@ void no_proxy_required_calls_the_correct_http_client_results_validation_result(b } else { assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); } + + verify(httpClientWrapper, times(1)).sendDirectRequestVerifyCertificate(any()); + + verify(httpClientWrapper, never()).sendProxiedRequestVerifyCertificate(any()); + verify(httpClientWrapper, never()).sendProxiedRequestIgnoreCertificate(any()); + verify(httpClientWrapper, never()).sendDirectRequestIgnoreCertificate(any()); } private List createListOfRequests(boolean proxyRequired) throws MalformedURLException { diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorConfigurationModelListTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorConfigurationModelListTest.java index c038acc6a6..652344d871 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorConfigurationModelListTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/model/SecretValidatorConfigurationModelListTest.java @@ -24,6 +24,7 @@ void json_converter_can_handle_model_in_expected_way() { "requests" : [ { "url" : "https://api.example.com", "proxyRequired" : true, + "verifyCertificate" : false, "headers" : [ { "name" : "Authorization", "valuePrefix" : "Bearer" @@ -41,7 +42,7 @@ void json_converter_can_handle_model_in_expected_way() { """; String expected = "{\"validatorConfigList\":[{\"ruleId\":\"rule-id\",\"categorization\":{\"defaultSeverity\":\"high\",\"validationFailedSeverity\":\"medium\",\"validationSuccessSeverity\":\"critical\"}," - + "\"requests\":[{\"url\":\"https://api.example.com\",\"proxyRequired\":true,\"headers\":[{\"name\":\"Authorization\",\"valuePrefix\":\"Bearer\"}]," + + "\"requests\":[{\"url\":\"https://api.example.com\",\"proxyRequired\":true,\"verifyCertificate\":false,\"headers\":[{\"name\":\"Authorization\",\"valuePrefix\":\"Bearer\"}]," + "\"expectedResponse\":{\"httpStatus\":200,\"contains\":{\"allOf\":[\"is\",\"there\"],\"oneOf\":[\"success\"]}}}]}]}"; /* execute */ diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java index 08f88e2f02..94fef4f316 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java @@ -16,7 +16,7 @@ @ExtendWith(SpringExtension.class) @EnableConfigurationProperties @TestPropertySource(properties = { "secret.validator.config-file=src/test/resources/config-test-files/valid-files/test-config.json", - "secret.validator.trust-all-certificates=false", "pds.job.result.file=src/test/resources/config-test-files/valid-files/test-result.txt" }) + "secret.validator.connection-retries=5", "pds.job.result.file=src/test/resources/config-test-files/valid-files/test-result.txt" }) @ActiveProfiles("test") class SecretValidatorConfigurationSpringBootTest { @@ -31,7 +31,7 @@ void properties_are_created_correctly() { /* test */ // check if all SecretValidatorProperties are as expected - assertFalse(properties.isTrustAllCertificates()); + assertEquals(5L, properties.getConnectionRetries()); assertEquals("src/test/resources/config-test-files/valid-files/test-config.json", properties.getConfigFile().toString()); // check if the PDS job result file is as expected diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java index 1700d787b9..4701ed37b7 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java @@ -14,7 +14,7 @@ class SecretValidatorPropertiesTest { @Test void validator_config_file_is_null_throws_exception() { /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(null, false)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(null, 5L)); } @Test @@ -24,7 +24,7 @@ void not_existing_validator_config_file_throws_exception() { when(notExisting.exists()).thenReturn(false); /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notExisting, false)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notExisting, 5L)); } @Test @@ -35,7 +35,7 @@ void not_readable_validator_config_file_throws_exception() { when(notReadable.canRead()).thenReturn(false); /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notReadable, false)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notReadable, 5L)); } @Test @@ -44,11 +44,11 @@ void valid_properties_result_in_valid_configuration() { File validConfigFile = new File("src/test/resources/config-test-files/valid-files/test-config.json"); /* execute */ - SecretValidatorProperties properties = new SecretValidatorProperties(validConfigFile, true); + SecretValidatorProperties properties = new SecretValidatorProperties(validConfigFile, 5L); /* test */ assertEquals(validConfigFile, properties.getConfigFile()); - assertTrue(properties.isTrustAllCertificates()); + assertEquals(5L, properties.getConnectionRetries()); } } diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactoryTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactoryTest.java deleted file mode 100644 index b577f34141..0000000000 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientFactoryTest.java +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -package com.mercedesbenz.sechub.wrapper.secret.validator.support; - -import static org.junit.Assert.assertTrue; - -import java.net.http.HttpClient; - -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class SecretValidatorHttpClientFactoryTest { - - private SecretValidatorHttpClientFactory factoryToTest = new SecretValidatorHttpClientFactory(); - - @ParameterizedTest - @ValueSource(booleans = { true, false }) - void create_proxy_http_client_returns_expected_http_client(boolean trustAllCertificates) { - /* execute */ - HttpClient proxyHttpClient = factoryToTest.createProxyHttpClient(trustAllCertificates); - - /* test */ - assertTrue(proxyHttpClient.proxy().isPresent()); - } - - @ParameterizedTest - @ValueSource(booleans = { true, false }) - void create_direct_http_client_returns_expected_http_client(boolean trustAllCertificates) { - /* execute */ - HttpClient proxyHttpClient = factoryToTest.createDirectHttpClient(trustAllCertificates); - - /* test */ - assertTrue(proxyHttpClient.proxy().isEmpty()); - } - -} From 3ab6b0bbbf5a311e3867073cf246d8e528c28c92 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 08:43:47 +0200 Subject: [PATCH 02/10] Add retry mechanism to be more resistent to network errors #3376 - add retry mechanic with default - number of retries can be configured --- .../execution/SecretValidationService.java | 2 +- .../SecretValidationServiceImpl.java | 4 ++-- .../SecretValidatorExecutionService.java | 7 +++--- .../SecretValidatorWebRequestService.java | 12 ++++++++-- ...rationTestSecretValidationServiceImpl.java | 2 +- .../SecretValidationServiceImplTest.java | 24 +++++++++---------- .../SecretValidatorExecutionServiceTest.java | 14 +++++------ .../SecretValidatorWebRequestServiceTest.java | 17 +++++++------ 8 files changed, 47 insertions(+), 35 deletions(-) diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java index 9a25f5b55f..e51ddafa0e 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java @@ -9,6 +9,6 @@ public interface SecretValidationService { - SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests); + SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries); } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java index 678bbe1a37..45fb9ad8cb 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java @@ -24,7 +24,7 @@ public class SecretValidationServiceImpl implements SecretValidationService { SecretValidatorWebRequestService webRequestService; @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries) { ArtifactContent snippet = findingRegion.getSnippet(); SecretValidationResult validationResult = new SecretValidationResult(); if (snippet == null) { @@ -39,7 +39,7 @@ public SecretValidationResult validateFindingByRegion(Region findingRegion, Stri validationResult.setValidationStatus(SecretValidationStatus.SARIF_SNIPPET_NOT_SET); return validationResult; } - return webRequestService.validateFinding(snippetText, ruleId, requests); + return webRequestService.validateFinding(snippetText, ruleId, requests, connectionRetries); } } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java index fcc606e415..5e0104db78 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java @@ -46,7 +46,7 @@ public SarifSchema210 execute() { for (Result finding : findings) { SecretValidatorConfigurationModel config = validatorConfiguration.get(finding.getRuleId()); if (isValidationPossible(config, finding)) { - validateFindingAndEnhanceSarif(executionContext, config, finding); + validateFindingAndEnhanceSarif(config, finding, executionContext.getConnectionRetries()); } } } @@ -69,13 +69,14 @@ private boolean isValidationPossible(SecretValidatorConfigurationModel config, R return true; } - private void validateFindingAndEnhanceSarif(SecretValidatorExecutionContext executionContext, SecretValidatorConfigurationModel config, Result finding) { + private void validateFindingAndEnhanceSarif(SecretValidatorConfigurationModel config, Result finding, long connectionRetries) { for (Location location : finding.getLocations()) { if (!sarifValidationSupport.findingLocationCanBeValidated(location)) { continue; } Region findingRegion = location.getPhysicalLocation().getRegion(); - SecretValidationResult validationResult = validationService.validateFindingByRegion(findingRegion, config.getRuleId(), config.getRequests()); + SecretValidationResult validationResult = validationService.validateFindingByRegion(findingRegion, config.getRuleId(), config.getRequests(), + connectionRetries); sarifEnhancementService.addSerecoSeverityInfo(validationResult, findingRegion, config.getCategorization()); } } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java index b9806d2341..45b3a8e53a 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java @@ -31,7 +31,7 @@ public SecretValidatorWebRequestService(ResponseValidationService responseValida this.httpClientWrapper = httpClientWrapper; } - public SecretValidationResult validateFinding(String snippetText, String ruleId, List requests) { + public SecretValidationResult validateFinding(String snippetText, String ruleId, List requests, long connectionRetries) { SecretValidationResult validationResult = assertValidParams(snippetText, requests); if (validationResult != null) { return validationResult; @@ -44,13 +44,21 @@ public SecretValidationResult validateFinding(String snippetText, String ruleId, if (isRequestValid(request)) { response = createAndExecuteHttpRequest(snippetText, request); + // perform retries until the response is not null or we reached our maximum + // amount of retries + int retries = 0; + while (response == null || retries < connectionRetries) { + response = createAndExecuteHttpRequest(snippetText, request); + retries++; + } + if (responseValidationService.isValidResponse(response, request.getExpectedResponse())) { LOG.info("Finding of type: {} is valid!", ruleId); return createValidationResult(SecretValidationStatus.VALID, request.getUrl()); } } if (response == null) { - failedRequests += 1; + failedRequests++; } } // all requests failed diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java index a53ac6c34d..7808492d95 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java @@ -28,7 +28,7 @@ public class IntegrationTestSecretValidationServiceImpl implements SecretValidationService { @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries) { if (requests == null || requests.isEmpty()) { SecretValidationResult validationResult = new SecretValidationResult(); validationResult.setValidationStatus(SecretValidationStatus.INVALID); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java index ae5ad717fb..e491beb277 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java @@ -40,13 +40,13 @@ void region_snippet_is_null_returns_expected_validation_result() { String ruleId = "rule-id"; Region region = new Region(); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(null, ruleId, requests)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(null, ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); /* test */ - verify(webRequestService, never()).validateFinding(null, ruleId, requests); + verify(webRequestService, never()).validateFinding(null, ruleId, requests, 0L); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -58,13 +58,13 @@ void region_snippet_text_is_null_returns_expected_validation_result() { Region region = new Region(); region.setSnippet(new ArtifactContent()); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -78,13 +78,13 @@ void region_snippet_text_is_blank_returns_expected_validation_result() { snippet.setText(" "); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -98,13 +98,13 @@ void region_snippet_text_is_set_results_in_web_request_service_called_once() { snippet.setText("secret"); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); /* test */ - verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), ruleId, requests); + verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validateFindingByRegion.getValidationStatus()); } diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java index f61a0839ec..f37e7f545a 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java @@ -73,7 +73,7 @@ void finding_cannot_be_validated_results_in_validation_and_categorization_never_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -98,7 +98,7 @@ void empty_config_map_results_in_validation_and_categorization_never_being_calle /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -125,7 +125,7 @@ void categorization_of_config_is_null_results_in_validation_and_categorization_n /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -153,7 +153,7 @@ void categorization_of_config_is_empty_results_in_validation_and_categorization_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -183,7 +183,7 @@ void finding_location_cannot_be_validated_results_in_validation_and_categorizati /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any()); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(1)).findingLocationCanBeValidated(any()); @@ -196,7 +196,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio when(contextFactory.create()).thenReturn(executionContext); SecretValidationResult secretValidationResult = new SecretValidationResult(); - when(validationService.validateFindingByRegion(any(), any(), any())).thenReturn(secretValidationResult); + when(validationService.validateFindingByRegion(any(), any(), any(), 0L)).thenReturn(secretValidationResult); doNothing().when(sarifEnhancementService).addSerecoSeverityInfo(any(), any(), any()); @@ -208,7 +208,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, times(6)).validateFindingByRegion(any(), any(), any()); + verify(validationService, times(6)).validateFindingByRegion(any(), any(), any(), 0L); verify(sarifEnhancementService, times(6)).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(6)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(6)).findingLocationCanBeValidated(any()); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java index 56c7687ab4..7259c3a1c9 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java @@ -38,7 +38,7 @@ void beforeEach() { @Test void no_finding_snippet_text_available_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding(null, "example-rule-id", new ArrayList<>()); + SecretValidationResult validationResult = serviceTotest.validateFinding(null, "example-rule-id", new ArrayList<>(), 0L); /* test */ assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validationResult.getValidationStatus()); @@ -47,7 +47,7 @@ void no_finding_snippet_text_available_results_in_finding_being_skipped_from_val @Test void no_requests_defined_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", "example-rule-id", new ArrayList<>()); + SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", "example-rule-id", new ArrayList<>(), 0L); /* test */ assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validationResult.getValidationStatus()); @@ -60,7 +60,7 @@ void request_url_is_null_results_request_will_be_skipped() { requests.add(new SecretValidatorRequest()); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, 0L); /* test */ // no validation request was performed ends up with the following status, only @@ -72,6 +72,8 @@ void request_url_is_null_results_request_will_be_skipped() { @ValueSource(booleans = { true, false }) void proxy_required_calls_the_correct_http_client_returns_expected_validation_result(boolean expectedValidation) throws IOException, InterruptedException { /* prepare */ + long connectionRetries = 2L; + List requests = createListOfRequests(true); @SuppressWarnings("unchecked") HttpResponse response = mock(HttpResponse.class); @@ -79,7 +81,7 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, connectionRetries); /* test */ if (expectedValidation) { @@ -89,7 +91,7 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); } - verify(httpClientWrapper, times(1)).sendProxiedRequestVerifyCertificate(any()); + verify(httpClientWrapper, times(3)).sendProxiedRequestVerifyCertificate(any()); verify(httpClientWrapper, never()).sendProxiedRequestIgnoreCertificate(any()); verify(httpClientWrapper, never()).sendDirectRequestVerifyCertificate(any()); @@ -100,6 +102,7 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re @ValueSource(booleans = { true, false }) void no_proxy_required_calls_the_correct_http_client_results_validation_result(boolean expectedValidation) throws IOException, InterruptedException { /* prepare */ + long connectionRetries = 3L; List requests = createListOfRequests(false); @SuppressWarnings("unchecked") @@ -108,7 +111,7 @@ void no_proxy_required_calls_the_correct_http_client_results_validation_result(b when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, connectionRetries); /* test */ if (expectedValidation) { @@ -118,7 +121,7 @@ void no_proxy_required_calls_the_correct_http_client_results_validation_result(b assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); } - verify(httpClientWrapper, times(1)).sendDirectRequestVerifyCertificate(any()); + verify(httpClientWrapper, times(4)).sendDirectRequestVerifyCertificate(any()); verify(httpClientWrapper, never()).sendProxiedRequestVerifyCertificate(any()); verify(httpClientWrapper, never()).sendProxiedRequestIgnoreCertificate(any()); From c9d10e15ae3690a1c4d4884a502445b7d1ec1d51 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 09:41:49 +0200 Subject: [PATCH 03/10] Add configurable timeout and improve retry handling #3372 #3376 --- sechub-wrapper-secretvalidation/README.adoc | 16 +++++++- .../execution/SecretValidationService.java | 2 +- .../SecretValidationServiceImpl.java | 4 +- .../SecretValidatorExecutionContext.java | 14 +++---- ...ecretValidatorExecutionContextFactory.java | 2 +- .../SecretValidatorExecutionService.java | 6 +-- .../SecretValidatorWebRequestService.java | 39 +++++++++++-------- ...rationTestSecretValidationServiceImpl.java | 2 +- .../properties/SecretValidatorProperties.java | 16 +++++--- .../SecretValidatorHttpClientWrapper.java | 11 +++++- .../src/main/resources/application.properties | 3 +- .../SecretValidationServiceImplTest.java | 24 ++++++------ ...tValidatorExecutionContextFactoryTest.java | 4 +- .../SecretValidatorExecutionServiceTest.java | 27 ++++++------- .../SecretValidatorWebRequestServiceTest.java | 22 +++++------ ...tValidatorConfigurationSpringBootTest.java | 6 ++- .../SecretValidatorPropertiesTest.java | 11 +++--- 17 files changed, 123 insertions(+), 86 deletions(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index f1ca7ee8c0..2e35ce46d0 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -80,16 +80,28 @@ like a specific `httpStatus` code or the response body should contain `allOf` or There exists also some optional variables: ---- -SECRET_VALIDATOR_CONNECTIONRETRIES +SECRET_VALIDATOR_MAXIMUMRETRIES +SECRET_VALIDATOR_TIMEOUTSECONDS ---- [TIP] ==== -The property `secret.validator.connection-retries`or the corresponding environment variable `SECRET_VALIDATOR_CONNECTIONRETRIES` can be set to specify the number of retries for each of the request, to be more resistant to network issues. +The property `secret.validator.maximum-retries` or the corresponding environment variable `SECRET_VALIDATOR_MAXIMUMRETRIES` can be used to specify the `number of retries` for each of the request, to be more resistant to network issues. The default value is `3` meaning in the worst case `4` requests will be performed on connection issues. + +The property `secret.validator.timeout-seconds` or the corresponding environment variable `SECRET_VALIDATOR_TIMEOUTSECONDS` can be used to specify the number of `seconds` for each of the request before returning because of a timeout. +The default value is `5` seconds. This means on default after maximum `5` seconds the next request will be performed. + This can be useful, in certain situations or setups. ==== +===== Default spring boot configuration +The defaults can be found inside the <> file: +[source,properties] +---- +include::src/main/resources/application.properties[] +---- + ===== Proxy configuration Inside the configuration file each request has to configure if a proxy server is required to access this specific URL or not. The wrapper is implemented to use the default proxy of the system properties. To configure a proxy, launch the application with the following arguments. diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java index e51ddafa0e..319ebd7992 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationService.java @@ -9,6 +9,6 @@ public interface SecretValidationService { - SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries); + SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, int maximumRetries); } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java index 45fb9ad8cb..a658ca79b4 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java @@ -24,7 +24,7 @@ public class SecretValidationServiceImpl implements SecretValidationService { SecretValidatorWebRequestService webRequestService; @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, int maximumRetries) { ArtifactContent snippet = findingRegion.getSnippet(); SecretValidationResult validationResult = new SecretValidationResult(); if (snippet == null) { @@ -39,7 +39,7 @@ public SecretValidationResult validateFindingByRegion(Region findingRegion, Stri validationResult.setValidationStatus(SecretValidationStatus.SARIF_SNIPPET_NOT_SET); return validationResult; } - return webRequestService.validateFinding(snippetText, ruleId, requests, connectionRetries); + return webRequestService.validateFinding(snippetText, ruleId, requests, maximumRetries); } } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java index 8b98a4f265..262c9cc435 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContext.java @@ -15,7 +15,7 @@ public class SecretValidatorExecutionContext { private Map validatorConfiguration = new HashMap<>(); - private long connectionRetries; + private int maximumRetries; private SecretValidatorExecutionContext() { } @@ -28,8 +28,8 @@ public Map getValidatorConfiguration( return Collections.unmodifiableMap(validatorConfiguration); } - public long getConnectionRetries() { - return connectionRetries; + public int getMaximumRetries() { + return maximumRetries; } public static SecretValidatorExecutionContextBuilder builder() { @@ -42,7 +42,7 @@ public static class SecretValidatorExecutionContextBuilder { private Map validatorConfiguration = new HashMap<>(); - private long connectionRetries; + private int maximumRetries; public SecretValidatorExecutionContextBuilder setSarifReport(SarifSchema210 report) { this.sarifReport = report; @@ -54,8 +54,8 @@ public SecretValidatorExecutionContextBuilder setValidatorConfiguration(Map requests, long connectionRetries) { + public SecretValidationResult validateFinding(String snippetText, String ruleId, List requests, int maximumRetries) { SecretValidationResult validationResult = assertValidParams(snippetText, requests); if (validationResult != null) { return validationResult; } int failedRequests = 0; - for (SecretValidatorRequest request : requests) { + for (SecretValidatorRequest configuredRequest : requests) { HttpResponse response = null; - if (isRequestValid(request)) { - response = createAndExecuteHttpRequest(snippetText, request); + if (isRequestValid(configuredRequest)) { + HttpRequest httpRequest = createHttpRequest(snippetText, configuredRequest); + response = executeHttpRequest(configuredRequest, httpRequest); - // perform retries until the response is not null or we reached our maximum - // amount of retries - int retries = 0; - while (response == null || retries < connectionRetries) { - response = createAndExecuteHttpRequest(snippetText, request); - retries++; + if (response == null) { + response = retryConnection(maximumRetries, configuredRequest, httpRequest); } - if (responseValidationService.isValidResponse(response, request.getExpectedResponse())) { + if (responseValidationService.isValidResponse(response, configuredRequest.getExpectedResponse())) { LOG.info("Finding of type: {} is valid!", ruleId); - return createValidationResult(SecretValidationStatus.VALID, request.getUrl()); + return createValidationResult(SecretValidationStatus.VALID, configuredRequest.getUrl()); } } if (response == null) { @@ -69,6 +66,17 @@ public SecretValidationResult validateFinding(String snippetText, String ruleId, return createValidationResult(SecretValidationStatus.INVALID); } + private HttpResponse retryConnection(int maximumRetries, SecretValidatorRequest configuredRequest, HttpRequest httpRequest) { + HttpResponse response = null; + for (int retries = 0; retries < maximumRetries; retries++) { + response = executeHttpRequest(configuredRequest, httpRequest); + if (response != null) { + return response; + } + } + return response; + } + private SecretValidationResult assertValidParams(String snippetText, List requests) { if (snippetText == null || snippetText.isBlank()) { LOG.warn("Cannot validate finding because the SARIF snippet text is null or empty."); @@ -94,10 +102,9 @@ private boolean isRequestValid(SecretValidatorRequest request) { return true; } - private HttpResponse createAndExecuteHttpRequest(String snippetText, SecretValidatorRequest request) { - HttpRequest httpRequest = createHttpRequest(snippetText, request); - boolean proxyRequired = request.isProxyRequired(); - boolean verifyCertificate = request.isVerifyCertificate(); + private HttpResponse executeHttpRequest(SecretValidatorRequest configuredRequest, HttpRequest httpRequest) { + boolean proxyRequired = configuredRequest.isProxyRequired(); + boolean verifyCertificate = configuredRequest.isVerifyCertificate(); if (proxyRequired) { if (verifyCertificate) { return httpClientWrapper.sendProxiedRequestVerifyCertificate(httpRequest); diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java index 7808492d95..33d0be56ad 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/test/IntegrationTestSecretValidationServiceImpl.java @@ -28,7 +28,7 @@ public class IntegrationTestSecretValidationServiceImpl implements SecretValidationService { @Override - public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, long connectionRetries) { + public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, int maximumRetries) { if (requests == null || requests.isEmpty()) { SecretValidationResult validationResult = new SecretValidationResult(); validationResult.setValidationStatus(SecretValidationStatus.INVALID); diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java index e970694658..a88acdac0f 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorProperties.java @@ -10,10 +10,11 @@ public class SecretValidatorProperties { private final File configFile; - private long connectionRetries; + private int maximumRetries; + private long timeoutSeconds; @ConstructorBinding - public SecretValidatorProperties(File configFile, long connectionRetries) { + public SecretValidatorProperties(File configFile, int maximumRetries, long timeoutSeconds) { if (configFile == null) { throw new IllegalArgumentException("The secret validator configuration file is null!"); } @@ -27,14 +28,19 @@ public SecretValidatorProperties(File configFile, long connectionRetries) { throw new IllegalArgumentException("The secret validator configuration file " + configFile + " is not readable!"); } - this.connectionRetries = connectionRetries; + this.maximumRetries = maximumRetries; + this.timeoutSeconds = timeoutSeconds; } public File getConfigFile() { return configFile; } - public long getConnectionRetries() { - return connectionRetries; + public int getMaximumRetries() { + return maximumRetries; + } + + public long getTimeoutSeconds() { + return timeoutSeconds; } } diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java index eef38663fd..0313c59c3d 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java @@ -10,6 +10,7 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.time.Duration; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; @@ -19,6 +20,8 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import com.mercedesbenz.sechub.wrapper.secret.validator.properties.SecretValidatorProperties; + @Component public class SecretValidatorHttpClientWrapper { @@ -32,24 +35,30 @@ public class SecretValidatorHttpClientWrapper { private HttpClient directHttpClientVerifyCertificate; private HttpClient directHttpClientIgnoreCertificate; - public SecretValidatorHttpClientWrapper() { + public SecretValidatorHttpClientWrapper(SecretValidatorProperties properties) { TrustManager pseudoTrustManager = createTrustManagerWhichTrustsEveryBody(); SSLContext sslContext = createSSLContextForTrustManager(pseudoTrustManager); + + Duration timeout = Duration.ofSeconds(properties.getTimeoutSeconds()); /* @formatter:off */ proxiedHttpClientVerifyCertificate = HttpClient.newBuilder() .proxy(ProxySelector.getDefault()) + .connectTimeout(timeout) .build(); proxiedHttpClientIgnoreCertificate = HttpClient.newBuilder() .proxy(ProxySelector.getDefault()) .sslContext(sslContext) + .connectTimeout(timeout) .build(); directHttpClientVerifyCertificate = HttpClient.newBuilder() + .connectTimeout(timeout) .build(); directHttpClientIgnoreCertificate = HttpClient.newBuilder() .sslContext(sslContext) + .connectTimeout(timeout) .build(); /* @formatter:on */ } diff --git a/sechub-wrapper-secretvalidation/src/main/resources/application.properties b/sechub-wrapper-secretvalidation/src/main/resources/application.properties index 54fd930f98..e39b5f57c5 100644 --- a/sechub-wrapper-secretvalidation/src/main/resources/application.properties +++ b/sechub-wrapper-secretvalidation/src/main/resources/application.properties @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MIT secret.validator.config-file=src/main/resources/gitleaks-github-config.json -secret.validator.connection-retries=3 \ No newline at end of file +secret.validator.maximum-retries=3 +secret.validator.timeout-seconds=5 \ No newline at end of file diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java index e491beb277..8ae5d4d295 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java @@ -40,13 +40,13 @@ void region_snippet_is_null_returns_expected_validation_result() { String ruleId = "rule-id"; Region region = new Region(); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(null, ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(null, ruleId, requests, 0)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0); /* test */ - verify(webRequestService, never()).validateFinding(null, ruleId, requests, 0L); + verify(webRequestService, never()).validateFinding(null, ruleId, requests, 0); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -58,13 +58,13 @@ void region_snippet_text_is_null_returns_expected_validation_result() { Region region = new Region(); region.setSnippet(new ArtifactContent()); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -78,13 +78,13 @@ void region_snippet_text_is_blank_returns_expected_validation_result() { snippet.setText(" "); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0); /* test */ - verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); + verify(webRequestService, never()).validateFinding(region.getSnippet().getText(), ruleId, requests, 0); assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validateFindingByRegion.getValidationStatus()); } @@ -98,13 +98,13 @@ void region_snippet_text_is_set_results_in_web_request_service_called_once() { snippet.setText("secret"); region.setSnippet(snippet); List requests = new ArrayList<>(); - when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0L)).thenReturn(new SecretValidationResult()); + when(webRequestService.validateFinding(region.getSnippet().getText(), ruleId, requests, 0)).thenReturn(new SecretValidationResult()); /* execute */ - SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0L); + SecretValidationResult validateFindingByRegion = serviceToTest.validateFindingByRegion(region, ruleId, requests, 0); /* test */ - verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), ruleId, requests, 0L); + verify(webRequestService, times(1)).validateFinding(region.getSnippet().getText(), ruleId, requests, 0); assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validateFindingByRegion.getValidationStatus()); } diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java index 8f7a702f6a..853b5fd8a2 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java @@ -33,11 +33,11 @@ void beforeEach() { invalidsecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(invalidSarifFile); - invalidProperties = new SecretValidatorProperties(invalidConfigFile, 5L); + invalidProperties = new SecretValidatorProperties(invalidConfigFile, 5, 4L); validSecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(validSarifFile); - validProperties = new SecretValidatorProperties(validConfigFile, 5L); + validProperties = new SecretValidatorProperties(validConfigFile, 5, 4L); } @Test diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java index f37e7f545a..9b0d03bc70 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java @@ -2,6 +2,7 @@ package com.mercedesbenz.sechub.wrapper.secret.validator.execution; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -63,7 +64,7 @@ void finding_cannot_be_validated_results_in_validation_and_categorization_never_ when(ruleConfigurations.get(any())).thenReturn(null); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); + .setValidatorConfiguration(ruleConfigurations).setMaximumRetries(5).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(false); @@ -73,7 +74,7 @@ void finding_cannot_be_validated_results_in_validation_and_categorization_never_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -88,7 +89,7 @@ void empty_config_map_results_in_validation_and_categorization_never_being_calle when(ruleConfigurations.get(any())).thenReturn(null); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); + .setValidatorConfiguration(ruleConfigurations).setMaximumRetries(5).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -98,7 +99,7 @@ void empty_config_map_results_in_validation_and_categorization_never_being_calle /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -115,7 +116,7 @@ void categorization_of_config_is_null_results_in_validation_and_categorization_n when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); + .setValidatorConfiguration(ruleConfigurations).setMaximumRetries(5).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -125,7 +126,7 @@ void categorization_of_config_is_null_results_in_validation_and_categorization_n /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -143,7 +144,7 @@ void categorization_of_config_is_empty_results_in_validation_and_categorization_ when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); + .setValidatorConfiguration(ruleConfigurations).setMaximumRetries(5).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -153,7 +154,7 @@ void categorization_of_config_is_empty_results_in_validation_and_categorization_ /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); } @@ -172,7 +173,7 @@ void finding_location_cannot_be_validated_results_in_validation_and_categorizati when(ruleConfigurations.get(any())).thenReturn(config); SecretValidatorExecutionContext executionContext = SecretValidatorExecutionContext.builder().setSarifReport(report) - .setValidatorConfiguration(ruleConfigurations).setConnectionRetries(5L).build(); + .setValidatorConfiguration(ruleConfigurations).setMaximumRetries(5).build(); when(contextFactory.create()).thenReturn(executionContext); when(sarifValidationSupport.findingCanBeValidated(any())).thenReturn(true); @@ -183,7 +184,7 @@ void finding_location_cannot_be_validated_results_in_validation_and_categorizati /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, never()).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, never()).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, never()).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(1)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(1)).findingLocationCanBeValidated(any()); @@ -196,7 +197,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio when(contextFactory.create()).thenReturn(executionContext); SecretValidationResult secretValidationResult = new SecretValidationResult(); - when(validationService.validateFindingByRegion(any(), any(), any(), 0L)).thenReturn(secretValidationResult); + when(validationService.validateFindingByRegion(any(), any(), any(), anyInt())).thenReturn(secretValidationResult); doNothing().when(sarifEnhancementService).addSerecoSeverityInfo(any(), any(), any()); @@ -208,7 +209,7 @@ void valid_config_and_valid_sarif_report_results_in_validation_and_categorizatio /* test */ verify(contextFactory, times(1)).create(); - verify(validationService, times(6)).validateFindingByRegion(any(), any(), any(), 0L); + verify(validationService, times(6)).validateFindingByRegion(any(), any(), any(), anyInt()); verify(sarifEnhancementService, times(6)).addSerecoSeverityInfo(any(), any(), any()); verify(sarifValidationSupport, times(6)).findingCanBeValidated(any()); verify(sarifValidationSupport, times(6)).findingLocationCanBeValidated(any()); @@ -222,7 +223,7 @@ private SecretValidatorExecutionContext createValidExecutionContext() { /* @formatter:off */ return SecretValidatorExecutionContext.builder() - .setConnectionRetries(5L) + .setMaximumRetries(5) .setSarifReport(report) .setValidatorConfiguration(ruleConfigurations) .build(); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java index 7259c3a1c9..26c741ca82 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestServiceTest.java @@ -38,7 +38,7 @@ void beforeEach() { @Test void no_finding_snippet_text_available_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding(null, "example-rule-id", new ArrayList<>(), 0L); + SecretValidationResult validationResult = serviceTotest.validateFinding(null, "example-rule-id", new ArrayList<>(), 0); /* test */ assertEquals(SecretValidationStatus.SARIF_SNIPPET_NOT_SET, validationResult.getValidationStatus()); @@ -47,7 +47,7 @@ void no_finding_snippet_text_available_results_in_finding_being_skipped_from_val @Test void no_requests_defined_results_in_finding_being_skipped_from_validation() { /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", "example-rule-id", new ArrayList<>(), 0L); + SecretValidationResult validationResult = serviceTotest.validateFinding("not-empty", "example-rule-id", new ArrayList<>(), 0); /* test */ assertEquals(SecretValidationStatus.NO_VALIDATION_CONFIGURED, validationResult.getValidationStatus()); @@ -60,7 +60,7 @@ void request_url_is_null_results_request_will_be_skipped() { requests.add(new SecretValidatorRequest()); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, 0L); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, 0); /* test */ // no validation request was performed ends up with the following status, only @@ -72,7 +72,7 @@ void request_url_is_null_results_request_will_be_skipped() { @ValueSource(booleans = { true, false }) void proxy_required_calls_the_correct_http_client_returns_expected_validation_result(boolean expectedValidation) throws IOException, InterruptedException { /* prepare */ - long connectionRetries = 2L; + int maximumRetries = 2; List requests = createListOfRequests(true); @SuppressWarnings("unchecked") @@ -81,7 +81,7 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, connectionRetries); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, maximumRetries); /* test */ if (expectedValidation) { @@ -91,7 +91,7 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); } - verify(httpClientWrapper, times(3)).sendProxiedRequestVerifyCertificate(any()); + verify(httpClientWrapper, times(1)).sendProxiedRequestVerifyCertificate(any()); verify(httpClientWrapper, never()).sendProxiedRequestIgnoreCertificate(any()); verify(httpClientWrapper, never()).sendDirectRequestVerifyCertificate(any()); @@ -102,23 +102,21 @@ void proxy_required_calls_the_correct_http_client_returns_expected_validation_re @ValueSource(booleans = { true, false }) void no_proxy_required_calls_the_correct_http_client_results_validation_result(boolean expectedValidation) throws IOException, InterruptedException { /* prepare */ - long connectionRetries = 3L; + int maximumRetries = 3; List requests = createListOfRequests(false); - @SuppressWarnings("unchecked") - HttpResponse response = mock(HttpResponse.class); - when(httpClientWrapper.sendDirectRequestVerifyCertificate(any())).thenReturn(response); + when(httpClientWrapper.sendDirectRequestVerifyCertificate(any())).thenReturn(null); when(responseValidationService.isValidResponse(any(), any())).thenReturn(expectedValidation); /* execute */ - SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, connectionRetries); + SecretValidationResult validationResult = serviceTotest.validateFinding("no-empty", "example-rule-id", requests, maximumRetries); /* test */ if (expectedValidation) { assertEquals(SecretValidationStatus.VALID, validationResult.getValidationStatus()); assertEquals("http://example.com", validationResult.getValidatedByUrl()); } else { - assertEquals(SecretValidationStatus.INVALID, validationResult.getValidationStatus()); + assertEquals(SecretValidationStatus.ALL_VALIDATION_REQUESTS_FAILED, validationResult.getValidationStatus()); } verify(httpClientWrapper, times(4)).sendDirectRequestVerifyCertificate(any()); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java index 94fef4f316..c2a8d888be 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorConfigurationSpringBootTest.java @@ -16,7 +16,8 @@ @ExtendWith(SpringExtension.class) @EnableConfigurationProperties @TestPropertySource(properties = { "secret.validator.config-file=src/test/resources/config-test-files/valid-files/test-config.json", - "secret.validator.connection-retries=5", "pds.job.result.file=src/test/resources/config-test-files/valid-files/test-result.txt" }) + "secret.validator.maximum-retries=5", "secret.validator.timeout-seconds=7", + "pds.job.result.file=src/test/resources/config-test-files/valid-files/test-result.txt" }) @ActiveProfiles("test") class SecretValidatorConfigurationSpringBootTest { @@ -31,7 +32,8 @@ void properties_are_created_correctly() { /* test */ // check if all SecretValidatorProperties are as expected - assertEquals(5L, properties.getConnectionRetries()); + assertEquals(5L, properties.getMaximumRetries()); + assertEquals(7, properties.getTimeoutSeconds()); assertEquals("src/test/resources/config-test-files/valid-files/test-config.json", properties.getConfigFile().toString()); // check if the PDS job result file is as expected diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java index 4701ed37b7..8c33752327 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/properties/SecretValidatorPropertiesTest.java @@ -14,7 +14,7 @@ class SecretValidatorPropertiesTest { @Test void validator_config_file_is_null_throws_exception() { /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(null, 5L)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(null, 5, 4L)); } @Test @@ -24,7 +24,7 @@ void not_existing_validator_config_file_throws_exception() { when(notExisting.exists()).thenReturn(false); /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notExisting, 5L)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notExisting, 5, 4L)); } @Test @@ -35,7 +35,7 @@ void not_readable_validator_config_file_throws_exception() { when(notReadable.canRead()).thenReturn(false); /* execute + test */ - assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notReadable, 5L)); + assertThrows(IllegalArgumentException.class, () -> new SecretValidatorProperties(notReadable, 5, 4L)); } @Test @@ -44,11 +44,12 @@ void valid_properties_result_in_valid_configuration() { File validConfigFile = new File("src/test/resources/config-test-files/valid-files/test-config.json"); /* execute */ - SecretValidatorProperties properties = new SecretValidatorProperties(validConfigFile, 5L); + SecretValidatorProperties properties = new SecretValidatorProperties(validConfigFile, 5, 4L); /* test */ assertEquals(validConfigFile, properties.getConfigFile()); - assertEquals(5L, properties.getConnectionRetries()); + assertEquals(5L, properties.getMaximumRetries()); + assertEquals(4, properties.getTimeoutSeconds()); } } From f9459a0ed422f7ab5a7cd4ccbcbeaf7da37928a7 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 09:51:55 +0200 Subject: [PATCH 04/10] Change link to application.properties #3378 --- sechub-wrapper-secretvalidation/README.adoc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index 2e35ce46d0..edc1b340e3 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -96,11 +96,7 @@ This can be useful, in certain situations or setups. ==== ===== Default spring boot configuration -The defaults can be found inside the <> file: -[source,properties] ----- -include::src/main/resources/application.properties[] ----- +The defaults can be found inside the link:src/main/resources/application.properties[View application.properties] file: ===== Proxy configuration Inside the configuration file each request has to configure if a proxy server is required to access this specific URL or not. From df8102a5105d8b2dd8b9e99041df719cc82ed91e Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 10:17:06 +0200 Subject: [PATCH 05/10] Refactoring #3378 --- sechub-wrapper-secretvalidation/README.adoc | 2 +- .../validator/cli/SecretValidatorCLI.java | 11 +++--- .../SecretValidationServiceImpl.java | 8 +++-- ...ecretValidatorExecutionContextFactory.java | 11 +++--- .../SecretValidatorExecutionService.java | 25 ++++++++------ .../SecretValidatorWebRequestService.java | 4 +-- .../SecretValidatorHttpClientWrapper.java | 6 ++-- .../SecretValidationServiceImplTest.java | 9 +++-- ...tValidatorExecutionContextFactoryTest.java | 34 +++++-------------- .../SecretValidatorExecutionServiceTest.java | 21 ++++-------- 10 files changed, 58 insertions(+), 73 deletions(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index edc1b340e3..8d3773d772 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -96,7 +96,7 @@ This can be useful, in certain situations or setups. ==== ===== Default spring boot configuration -The defaults can be found inside the link:src/main/resources/application.properties[View application.properties] file: +The defaults can be found inside the link:src/main/resources/application.properties[application.properties] file: ===== Proxy configuration Inside the configuration file each request has to configure if a proxy server is required to access this specific URL or not. diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/cli/SecretValidatorCLI.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/cli/SecretValidatorCLI.java index fd7e18170b..37f1717fd6 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/cli/SecretValidatorCLI.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/cli/SecretValidatorCLI.java @@ -3,7 +3,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @@ -21,11 +20,13 @@ public class SecretValidatorCLI implements CommandLineRunner { private static final Logger LOG = LoggerFactory.getLogger(SecretValidatorCLI.class); - @Autowired - SecretValidatorExecutionService executionService; + private final SecretValidatorExecutionService executionService; + private final SecretValidatorPDSJobResult pdsJobResult; - @Autowired - SecretValidatorPDSJobResult pdsJobResult; + public SecretValidatorCLI(SecretValidatorExecutionService executionService, SecretValidatorPDSJobResult pdsJobResult) { + this.executionService = executionService; + this.pdsJobResult = pdsJobResult; + } @Override public void run(String... args) throws Exception { diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java index a658ca79b4..b57e9d0c35 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImpl.java @@ -5,7 +5,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @@ -20,8 +19,11 @@ public class SecretValidationServiceImpl implements SecretValidationService { private static final Logger LOG = LoggerFactory.getLogger(SecretValidationServiceImpl.class); - @Autowired - SecretValidatorWebRequestService webRequestService; + private final SecretValidatorWebRequestService webRequestService; + + public SecretValidationServiceImpl(SecretValidatorWebRequestService webRequestService) { + this.webRequestService = webRequestService; + } @Override public SecretValidationResult validateFindingByRegion(Region findingRegion, String ruleId, List requests, int maximumRetries) { diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactory.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactory.java index 59f204421a..cc05ce3e4c 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactory.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactory.java @@ -7,7 +7,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.mercedesbenz.sechub.commons.TextFileReader; @@ -23,11 +22,13 @@ public class SecretValidatorExecutionContextFactory { private static final Logger LOG = LoggerFactory.getLogger(SecretValidatorExecutionContextFactory.class); - @Autowired - SecretValidatorPDSJobResult pdsResult; + private final SecretValidatorPDSJobResult pdsResult; + private final SecretValidatorProperties properties; - @Autowired - SecretValidatorProperties properties; + public SecretValidatorExecutionContextFactory(SecretValidatorPDSJobResult pdsResult, SecretValidatorProperties properties) { + this.pdsResult = pdsResult; + this.properties = properties; + } TextFileReader reader = new TextFileReader(); diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java index 352975c789..0c4b4e02c6 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionService.java @@ -6,7 +6,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.mercedesbenz.sechub.wrapper.secret.validator.model.SecretValidatorCategorization; @@ -23,17 +22,23 @@ public class SecretValidatorExecutionService { private static final Logger LOG = LoggerFactory.getLogger(SecretValidatorExecutionService.class); - @Autowired - SecretValidatorExecutionContextFactory contextFactory; + private final SecretValidatorExecutionContextFactory contextFactory; + private final SecretValidationService validationService; + private final SerecoSeveritySarifEnhancementService sarifEnhancementService; + private final SarifValidationSupport sarifValidationSupport; - @Autowired - SecretValidationService validationService; + /* @formatter:off */ + public SecretValidatorExecutionService(SecretValidatorExecutionContextFactory contextFactory, + SecretValidationService validationService, + SerecoSeveritySarifEnhancementService sarifEnhancementService, + SarifValidationSupport sarifValidationSupport) { - @Autowired - SerecoSeveritySarifEnhancementService sarifEnhancementService; - - @Autowired - SarifValidationSupport sarifValidationSupport; + this.contextFactory = contextFactory; + this.validationService = validationService; + this.sarifEnhancementService = sarifEnhancementService; + this.sarifValidationSupport = sarifValidationSupport; + /* @formatter:on */ + } public SarifSchema210 execute() { SecretValidatorExecutionContext executionContext = contextFactory.create(); diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java index 0c05ef7077..496433b95d 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorWebRequestService.java @@ -21,9 +21,9 @@ public class SecretValidatorWebRequestService { private static final Logger LOG = LoggerFactory.getLogger(SecretValidatorWebRequestService.class); - private SecretValidatorHttpClientWrapper httpClientWrapper; + private final SecretValidatorHttpClientWrapper httpClientWrapper; - private ResponseValidationService responseValidationService; + private final ResponseValidationService responseValidationService; public SecretValidatorWebRequestService(ResponseValidationService responseValidationService, SecretValidatorHttpClientWrapper httpClientWrapper) { diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java index 0313c59c3d..2e2509f211 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java @@ -29,11 +29,11 @@ public class SecretValidatorHttpClientWrapper { private static final String TLS = "TLS"; - private HttpClient proxiedHttpClientVerifyCertificate; + private final HttpClient proxiedHttpClientVerifyCertificate; private HttpClient proxiedHttpClientIgnoreCertificate; - private HttpClient directHttpClientVerifyCertificate; - private HttpClient directHttpClientIgnoreCertificate; + private final HttpClient directHttpClientVerifyCertificate; + private final HttpClient directHttpClientIgnoreCertificate; public SecretValidatorHttpClientWrapper(SecretValidatorProperties properties) { TrustManager pseudoTrustManager = createTrustManagerWhichTrustsEveryBody(); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java index 8ae5d4d295..02d5f7d9c3 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidationServiceImplTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import com.mercedesbenz.sechub.wrapper.secret.validator.model.SecretValidatorRequest; @@ -23,15 +24,13 @@ class SecretValidationServiceImplTest { private SecretValidationServiceImpl serviceToTest; - private SecretValidatorWebRequestService webRequestService; + private static final SecretValidatorWebRequestService webRequestService = mock(); @BeforeEach void beforeEach() { - serviceToTest = new SecretValidationServiceImpl(); - - webRequestService = mock(SecretValidatorWebRequestService.class); - serviceToTest.webRequestService = webRequestService; + Mockito.reset(webRequestService); + serviceToTest = new SecretValidationServiceImpl(webRequestService); } @Test diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java index 853b5fd8a2..4061a719a5 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java @@ -7,7 +7,6 @@ import java.io.File; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.mercedesbenz.sechub.wrapper.secret.validator.properties.SecretValidatorPDSJobResult; @@ -15,35 +14,22 @@ class SecretValidatorExecutionContextFactoryTest { - private SecretValidatorExecutionContextFactory factoryToTest; - - private SecretValidatorPDSJobResult invalidsecretValidatorPDSJobResult; - private SecretValidatorPDSJobResult validSecretValidatorPDSJobResult; - private SecretValidatorProperties invalidProperties; - private SecretValidatorProperties validProperties; - + /* @formatter:off */ private static final File invalidSarifFile = new File("src/test/resources/config-test-files/invalid-files/invalid-sarif.txt"); private static final File invalidConfigFile = new File("src/test/resources/config-test-files/invalid-files/invalid-validator-config.txt"); private static final File validSarifFile = new File("src/test/resources/config-test-files/valid-files/test-result.txt"); private static final File validConfigFile = new File("src/test/resources/config-test-files/valid-files/test-config.json"); - @BeforeEach - void beforeEach() { - factoryToTest = new SecretValidatorExecutionContextFactory(); - - invalidsecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(invalidSarifFile); - - invalidProperties = new SecretValidatorProperties(invalidConfigFile, 5, 4L); - - validSecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(validSarifFile); - - validProperties = new SecretValidatorProperties(validConfigFile, 5, 4L); - } + private static final SecretValidatorPDSJobResult invalidsecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(invalidSarifFile); + private static final SecretValidatorPDSJobResult validSecretValidatorPDSJobResult = new SecretValidatorPDSJobResult(validSarifFile); + private static final SecretValidatorProperties invalidProperties = new SecretValidatorProperties(invalidConfigFile, 5, 4L); + private static final SecretValidatorProperties validProperties = new SecretValidatorProperties(validConfigFile, 5, 4L); + /* @formatter:on */ @Test void invalid_sarif_pds_job_result_file_throws_exception() { /* prepare */ - factoryToTest.pdsResult = invalidsecretValidatorPDSJobResult; + SecretValidatorExecutionContextFactory factoryToTest = new SecretValidatorExecutionContextFactory(invalidsecretValidatorPDSJobResult, validProperties); /* execute + test */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> factoryToTest.create()); @@ -53,8 +39,7 @@ void invalid_sarif_pds_job_result_file_throws_exception() { @Test void invalid_secret_validator_config_file_throws_exception() { /* prepare */ - factoryToTest.pdsResult = validSecretValidatorPDSJobResult; - factoryToTest.properties = invalidProperties; + SecretValidatorExecutionContextFactory factoryToTest = new SecretValidatorExecutionContextFactory(validSecretValidatorPDSJobResult, invalidProperties); /* execute + test */ IllegalStateException exception = assertThrows(IllegalStateException.class, () -> factoryToTest.create()); @@ -64,8 +49,7 @@ void invalid_secret_validator_config_file_throws_exception() { @Test void valid_files_return_valid_execution_context() { /* prepare */ - factoryToTest.pdsResult = validSecretValidatorPDSJobResult; - factoryToTest.properties = validProperties; + SecretValidatorExecutionContextFactory factoryToTest = new SecretValidatorExecutionContextFactory(validSecretValidatorPDSJobResult, validProperties); /* execute */ SecretValidatorExecutionContext secretValidatorExecutionContext = factoryToTest.create(); diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java index 9b0d03bc70..8e4e88dff7 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionServiceTest.java @@ -18,6 +18,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import com.mercedesbenz.sechub.commons.model.JSONConverter; import com.mercedesbenz.sechub.test.TestFileReader; @@ -35,24 +36,16 @@ class SecretValidatorExecutionServiceTest { private SecretValidatorExecutionService serviceToTest; - private SecretValidatorExecutionContextFactory contextFactory; - private SecretValidationServiceImpl validationService; - private SerecoSeveritySarifEnhancementService sarifEnhancementService; - private SarifValidationSupport sarifValidationSupport; + private static final SecretValidatorExecutionContextFactory contextFactory = mock(); + private static final SecretValidationServiceImpl validationService = mock(); + private static final SerecoSeveritySarifEnhancementService sarifEnhancementService = mock(); + private static final SarifValidationSupport sarifValidationSupport = mock(); @BeforeEach void beforeEach() { - serviceToTest = new SecretValidatorExecutionService(); + Mockito.reset(contextFactory, validationService, sarifEnhancementService, sarifValidationSupport); - contextFactory = mock(SecretValidatorExecutionContextFactory.class); - validationService = mock(SecretValidationServiceImpl.class); - sarifEnhancementService = mock(SerecoSeveritySarifEnhancementService.class); - sarifValidationSupport = mock(SarifValidationSupport.class); - - serviceToTest.contextFactory = contextFactory; - serviceToTest.validationService = validationService; - serviceToTest.sarifEnhancementService = sarifEnhancementService; - serviceToTest.sarifValidationSupport = sarifValidationSupport; + serviceToTest = new SecretValidatorExecutionService(contextFactory, validationService, sarifEnhancementService, sarifValidationSupport); } @Test From e32c737422e3e8ba0144f4053938f69af0df3b55 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 10:45:18 +0200 Subject: [PATCH 06/10] Update documentation and remove not useful default #3378 --- sechub-wrapper-secretvalidation/README.adoc | 4 +++- .../src/main/resources/application.properties | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index 8d3773d772..978928c981 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -15,10 +15,12 @@ In case the secret was valid,the key `secretscan.validated.by.url` will be added The wrapper application is an executable jar and needs no command line arguments. It can automatically use all https://mercedes-benz.github.io/sechub/latest/sechub-product-delegation-server.html#launcher-scripts[standard PDS environment variables] -and following special mandatory environment variable: +and following special mandatory environment variable. Regarding the following mandatory parameters in a pds-soultion the environment variable `PDS_JOB_RESULT_FILE` should always be available, +since this application is supposed to run after the secret scanning tool, when a SARIF report was already written to `$PDS_JOB_RESULT_FILE`: ---- SECRET_VALIDATOR_CONFIGFILE +PDS_JOB_RESULT_FILE ---- [IMPORTANT] diff --git a/sechub-wrapper-secretvalidation/src/main/resources/application.properties b/sechub-wrapper-secretvalidation/src/main/resources/application.properties index e39b5f57c5..cdf05c1c62 100644 --- a/sechub-wrapper-secretvalidation/src/main/resources/application.properties +++ b/sechub-wrapper-secretvalidation/src/main/resources/application.properties @@ -1,5 +1,4 @@ # SPDX-License-Identifier: MIT -secret.validator.config-file=src/main/resources/gitleaks-github-config.json secret.validator.maximum-retries=3 secret.validator.timeout-seconds=5 \ No newline at end of file From 5cdfe8e92d64ee5790b530acdf7bab3a373cdfc5 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Thu, 22 Aug 2024 12:20:42 +0200 Subject: [PATCH 07/10] Update documentation #3379 --- sechub-wrapper-secretvalidation/README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index 978928c981..179bc94b22 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -89,7 +89,7 @@ SECRET_VALIDATOR_TIMEOUTSECONDS [TIP] ==== The property `secret.validator.maximum-retries` or the corresponding environment variable `SECRET_VALIDATOR_MAXIMUMRETRIES` can be used to specify the `number of retries` for each of the request, to be more resistant to network issues. -The default value is `3` meaning in the worst case `4` requests will be performed on connection issues. +The default value is `3` meaning in the worst case scenario `4` requests will be performed for each secret. The property `secret.validator.timeout-seconds` or the corresponding environment variable `SECRET_VALIDATOR_TIMEOUTSECONDS` can be used to specify the number of `seconds` for each of the request before returning because of a timeout. The default value is `5` seconds. This means on default after maximum `5` seconds the next request will be performed. From da2ab630c84e584e2c58367f1b74fb4134cc6a62 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Fri, 23 Aug 2024 11:14:57 +0200 Subject: [PATCH 08/10] PR Review changes #3379 --- sechub-wrapper-secretvalidation/README.adoc | 2 +- .../validator/support/SecretValidatorHttpClientWrapper.java | 2 +- .../execution/SecretValidatorExecutionContextFactoryTest.java | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sechub-wrapper-secretvalidation/README.adoc b/sechub-wrapper-secretvalidation/README.adoc index 179bc94b22..b405efb0f7 100644 --- a/sechub-wrapper-secretvalidation/README.adoc +++ b/sechub-wrapper-secretvalidation/README.adoc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -== Secret valdiation Wrapper +== Secret validation Wrapper This wrapper is a Spring Boot application, that is supposed to run on PDS solutions performing secret scans. After the secret scanning tool is done it will try to validate secrets found and enhance the SARIF report with a custom PropertyBag for each finding location. diff --git a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java index 2e2509f211..408b7eb42b 100644 --- a/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java +++ b/sechub-wrapper-secretvalidation/src/main/java/com/mercedesbenz/sechub/wrapper/secret/validator/support/SecretValidatorHttpClientWrapper.java @@ -30,7 +30,7 @@ public class SecretValidatorHttpClientWrapper { private static final String TLS = "TLS"; private final HttpClient proxiedHttpClientVerifyCertificate; - private HttpClient proxiedHttpClientIgnoreCertificate; + private final HttpClient proxiedHttpClientIgnoreCertificate; private final HttpClient directHttpClientVerifyCertificate; private final HttpClient directHttpClientIgnoreCertificate; diff --git a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java index 4061a719a5..5813bbdce9 100644 --- a/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java +++ b/sechub-wrapper-secretvalidation/src/test/java/com/mercedesbenz/sechub/wrapper/secret/validator/execution/SecretValidatorExecutionContextFactoryTest.java @@ -1,9 +1,7 @@ // SPDX-License-Identifier: MIT package com.mercedesbenz.sechub.wrapper.secret.validator.execution; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import java.io.File; From 4c569ebbc170e0468e1d766ac73e75aab15990e9 Mon Sep 17 00:00:00 2001 From: Jan Winz Date: Fri, 23 Aug 2024 11:33:18 +0200 Subject: [PATCH 09/10] Remove unused file #3379 --- .../resources/gitleaks-github-config.json | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json diff --git a/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json b/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json deleted file mode 100644 index 0ff864f637..0000000000 --- a/sechub-wrapper-secretvalidation/src/main/resources/gitleaks-github-config.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "validatorConfigList" : [ { - "ruleId" : "github-pat", - "categorization" : { - "defaultSeverity" : "high", - "validationFailedSeverity" : "medium", - "validationSuccessSeverity" : "critical" - }, - "requests" : [ { - "proxyRequired" : true, - "url" : "https://api.github.com", - "headers" : [ { - "name" : "Authorization", - "valuePrefix" : "Bearer" - } ], - "expectedResponse" : { - "httpStatus" : 200 - } - } ] - } ] -} \ No newline at end of file From 3483f1597a996b638f33f30fc54ec5eddaa78049 Mon Sep 17 00:00:00 2001 From: "sven-dmlr (via github-actions)" Date: Fri, 23 Aug 2024 09:58:51 +0000 Subject: [PATCH 10/10] docs update by SecHub release job @github-actions --- ...ram_falsepositives_definition_overview.svg | 2 +- ...iagram_falsepositives_runtime_overview.svg | 2 +- .../images/diagram_pds_events_storage.svg | 2 +- .../diagram_sechub_job_cancellation.svg | 2 +- .../images/diagram_target_architecture.svg | 2 +- ...rview_uc_admin_assigns_user_to_project.svg | 2 +- ...admin_enables_scheduler_job_processing.svg | 2 +- ...w_uc_admin_unassigns_user_from_project.svg | 2 +- ...min_updates_auto_cleanup_configuration.svg | 2 +- docs/latest/sechub-architecture.html | 765 +++++++++++----- docs/latest/sechub-client.html | 22 +- .../sechub-developer-quickstart-guide.html | 6 +- docs/latest/sechub-getting-started.html | 6 +- docs/latest/sechub-operations.html | 6 +- .../sechub-product-delegation-server.html | 8 +- docs/latest/sechub-restapi.html | 844 ++++++++++++------ docs/latest/sechub-techdoc.html | 808 +++++++++++++---- docs/latest/sechub-tutorials.html | 6 +- docs/latest/server-download.html | 2 +- 19 files changed, 1762 insertions(+), 729 deletions(-) diff --git a/docs/latest/images/diagram_falsepositives_definition_overview.svg b/docs/latest/images/diagram_falsepositives_definition_overview.svg index 4383a962df..7465bb7fdd 100644 --- a/docs/latest/images/diagram_falsepositives_definition_overview.svg +++ b/docs/latest/images/diagram_falsepositives_definition_overview.svg @@ -1 +1 @@ -com.mercedesbenz.sechub.domain.scan.projectcom.mercedesbenz.sechub.domain.scan.reportcom.mercedesbenz.sechub.commons.modelFalsePositiveJobDataServiceScanReportRepository : scanReportRepositoryScanProjectConfigService : configServiceFalsePositiveJobDataListValidation : falsePositiveJobDataListValidationFalsePositiveJobDataConfigMerger : mergerFalsePositiveJobDataConfigMergerFalsePositiveJobDataListString : apiVersionString : typeFalsePositiveJobData : jobDataFalsePositiveJobDataListValidationFalsePositiveProjectConfigurationList<FalsePositiveEntry> : falsePositivesScanProjectConfigServiceScanProjectConfigRepository : repositoryFalsePositiveCodePartMetaDataString : locationString : relevantPartString : sourceCodeFalsePositiveEntryFalsePositiveJobData : jobDataString : authorFalsePositiveMetaData : metaDataDate : createdFalsePositiveJobDataUUID : jobUUIDString : commentFalsePositiveMetaDataScanType : scanTypeString : nameSeverity : severityFalsePositiveCodeMetaData : codeFalsePositiveWebMetaData : webInteger : cweIdString : cveIdString : owaspScanProjectConfigScanProjectConfigRepositoryFalsePositiveCodeMetaDataFalsePositiveCodePartMetaData : startFalsePositiveCodePartMetaData : endFalsePositiveWebMetaDataFalsePositiveWebRequestMetaData : requestFalsePositiveWebResponseMetaData: responseFalsePositiveWebRequestMetaDataString: methodString: targetString: protocolString: versionString: attackVectorFalsePositiveWebResponseMetaDataString: evidenceint: statuscodeScanReportRepositoryScanSecHubReportSecHubCodeCallStackSecHubFindingScanTypeSeverity \ No newline at end of file +com.mercedesbenz.sechub.domain.scan.projectcom.mercedesbenz.sechub.domain.scan.reportcom.mercedesbenz.sechub.commons.modelFalsePositiveDataServiceScanReportRepository : scanReportRepositoryScanProjectConfigService : configServiceFalsePositiveDataListValidation : falsePositiveJobDataListValidationFalsePositiveDataConfigMerger : mergerFalsePositiveDataConfigMergerFalsePositiveDataListString : apiVersionString : typeFalsePositiveJobData : jobDataFalsePositiveDataListValidationFalsePositiveProjectConfigurationList<FalsePositiveEntry> : falsePositivesScanProjectConfigServiceScanProjectConfigRepository : repositoryFalsePositiveCodePartMetaDataString : locationString : relevantPartString : sourceCodeFalsePositiveEntryFalsePositiveJobData : jobDataString : authorFalsePositiveMetaData : metaDataDate : createdFalsePositiveJobDataUUID : jobUUIDString : commentFalsePositiveMetaDataScanType : scanTypeString : nameSeverity : severityFalsePositiveCodeMetaData : codeFalsePositiveWebMetaData : webInteger : cweIdString : cveIdString : owaspFalsePositiveProjectDataString : idString : commentWebscanFalsePositiveProjectData: webScanScanProjectConfigScanProjectConfigRepositoryWebscanFalsePositiveProjectDataInteger : cweIdList<String> : hostPatternsList<String> : urlPathPatternsList<String> : protocolsList<String> : portsList<String> : methodsFalsePositiveCodeMetaDataFalsePositiveCodePartMetaData : startFalsePositiveCodePartMetaData : endFalsePositiveWebMetaDataFalsePositiveWebRequestMetaData : requestFalsePositiveWebResponseMetaData: responseFalsePositiveWebRequestMetaDataString: methodString: targetString: protocolString: versionString: attackVectorFalsePositiveWebResponseMetaDataString: evidenceint: statuscodeScanReportRepositoryScanSecHubReportSecHubCodeCallStackSecHubFindingScanTypeSeverity \ No newline at end of file diff --git a/docs/latest/images/diagram_falsepositives_runtime_overview.svg b/docs/latest/images/diagram_falsepositives_runtime_overview.svg index 963625e9e5..e3f74e31ad 100644 --- a/docs/latest/images/diagram_falsepositives_runtime_overview.svg +++ b/docs/latest/images/diagram_falsepositives_runtime_overview.svg @@ -1 +1 @@ -com.mercedesbenz.sechub.domain.scan.product.serecocom.mercedesbenz.sechub.domain.scan.projectcom.mercedesbenz.sechub.sereco.metadataSerecoFalsePositiveMarkerSerecoFalsePositiveFinder : falsePositiveCodeFinderScanProjectConfigService : scanProjectConfigServiceSerecoFalsePositiveFinderSerecoFalsePositiveCodeScanStrategy : codeSCanStrategySerecoFalsePositiveCodeScanStrategySerecoSourceRelevantPartResolver : relevantPartResolverSerecoFalsePositiveWebScanStrategySerecoSourceRelevantPartResolverFalsePositiveEntryScanProjectConfigServiceFalsePositiveMetaDataFalsePositiveCodePartMetaDataSerecoVulnerabilitySerecoCodeCallStackElement \ No newline at end of file +com.mercedesbenz.sechub.domain.scan.product.serecocom.mercedesbenz.sechub.domain.scan.projectcom.mercedesbenz.sechub.sereco.metadataSerecoFalsePositiveMarkerSerecoJobDataFalsePositiveFinder : jobDatafalsePositiveCodeFinderScanProjectConfigService : scanProjectConfigServiceSerecoProjectDataFalsePositiveFinder: projectDataFalsePositiveFinderSerecoProjectDataPatternMapFactory: projectDataPatternMapFactorySerecoJobDataFalsePositiveFinderCodeScanJobDataFalsePositiveStrategy : jobDataCodeScanStrategySecretScanJobDataFalsePositiveStrategy: jobDataSecretScanStrategyWebScanJobDataFalsePositiveStrategy: jobDataSebScanStrategySerecoProjectDataFalsePositiveFinderWebScanProjectDataFalsePositiveStrategy: webScanProjectDataStrategySerecoProjectDataPatternMapFactoryCodeScanJobDataFalsePositiveStrategySerecoSourceRelevantPartResolver : relevantPartResolverWebScanJobDataFalsePositiveStrategySecretScanJobDataFalsePositiveStrategySerecoSourceRelevantPartResolverWebScanProjectDataFalsePositiveStrategyFalsePositiveEntryScanProjectConfigServiceFalsePositiveMetaDataFalsePositiveCodePartMetaDataFalsePositiveProjectDataSerecoVulnerabilitySerecoCodeCallStackElement \ No newline at end of file diff --git a/docs/latest/images/diagram_pds_events_storage.svg b/docs/latest/images/diagram_pds_events_storage.svg index 335f19d0ff..56071a05dc 100644 --- a/docs/latest/images/diagram_pds_events_storage.svg +++ b/docs/latest/images/diagram_pds_events_storage.svg @@ -1 +1 @@ -$workspace/$jobUUID/eventsPDS-Job-QueuelauncherScriptEvent FilePDSWorkspaceServicevoid sendEvent(UUID jobUUID, ExecutionEventType eventType,ExecutionEventData eventData)ExecutionEventData fetchEventDataOrNull(UUID jobUUID, ExecutionEventType eventType) {ExecutionEventDataPDSExecutionCallableFactoryPDSExecutionCallablePDSBatchTriggerServicevoid triggerExecutionOfNextJob()PDSJobCancelTriggerServicevoid triggerHandleCancelRequests()PDSCancelServicevoid handleJobCancelRequests()PDSExecutionServiceInside the event folder we havefiles with name pattern"${eventTypeName}.json". Someevents have only one file.Remark: Currently not implemented,but if an event type shall supports multiplefiles in future the name pattern shall be:"${eventTypeName}[${nr}].json"cancel job by job UUIDcreatescreates/useswrites/reads event filesinto workspace foldercontains files whichhave JSOn contentcan readcreates processprepares workspace, sends eventscallsuses \ No newline at end of file +$workspace/$jobUUID/eventsPDS-Job-QueuelauncherScriptEvent FilePDSWorkspaceServicevoid sendEvent(UUID jobUUID, ExecutionEventType eventType,ExecutionEventData eventData)ExecutionEventData fetchEventDataOrNull(UUID jobUUID, ExecutionEventType eventType) {ExecutionEventDataPDSExecutionCallableFactoryPDSExecutionCallablePDSBatchTriggerServicevoid triggerExecutionOfNextJob()PDSJobCancelTriggerServicevoid triggerHandleCancelRequests()PDSCancelServicevoid handleJobCancelRequests()PDSExecutionServiceInside the event folder we havefiles with name pattern"${eventTypeName}.json". Someevents have only one file.Remark: Currently not implemented,but if an event type shall supports multiplefiles in future the name pattern shall be:"${eventTypeName}[${nr}].json"cancel job by job UUIDcreatescreates/useswrites/reads event filesinto workspace foldercontains files whichhave JSOn contentcan readcreates processprepares workspace, sends eventscallsuses \ No newline at end of file diff --git a/docs/latest/images/diagram_sechub_job_cancellation.svg b/docs/latest/images/diagram_sechub_job_cancellation.svg index c4053637ef..33ad1462c8 100644 --- a/docs/latest/images/diagram_sechub_job_cancellation.svg +++ b/docs/latest/images/diagram_sechub_job_cancellation.svg @@ -1 +1 @@ -Event Nr.Message IDWhat happens at this event ?A1START_SCANScan - runningB1REQUEST_SCHEDULER_JOB_STATUSScan - periodic inspection if scheduler job marked as cancel requestedC1REQUEST_JOB_CANCELLATIONCancel request startedD1CANCELLATION_RUNNINGCancel scan running/ ongoingE1PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONEProduct execucutor cancel operations have finished (post processing donecom.mercedesbenz.sechub.domain.schedulecom.mercedesbenz.sechub.sharedkernelcom.mercedesbenz.sechub.domain.scancom.mercedesbenz.sechub.domain.administrationcom.mercedesbenz.sechub.domain.notification«Entity»ScheduleSecHubJobExecutionStateINITIALIZINGREADY_TO_STARTSTARTEDCANCEL_REQUESTEDCANCELEDENDEDExecutionResultNONEOKFAILEDSynchronSecHubJobExecutorSchedulerJobStatusRequestHandlerScheduleJobLauncherServiceSchedulerJobBatchTriggerServiceScheduleMessagehandlerhandleCancelJobRequested()SchedulerCancelJobServiceThe steps- D*are only triggered when the SecHub job hasthe execution result NONE.The execution state isnotinspected.DomainMessageServiceEventBus«Entity»ProductResultUUID uuidUUID secHubJobUUIDUUID productExecutorConfigUUIDString resultString messagesString metaDataLocalDateTime startedLocalDateTime endedSecHubExecutionContextmarkCancelRequested()ScanProgressMonitorProductExecutorList<ProductResult> execute(SecHubExecutionContext context, ProductExecutorContext executorContext)ScanServicestartScan()ScanJobExecutorScanJobExecutionRunnableScanJobCancellationRunnableAdapterAdapterExecutionResult start(C config, AdapterMetaDataCallback callback)boolean cancel(C config, AdapterMetaDataCallback callback)ProductExecutionStoreServiceexecuteProductsAndStoreResults(SecHubExecutionContext context)AbstractProductExecutionServiceAbstractProductExecutorCanceableProductExecutorboolean cancel(ProductExecutorData data)ScanJobRunnableDataProductExecutorDataSecHubExecutionHistorySecHubExecutionHistoryElementThe scan job executor is central point ofthe scan steep in scan domain.It does the start of the scan itself anddoes also periodically the inspect the schedulerjob status via event busExecutorThreadCancellationThreadJobAdministrationRestControllerJobAdministrationMessageHandlerJobCancelServiceNotificationMessageHandlerProcuctIs used to have eventcommunications between domainssends async REQUEST_JOB_CANCELLATION (C1)sends async CANCELLATION_RUNNING (D1)sends async CANCELLATION_RUNNING (D1)stores resultusescalls cancel servicebecause of C2marks as CANCEL_REQUESTED (C3)callssends async CANCELLATION_RUNNING (D1)sends async REQUEST_JOB_CANCELLATION (C1)receives "PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONE" (E1) ASYNCHRONsends synch REQUEST_SCHEDULER_JOB_STATUS (B1)set SecHub job finally as CANCELEDcreatesusesstores resultsusescallsusesconfigures and usesusescreates + uses (A3)runsinterrupts ExecutorThreadwhen being canceled.This immediately interrupts all product calls hard.runscreatescancelsstartscreates if necessarystarts when necessarycreates contextcreatesmarks as cancel requestedso available in product executorscallsuses information aboutproduct executors and datasends "START_SCAN" (A1) SYNCHRONsends synchron REQUEST_SCHEDULER_JOB_STATUS (B1)and receives job statusrecevies "START_SCAN" (A2) SYNCHRON (returns result)communicationsends "PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONE" (E1) ASYNCHRON \ No newline at end of file +Event Nr.Message IDWhat happens at this event ?A1START_SCANScan - runningB1REQUEST_SCHEDULER_JOB_STATUSScan - periodic inspection if scheduler job marked as cancel requestedC1REQUEST_JOB_CANCELLATIONCancel request startedD1CANCELLATION_RUNNINGCancel scan running/ ongoingE1PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONEProduct execucutor cancel operations have finished (post processing donecom.mercedesbenz.sechub.domain.schedulecom.mercedesbenz.sechub.sharedkernelcom.mercedesbenz.sechub.domain.scancom.mercedesbenz.sechub.domain.administrationcom.mercedesbenz.sechub.domain.notification«Entity»ScheduleSecHubJobExecutionStateINITIALIZINGREADY_TO_STARTSTARTEDCANCEL_REQUESTEDCANCELEDENDEDExecutionResultNONEOKFAILEDSynchronSecHubJobExecutorSchedulerJobStatusRequestHandlerScheduleJobLauncherServiceSchedulerJobBatchTriggerServiceScheduleMessagehandlerhandleCancelJobRequested()SchedulerCancelJobServiceThe steps- D*are only triggered when the SecHub job hasthe execution result NONE.The execution state isnotinspected.DomainMessageServiceEventBus«Entity»ProductResultUUID uuidUUID secHubJobUUIDUUID productExecutorConfigUUIDString resultString messagesString metaDataLocalDateTime startedLocalDateTime endedSecHubExecutionContextmarkCancelRequested()ScanProgressMonitorProductExecutorList<ProductResult> execute(SecHubExecutionContext context, ProductExecutorContext executorContext)ScanServicestartScan()ScanJobExecutorScanJobExecutionRunnableScanJobCancellationRunnableAdapterAdapterExecutionResult start(C config, AdapterMetaDataCallback callback)boolean cancel(C config, AdapterMetaDataCallback callback)ProductExecutionStoreServiceexecuteProductsAndStoreResults(SecHubExecutionContext context)AbstractProductExecutionServiceAbstractProductExecutorCanceableProductExecutorboolean cancel(ProductExecutorData data)ScanJobRunnableDataProductExecutorDataSecHubExecutionHistorySecHubExecutionHistoryElementThe scan job executor is central point ofthe scan steep in scan domain.It does the start of the scan itself anddoes also periodically the inspect the schedulerjob status via event busExecutorThreadCancellationThreadJobAdministrationRestControllerJobAdministrationMessageHandlerJobCancelServiceNotificationMessageHandlerProcuctIs used to have eventcommunications between domainssends async REQUEST_JOB_CANCELLATION (C1)sends async CANCELLATION_RUNNING (D1)sends async CANCELLATION_RUNNING (D1)stores resultusescalls cancel servicebecause of C2marks as CANCEL_REQUESTED (C3)callssends async CANCELLATION_RUNNING (D1)sends async REQUEST_JOB_CANCELLATION (C1)receives "PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONE" (E1) ASYNCHRONsends synch REQUEST_SCHEDULER_JOB_STATUS (B1)set SecHub job finally as CANCELEDcreatesusesstores resultsusescallsusesconfigures and usesusescreates + uses (A3)runsinterrupts ExecutorThreadwhen being canceled.This immediately interrupts all product calls hard.runscreatescancelsstartscreates if necessarystarts when necessarycreates contextcreatesmarks as cancel requestedso available in product executorscallsuses information aboutproduct executors and datasends "START_SCAN" (A1) SYNCHRONsends synchron REQUEST_SCHEDULER_JOB_STATUS (B1)and receives job statusrecevies "START_SCAN" (A2) SYNCHRON (returns result)communicationsends "PRODUCT_EXECUTOR_CANCEL_OPERATIONS_DONE" (E1) ASYNCHRON \ No newline at end of file diff --git a/docs/latest/images/diagram_target_architecture.svg b/docs/latest/images/diagram_target_architecture.svg index 107f3308c1..4a2152723e 100644 --- a/docs/latest/images/diagram_target_architecture.svg +++ b/docs/latest/images/diagram_target_architecture.svg @@ -1 +1 @@ -ProductExecutorList<ProductResult> execute()ScanType getScanType()int getVersion()boolean isMultipleConfigurationAllowed()SerecoReportProductExecutorProductExecutorDataNetworkLocationProviderList<URI> getURIs();List<InetAddress> getInetAdresses();NetworkTargetProductServerDataProviderString getIdentifierWhenInternetTarget();String getIdentifierWhenIntranetTarget();String getBaseURLWhenInternetTarget();String getBaseURLWhenIntranetTarget();String getUsernameWhenInternetTarget();String getUsernameWhenIntranetTarget();String getPasswordWhenInternetTarget();String getPasswordWhenIntranetTarget();boolean hasUntrustedCertificateWhenIntranetTarget();boolean hasUntrustedCertificateWhenInternetTarget();NetworkTargetInfoNetworkTargetType getNetworkTargetType()Set<URI> getNetworkTargetURIs()Set<InetAddress> getNetworkTargetIPs()AbstractProductExecutorabstract void customize(ProductExecutorData data);abstract List<ProductResult> executeByAdapter(ProductExecutorData data)NetworkTargetResolverNetworkTarget resolveTarget(URI uri);NetworkTarget resolveTarget(InetAddress inetAdress);The base class for mostly all product executors (except for Sereco).The child classes must implmemnt the `customize` method andconfigure the product executor data object accordingly.It will handle automatically target specific partsfor scan types where it is necessary (WebScan, InfraScan).All other scan types (e.g. CodeScan) do notneed to setup specific product executor data(like NetworkLocationProvider).NetworkTargetgetURI()getInetAdress()NetworkTargetType getType()Represents a network targetto use for a dedicated network typeNetworkTargetTypeNetworkTargetRegistryNetworkTargetInfoFactoryNetworkTargetInfo createInfo()Represents (final) information about whichURIs /IPs are for a dedicated networktarget type (e.g. INTERNET).NetworkTargetProductServerDataSuppportString getIdentifier(NetworkTargetType target)boolean isAbletoScan(NetworkTargetType target)String getBaseURL(NetworkTargetType type)String getUserId(NetworkTargetType type)String getPassword(NetworkTargetType target)Data normally comes fromsechub configurationData normally comes from aninstall setupcreates + customizesusesuses data supportcreate+use (if necessary)create+use (if necessary)internally created + usedusesusescontains1nprovides \ No newline at end of file +ProductExecutorList<ProductResult> execute()ScanType getScanType()int getVersion()boolean isMultipleConfigurationAllowed()SerecoReportProductExecutorProductExecutorDataNetworkLocationProviderList<URI> getURIs();List<InetAddress> getInetAdresses();NetworkTargetProductServerDataProviderString getIdentifierWhenInternetTarget();String getIdentifierWhenIntranetTarget();String getBaseURLWhenInternetTarget();String getBaseURLWhenIntranetTarget();String getUsernameWhenInternetTarget();String getUsernameWhenIntranetTarget();String getPasswordWhenInternetTarget();String getPasswordWhenIntranetTarget();boolean hasUntrustedCertificateWhenIntranetTarget();boolean hasUntrustedCertificateWhenInternetTarget();NetworkTargetInfoNetworkTargetType getNetworkTargetType()Set<URI> getNetworkTargetURIs()Set<InetAddress> getNetworkTargetIPs()AbstractProductExecutorabstract void customize(ProductExecutorData data);abstract List<ProductResult> executeByAdapter(ProductExecutorData data)NetworkTargetResolverNetworkTarget resolveTarget(URI uri);NetworkTarget resolveTarget(InetAddress inetAdress);The base class for mostly all product executors (except for Sereco).The child classes must implmemnt the `customize` method andconfigure the product executor data object accordingly.It will handle automatically target specific partsfor scan types where it is necessary (WebScan, InfraScan).All other scan types (e.g. CodeScan) do notneed to setup specific product executor data(like NetworkLocationProvider).NetworkTargetgetURI()getInetAdress()NetworkTargetType getType()Represents a network targetto use for a dedicated network typeNetworkTargetTypeNetworkTargetRegistryNetworkTargetInfoFactoryNetworkTargetInfo createInfo()Represents (final) information about whichURIs /IPs are for a dedicated networktarget type (e.g. INTERNET).NetworkTargetProductServerDataSuppportString getIdentifier(NetworkTargetType target)boolean isAbletoScan(NetworkTargetType target)String getBaseURL(NetworkTargetType type)String getUserId(NetworkTargetType type)String getPassword(NetworkTargetType target)Data normally comes fromsechub configurationData normally comes from aninstall setupcreates + customizesusesuses data supportcreate+use (if necessary)create+use (if necessary)internally created + usedusesusescontains1nprovides \ No newline at end of file diff --git a/docs/latest/images/event_overview_uc_admin_assigns_user_to_project.svg b/docs/latest/images/event_overview_uc_admin_assigns_user_to_project.svg index bc0cdfe6d2..1645550108 100644 --- a/docs/latest/images/event_overview_uc_admin_assigns_user_to_project.svg +++ b/docs/latest/images/event_overview_uc_admin_assigns_user_to_project.svg @@ -1 +1 @@ -UC_ADMIN_ASSIGNS_USER_TO_PROJECTadministrationauthorizationscanschedule0executedUSER_ADDED_TO_PROJECTUSER_ADDED_TO_PROJECT1REQUEST_USER_ROLE_RECALCULATION2USER_ROLES_CHANGED \ No newline at end of file +UC_ADMIN_ASSIGNS_USER_TO_PROJECTadministrationauthorizationscanschedule0executedUSER_ADDED_TO_PROJECTUSER_ADDED_TO_PROJECT1REQUEST_USER_ROLE_RECALCULATION2USER_ROLES_CHANGED \ No newline at end of file diff --git a/docs/latest/images/event_overview_uc_admin_enables_scheduler_job_processing.svg b/docs/latest/images/event_overview_uc_admin_enables_scheduler_job_processing.svg index eae359746b..104018dda4 100644 --- a/docs/latest/images/event_overview_uc_admin_enables_scheduler_job_processing.svg +++ b/docs/latest/images/event_overview_uc_admin_enables_scheduler_job_processing.svg @@ -1 +1 @@ -UC_ADMIN_ENABLES_SCHEDULER_JOB_PROCESSINGadministrationnotificationschedule0executedREQUEST_SCHEDULER_ENABLE_JOB_PROCESSING1SCHEDULER_JOB_PROCESSING_ENABLEDSCHEDULER_JOB_PROCESSING_ENABLED \ No newline at end of file +UC_ADMIN_ENABLES_SCHEDULER_JOB_PROCESSINGadministrationnotificationschedule0executedREQUEST_SCHEDULER_ENABLE_JOB_PROCESSING1SCHEDULER_JOB_PROCESSING_ENABLEDSCHEDULER_JOB_PROCESSING_ENABLED \ No newline at end of file diff --git a/docs/latest/images/event_overview_uc_admin_unassigns_user_from_project.svg b/docs/latest/images/event_overview_uc_admin_unassigns_user_from_project.svg index ae98eb91be..282852d6a7 100644 --- a/docs/latest/images/event_overview_uc_admin_unassigns_user_from_project.svg +++ b/docs/latest/images/event_overview_uc_admin_unassigns_user_from_project.svg @@ -1 +1 @@ -UC_ADMIN_UNASSIGNS_USER_FROM_PROJECTadministrationauthorizationscanschedule0executedUSER_REMOVED_FROM_PROJECTUSER_REMOVED_FROM_PROJECT1REQUEST_USER_ROLE_RECALCULATION2USER_ROLES_CHANGED \ No newline at end of file +UC_ADMIN_UNASSIGNS_USER_FROM_PROJECTadministrationauthorizationscanschedule0executedUSER_REMOVED_FROM_PROJECTUSER_REMOVED_FROM_PROJECT1REQUEST_USER_ROLE_RECALCULATION2USER_ROLES_CHANGED \ No newline at end of file diff --git a/docs/latest/images/event_overview_uc_admin_updates_auto_cleanup_configuration.svg b/docs/latest/images/event_overview_uc_admin_updates_auto_cleanup_configuration.svg index f1bbea3fc0..2bc500512c 100644 --- a/docs/latest/images/event_overview_uc_admin_updates_auto_cleanup_configuration.svg +++ b/docs/latest/images/event_overview_uc_admin_updates_auto_cleanup_configuration.svg @@ -1 +1 @@ -UC_ADMIN_UPDATES_AUTO_CLEANUP_CONFIGURATIONadministrationscanschedule0executedAUTO_CLEANUP_CONFIGURATION_CHANGEDAUTO_CLEANUP_CONFIGURATION_CHANGEDAUTO_CLEANUP_CONFIGURATION_CHANGED \ No newline at end of file +UC_ADMIN_UPDATES_AUTO_CLEANUP_CONFIGURATIONadministrationscanschedule0executedAUTO_CLEANUP_CONFIGURATION_CHANGEDAUTO_CLEANUP_CONFIGURATION_CHANGEDAUTO_CLEANUP_CONFIGURATION_CHANGED \ No newline at end of file diff --git a/docs/latest/sechub-architecture.html b/docs/latest/sechub-architecture.html index f106efd95a..bd8de64a12 100644 --- a/docs/latest/sechub-architecture.html +++ b/docs/latest/sechub-architecture.html @@ -531,7 +531,7 @@ @@ -5304,13 +5309,17 @@

7.5.44. UC_043-Admin receives notification about
-

7.5.45. UC_044-User marks false positives for finished sechub job

- @@ -8195,7 +8259,7 @@

7.6.9. Admin downloads all

-
$ curl 'https://sechub.example.com/api/admin/scan/download/50a3de31-e207-4ac3-a6da-0f46e478d7ff' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/admin/scan/download/0c5d212b-2caa-496f-b019-7fba0538e004' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -9360,7 +9424,7 @@

7.6.20. Admin shows scan logs for pro
-
[{"sechubJobUUID":"fc559da4-0535-46c7-941f-1a76d09a2ca1","executedBy":"spartakus","started":"2024-08-07T08:05:51.724664496","ended":"2024-08-08T08:05:51.724691357","status":"OK"}]
+
[{"sechubJobUUID":"bc7decbc-3281-4e8e-9a52-f11f3a1f76fc","executedBy":"spartakus","started":"2024-08-22T09:56:37.567632928","ended":"2024-08-23T09:56:37.567651473","status":"OK"}]
@@ -9970,7 +10034,7 @@

7.6.25.1. Code Scan variant
-
{"jobId":"e80bc191-1fab-4e51-9c53-44b956b37b88"}
+
{"jobId":"9d8a0959-0578-417c-a71b-243434efdacb"}
@@ -10149,7 +10213,7 @@
7.6.25.2. Code Sc
-
{"jobId":"278d510e-e7b2-4d07-b593-7fa77b54eef8"}
+
{"jobId":"1bd055ea-443d-4461-9e79-d56c8fbccab6"}
@@ -10308,7 +10372,7 @@
7.6.25.3. Secret scan variant
-
{"jobId":"07c86999-76c1-4a12-90b7-4b97a7632579"}
+
{"jobId":"2af233cb-e717-4426-8209-fa2b9bd7daca"}
@@ -10467,7 +10531,7 @@
7.6.25.4. License scan variant
-
{"jobId":"18b74d14-fd93-4beb-9ed0-623ba27171df"}
+
{"jobId":"cc1c6a6f-86b8-435f-b379-1f76addc21ab"}
@@ -10621,7 +10685,7 @@
7.6.25.5. Infrastructure s
-
{"jobId":"a47a9992-6b75-46db-a77a-5590b115e8e4"}
+
{"jobId":"541dbe04-d641-4b8b-9ac5-8fde01abf66d"}
@@ -10790,7 +10854,7 @@
7.6.25.6. Web scan anonymou
-
{"jobId":"ad2715a7-ed7c-49c5-9b0d-ef7b80f276c1"}
+
{"jobId":"0e3930f8-4911-4e4e-a278-aee540ec162e"}
@@ -10954,7 +11018,7 @@
7.6.25.7. Web sca
-
{"jobId":"f4542da9-59bb-41d2-a120-39a5f14e286a"}
+
{"jobId":"61090ac1-7f2d-423b-aa9d-eb0998ff1dc0"}
@@ -11113,7 +11177,7 @@
7.
-
{"jobId":"361d942a-c955-42ba-baea-41bfccfe08e3"}
+
{"jobId":"6f28ec92-7720-484b-b357-3cb7fddb5952"}
@@ -11287,7 +11351,7 @@
7.6.25.9. Web Scan login
-
{"jobId":"48c03859-a741-4e25-9ade-314a1583e45f"}
+
{"jobId":"98964e58-0c5e-4c44-a3a1-78db898ebf78"}
@@ -11481,7 +11545,7 @@
7.6.25.10. Web Sc
-
{"jobId":"046e0236-dd5f-4b07-8c57-3c45801b6c37"}
+
{"jobId":"5e8b7950-8e53-4d0b-9736-a4423fb46fc7"}
@@ -11645,7 +11709,7 @@
7.6.25.11. Web Scan headers v
-
{"jobId":"dd1b6f6b-7a47-408d-a919-0f06c9b43200"}
+
{"jobId":"a391b64e-a21b-40f0-92ad-c91480338e73"}
@@ -11734,7 +11798,7 @@

7.6.26. User uploads source code

-
$ curl 'https://sechub.example.com/api/project/project1/job/d26d431f-532e-403d-8649-41840afaf02a/sourcecode?checkSum=checkSumValue' -i -X POST \
+
$ curl 'https://sechub.example.com/api/project/project1/job/ab20be15-2b5e-4ec9-b8b2-36b4ad842bf8/sourcecode?checkSum=checkSumValue' -i -X POST \
     -H 'Content-Type: multipart/form-data;charset=UTF-8' \
     -F 'file=PK  
       �<M                       test1.txtPK  ?
@@ -11831,7 +11895,7 @@ 

7.6.27. User approves sechub job

-
$ curl 'https://sechub.example.com/api/project/project1/job/2599f5c1-4bb0-4ca2-9745-49411e356282/approve' -i -X PUT \
+
$ curl 'https://sechub.example.com/api/project/project1/job/e44c859f-66fa-4f41-bdeb-00ea47ad8438/approve' -i -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -11983,7 +12047,7 @@

7.6.28. User checks sechub job state

-
$ curl 'https://sechub.example.com/api/project/project1/job/acd54ae3-6a88-4002-85f0-c7026639380a' -i -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/job/aa96859a-509e-4761-9b1a-0fd448ac9275' -i -X GET \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -11992,7 +12056,7 @@

7.6.28. User checks sechub job state

-
{"jobUUID":"acd54ae3-6a88-4002-85f0-c7026639380a","owner":"CREATOR1","created":"","started":"2024-08-08T07:50:50.192109111","ended":"2024-08-08T08:05:50.192137775","state":"ENDED","result":"OK","trafficLight":"GREEN"}
+
{"jobUUID":"aa96859a-509e-4761-9b1a-0fd448ac9275","owner":"CREATOR1","created":"","started":"2024-08-23T09:41:36.176718254","ended":"2024-08-23T09:56:36.176745655","state":"ENDED","result":"OK","trafficLight":"GREEN"}
@@ -12067,7 +12131,7 @@
7.6.29.1. JSON variant
-
$ curl 'https://sechub.example.com/api/project/project1/report/5e4d6d16-930d-4a32-9277-b178d2e0a033' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/04b496b8-7bdb-4319-9bd5-d6a9ff143003' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/json'
@@ -12139,7 +12203,7 @@
7.6.29.2. HTML variant
-
$ curl 'https://sechub.example.com/api/project/project1/report/d2552d0b-e265-4673-ad90-e43e0f61a610' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/ec741b51-508d-4557-ba7f-8af620c6bb19' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/xhtml+xml'
@@ -12147,9 +12211,9 @@
7.6.29.2. HTML variant
-

7.6.30. User marks false positives for finished sechub job

+

7.6.30. User marks false positives

Definition

@@ -12243,7 +12307,7 @@

7.6.30. User marks f

type

String

-

The type of the json content. Currently only accepted value is 'falsePositiveJobDataList'.

+

The type of the json content. Currently only accepted value is 'falsePositiveDataList' but we also still accept the deprecated type 'falsePositiveJobDataList'.

jobData

@@ -12258,13 +12322,63 @@

7.6.30. User marks f

jobData[].findingId

Number

-

SecHub finding identifier - identifies problem inside the job which shall be markeda as a false positive. ATTENTION: at the moment only code scan false positive handling is supported. Infra and web scan findings will lead to a non accepted error!

+

SecHub finding identifier - identifies problem inside the job which shall be markeda as a false positive.

jobData[].comment

String

A comment describing why this is a false positive

+ +

projectData

+

Array

+

Porject data list containing false positive setup for the project

+ + +

projectData[].id

+

String

+

Identifier which is used to update or remove the respective false positive entry.

+ + +

projectData[].comment

+

String

+

A comment describing why this is a false positive.

+ + +

projectData[].webScan

+

Object

+

Defines a section for false positives which occur during webscans.

+ + +

projectData[].webScan.hostPatterns[]

+

Array

+

Defines a list of host patterns for false positives which occur during webscans. At least one entry must be present. Can be used with wildcards like '.host.com'. Each entry must contain more than just wildcards, '..' or '*' are not allowed.

+ + +

projectData[].webScan.urlPathPatterns[]

+

Array

+

Defines a list of urlPathPatterns for false positives which occur during webscans which make it easier e.g. to ignore query parameters. At least one entry must be present. Can be used with wildcards like '/api/users/'. Each entry must contain more than just wildcards, '//' or '' are not allowed.

+ + +

projectData[].webScan.methods[]

+

Array

+

Defines a list of (HTTP) methods for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all methods.

+ + +

projectData[].webScan.ports[]

+

Array

+

Defines a list of server ports for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all server ports.

+ + +

projectData[].webScan.protocols[]

+

Array

+

Defines a list of web request protocols like 'http', 'https', 'wss' for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all protocols.

+ + +

projectData[].webScan.cweId

+

Number

+

Defines a CWE ID for false positives which occur during webscans. This is mandatory, but can be empty. If it is not specified it matches the findings with no CWE IDs.

+
@@ -12277,7 +12391,7 @@

7.6.30. User marks f
$ curl 'https://sechub.example.com/api/project/project1/false-positives' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
-    -d '{"apiVersion":"1.0","type":"falsePositiveJobDataList","jobData":[{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"an optional comment why this is a false positive..."}]}'
+ -d '{"apiVersion":"1.0","type":"falsePositiveDataList","jobData":[{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"an optional comment why this is a false positive..."}],"projectData":[{"id":"unique-identifier","webScan":{"cweId":564,"ports":["8443","8080"],"protocols":["HTTP","HTTPS"],"urlPathPatterns":["/rest/api/project/*","/other/rest/api/"],"hostPatterns":["sub.host.com","*.other.host.com"],"methods":["GET","POST"]},"comment":"an optional comment for this false positive project entry"}]}'

@@ -12585,6 +12699,56 @@

7.6.32. User fetch

String

A comment from author describing why this was marked as a false positive

+ +

falsePositives[].projectData

+

Object

+

Porject data list containing false positive setup for the project.

+ + +

falsePositives[].projectData.id

+

String

+

Identifier which is used to update or remove the respective false positive entry.

+ + +

falsePositives[].projectData.comment

+

String

+

A comment describing why this is a false positive.

+ + +

falsePositives[].projectData.webScan

+

Object

+

Defines a section for false positives which occur during webscans.

+ + +

falsePositives[].projectData.webScan.hostPatterns[]

+

Array

+

Defines a list of host patterns for false positives which occur during webscans. At least one entry must be present. Can be used with wildcards like '.host.com'. Each entry must contain more than just wildcards, '..' or '*' are not allowed.

+ + +

falsePositives[].projectData.webScan.urlPathPatterns[]

+

Array

+

Defines a list of urlPathPatterns for false positives which occur during webscans which make it easier e.g. to ignore query parameters. At least one entry must be present. Can be used with wildcards like '/api/users/'. Each entry must contain more than just wildcards, '//' or '' are not allowed.

+ + +

falsePositives[].projectData.webScan.methods[]

+

Array

+

Defines a list of (HTTP) methods for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all methods.

+ + +

falsePositives[].projectData.webScan.ports[]

+

Array

+

Defines a list of server ports for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all server ports.

+ + +

falsePositives[].projectData.webScan.protocols[]

+

Array

+

Defines a list of web request protocols like 'http', 'https', 'wss' for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all protocols.

+ + +

falsePositives[].projectData.webScan.cweId

+

Number

+

Defines a CWE ID for false positives which occur during webscans. This is mandatory, but can be empty. If it is not specified it matches the findings with no CWE IDs.

+
@@ -12603,7 +12767,7 @@

7.6.32. User fetch

-
{"falsePositives":[{"jobData":{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"Only used in documentation build not in deployment"},"author":"developer1","metaData":{"scanType":"codeScan","name":"Absolute Path Traversal","severity":"MEDIUM","code":{"start":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"args","sourceCode":"\tpublic static void main(String[] args) throws Exception {"},"end":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"File","sourceCode":"\t\tFile documentsGenFolder = new File(path);"}},"cweId":36},"created":"2020-06-12 11:53:15"}]}
+
{"falsePositives":[{"jobData":{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"Only used in documentation build not in deployment"},"author":"developer1","metaData":{"scanType":"codeScan","name":"Absolute Path Traversal","severity":"MEDIUM","code":{"start":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"args","sourceCode":"\tpublic static void main(String[] args) throws Exception {"},"end":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"File","sourceCode":"\t\tFile documentsGenFolder = new File(path);"}},"cweId":36},"projectData":{"id":"unique-identifier","webScan":{"cweId":564,"ports":["8443","8080"],"protocols":["HTTP","HTTPS"],"urlPathPatterns":["/rest/api/project/*","/other/rest/api/"],"hostPatterns":["sub.host.com","*.other.host.com"],"methods":["GET","POST"]},"comment":"an optional comment for this false positive project entry"},"created":"2020-06-12 11:53:15"}]}

@@ -12697,7 +12861,7 @@

7.6.33. User uploads binaries

-
$ curl 'https://sechub.example.com/api/project/project1/job/897847f1-3e25-44cc-a4cf-67508dbd295a/binaries' -i -X POST \
+
$ curl 'https://sechub.example.com/api/project/project1/job/4c239794-a2fe-4c06-93c1-aa81672f8749/binaries' -i -X POST \
     -H 'Content-Type: multipart/form-data;charset=UTF-8' \
     -H 'x-file-size: 10240' \
     -F 'file=test1.txt                                                                                           0000664 0001750 0001750 00000000000 13353454574 012170  0                                                                                                    ustar   albert                          albert                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ' \
@@ -12778,14 +12942,106 @@ 

7.6.34. User downloads job rep

-
$ curl 'https://sechub.example.com/api/project/project1/report/spdx/28097c41-5d4d-4355-a509-ce22bdb69537' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/spdx/28d9d710-6053-46a3-ac91-8b7fc4ede1e0' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/json'
-

7.6.35. User self registration

+

7.6.35. User unmarks existing false positive project data definitons

+ +
+

Definition

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + +
Table 85. General request information
Value

Path

/api/project/{projectId}/false-positive/project-data/{id}

Method

DELETE

Status code

204 NO_CONTENT

+
+

Path parameters

+
+ + ++++ + + + + + + + + + + + + + + + + +
Table 86. https://localhost:8081/api/project/{projectId}/false-positive/project-data/{id}
ParameterDescription

projectId

The project id

id

Identifier which is used to remove the respective false positive entry.

+
+

Request headers

+
+ ++++ + + + + + + +
NameDescription
+
+

Example

+
+
+

Curl request

+
+
+
+
$ curl 'https://sechub.example.com/api/project/project1/false-positive/project-data/unique-identifier' -i -u 'user:secret' -X DELETE
+
+
+
+

Response body
+(empty)

+
+
+
+

7.6.36. User self registration

REST API for usecase UC_001-User self registration

@@ -12793,7 +13049,7 @@

7.6.35. User self registration

Definition

- +@@ -12872,7 +13128,7 @@

7.6.35. User self registration

-

7.6.36. Admin lists open user signups

+

7.6.37. Admin lists open user signups

@@ -12880,7 +13136,7 @@

7.6.36. Admin lists open user signups

Definition

Table 85. General request informationTable 87. General request information
- +@@ -12976,7 +13232,7 @@

7.6.36. Admin lists open user signups

-

7.6.37. Admin applies self registration

+

7.6.38. Admin applies self registration

@@ -12984,7 +13240,7 @@

7.6.37. Admin applies self registration

Definition

Table 86. General request informationTable 88. General request information
- +@@ -13014,7 +13270,7 @@

7.6.37. Admin applies self registration

Path parameters

Table 87. General request informationTable 89. General request information
- +@@ -13064,7 +13320,7 @@

7.6.37. Admin applies self registration
-

7.6.38. Admin deletes user signup

+

7.6.39. Admin deletes user signup

REST API for usecase UC_019-Admin deletes user signup

@@ -13072,7 +13328,7 @@

7.6.38. Admin deletes user signup

Definition

Table 88. https://localhost:8081/api/admin/signup/accept/{userId}Table 90. https://localhost:8081/api/admin/signup/accept/{userId}
- +@@ -13102,7 +13358,7 @@

7.6.38. Admin deletes user signup

Path parameters

Table 89. General request informationTable 91. General request information
- +@@ -13152,7 +13408,7 @@

7.6.38. Admin deletes user signup

-

7.6.39. User requests new API token

+

7.6.40. User requests new API token

@@ -13160,7 +13416,7 @@

7.6.39. User requests new API token

Definition

Table 90. https://localhost:8081/api/admin/signup/{userId}Table 92. https://localhost:8081/api/admin/signup/{userId}
- +@@ -13190,7 +13446,7 @@

7.6.39. User requests new API token

Path parameters

Table 91. General request informationTable 93. General request information
- +@@ -13226,7 +13482,7 @@

7.6.39. User requests new API token

-

7.6.40. Admin lists all running jobs

+

7.6.41. Admin lists all running jobs

@@ -13234,7 +13490,7 @@

7.6.40. Admin lists all running jobs

Definition

Table 92. https://localhost:8081/api/anonymous/refresh/apitoken/{emailAddress}Table 94. https://localhost:8081/api/anonymous/refresh/apitoken/{emailAddress}
- +@@ -13336,12 +13592,12 @@

7.6.40. Admin lists all running jobs

-
[{"jobUUID":"1761a2a9-37a9-48e1-98e5-63e3c2785c67","projectId":"project-name","owner":"owner-userid","status":"RUNNING","since":"2024-08-08T08:05:55.044912463"}]
+
[{"jobUUID":"c739e0cc-c0fc-40dc-bf9d-410b963cb727","projectId":"project-name","owner":"owner-userid","status":"RUNNING","since":"2024-08-23T09:56:40.748649884"}]
-

7.6.41. Admin cancels a job

+

7.6.42. Admin cancels a job

REST API for usecase UC_034-Admin cancels a job

@@ -13349,7 +13605,7 @@

7.6.41. Admin cancels a job

Definition

Table 93. General request informationTable 95. General request information
- +@@ -13379,7 +13635,7 @@

7.6.41. Admin cancels a job

Path parameters

Table 94. General request informationTable 96. General request information
- +@@ -13420,7 +13676,7 @@

7.6.41. Admin cancels a job

-
$ curl 'https://sechub.example.com/api/admin/jobs/cancel/08eaf3b6-4d6e-4ad9-a7ac-7d88b4884d13' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/cancel/0449764d-8f50-4674-9296-feea9f6c6e6e' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -13430,7 +13686,7 @@

7.6.41. Admin cancels a job

-

7.6.42. Admin restarts a job

+

7.6.43. Admin restarts a job

REST API for usecase UC_041-Admin restarts a job

@@ -13438,7 +13694,7 @@

7.6.42. Admin restarts a job

Definition

Table 95. https://localhost:8081/api/admin/jobs/cancel/{jobUUID}Table 97. https://localhost:8081/api/admin/jobs/cancel/{jobUUID}
- +@@ -13468,7 +13724,7 @@

7.6.42. Admin restarts a job

Path parameters

Table 96. General request informationTable 98. General request information
- +@@ -13509,7 +13765,7 @@

7.6.42. Admin restarts a job

-
$ curl 'https://sechub.example.com/api/admin/jobs/restart/98470906-23a7-4233-8228-4e213cb5b173' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/restart/96a0df4a-d99f-4ec2-aebf-ca7686ee893f' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -13519,7 +13775,7 @@

7.6.42. Admin restarts a job

-

7.6.43. Admin restarts a job (hard)

+

7.6.44. Admin restarts a job (hard)

@@ -13527,7 +13783,7 @@

7.6.43. Admin restarts a job (hard)

Definition

Table 97. https://localhost:8081/api/admin/jobs/restart/{jobUUID}Table 99. https://localhost:8081/api/admin/jobs/restart/{jobUUID}
- +@@ -13557,7 +13813,7 @@

7.6.43. Admin restarts a job (hard)

Path parameters

Table 98. General request informationTable 100. General request information
- +@@ -13598,7 +13854,7 @@

7.6.43. Admin restarts a job (hard)

-
$ curl 'https://sechub.example.com/api/admin/jobs/restart-hard/c3a07e23-27f4-4a02-9313-c5e8ee6aa8f7' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/restart-hard/a836178f-8a32-428d-887d-1967851dfa1a' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -13608,7 +13864,7 @@

7.6.43. Admin restarts a job (hard)

-

7.6.44. User defines mock data configuration for project

+

7.6.45. User defines mock data configuration for project

@@ -13616,7 +13872,7 @@

7.6.44. User defines m

Definition

Table 99. https://localhost:8081/api/admin/jobs/restart-hard/{jobUUID}Table 101. https://localhost:8081/api/admin/jobs/restart-hard/{jobUUID}
- +@@ -13677,7 +13933,7 @@

7.6.44. User defines m
-

7.6.45. User retrieves mock data configuration for project

+

7.6.46. User retrieves mock data configuration for project

@@ -13685,7 +13941,7 @@

7.6.45. User retriev

Definition

Table 100. General request informationTable 102. General request information
- +@@ -13749,7 +14005,7 @@

7.6.45. User retriev
-

7.6.46. Admin updates mapping configuration

+

7.6.47. Admin updates mapping configuration

@@ -13757,7 +14013,7 @@

7.6.46. Admin updates mapping confi

Definition

Table 101. General request informationTable 103. General request information
- +@@ -13787,7 +14043,7 @@

7.6.46. Admin updates mapping confi

Path parameters

Table 102. General request informationTable 104. General request information
- +@@ -13873,7 +14129,7 @@

7.6.46. Admin updates mapping confi
-

7.6.47. Admin fetches mapping configuration

+

7.6.48. Admin fetches mapping configuration

@@ -13881,7 +14137,7 @@

7.6.47. Admin fetches mapping confi

Definition

Table 103. https://localhost:8081/api/admin/config/mapping/{mappingId}Table 105. https://localhost:8081/api/admin/config/mapping/{mappingId}
- +@@ -13911,7 +14167,7 @@

7.6.47. Admin fetches mapping confi

Path parameters

Table 104. General request informationTable 106. General request information
- +@@ -14000,7 +14256,7 @@

7.6.47. Admin fetches mapping confi
-

7.6.48. Admin creates an executor configuration

+

7.6.49. Admin creates an executor configuration

@@ -14008,7 +14264,7 @@

7.6.48. Admin creates an execut

Definition

Table 105. https://localhost:8081/api/admin/config/mapping/{mappingId}Table 107. https://localhost:8081/api/admin/config/mapping/{mappingId}
- +@@ -14131,12 +14387,12 @@

7.6.48. Admin creates an execut
-
19a513e8-f664-43f3-ad0e-ec881c7762f7
+
885d3e89-2293-416d-a050-0f9748a4f27e
-

7.6.49. Admin deletes executor configuration

+

7.6.50. Admin deletes executor configuration

@@ -14144,7 +14400,7 @@

7.6.49. Admin deletes executor con

Definition

Table 106. General request informationTable 108. General request information
- +@@ -14174,7 +14430,7 @@

7.6.49. Admin deletes executor con

Path parameters

Table 107. General request informationTable 109. General request information
- +@@ -14215,7 +14471,7 @@

7.6.49. Admin deletes executor con
-
$ curl 'https://sechub.example.com/api/admin/config/executor/22fb2f08-7b58-4d57-acbb-00f12619c6e1' -i -u 'user:secret' -X DELETE \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/1d01ca8b-14f8-40f2-b55a-8899942e3cd4' -i -u 'user:secret' -X DELETE \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -14225,7 +14481,7 @@

7.6.49. Admin deletes executor con
-

7.6.50. Admin fetches executor configuration list

+

7.6.51. Admin fetches executor configuration list

@@ -14233,7 +14489,7 @@

7.6.50. Admin fetches executo

Definition

Table 108. https://localhost:8081/api/admin/config/executor/{uuid}Table 110. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -14330,12 +14586,12 @@

7.6.50. Admin fetches executo
-
{"executorConfigurations":[{"uuid":"7d298d34-1148-4803-975d-226862654d0b","name":"example configuration","enabled":true}],"type":"executorConfigurationList"}
+
{"executorConfigurations":[{"uuid":"271e5de2-6cb6-4b4a-a3b0-172f1b964f04","name":"example configuration","enabled":true}],"type":"executorConfigurationList"}
-

7.6.51. Admin fetches executor configuration

+

7.6.52. Admin fetches executor configuration

@@ -14343,7 +14599,7 @@

7.6.51. Admin fetches executor con

Definition

Table 109. General request informationTable 111. General request information
- +@@ -14373,7 +14629,7 @@

7.6.51. Admin fetches executor con

Path parameters

Table 110. General request informationTable 112. General request information
- +@@ -14483,7 +14739,7 @@

7.6.51. Admin fetches executor con
-
$ curl 'https://sechub.example.com/api/admin/config/executor/b60c002d-6882-41b7-9378-a1279f10fca9' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/7f4f4bd0-dd02-4340-a2fd-854c158720cf' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -14492,12 +14748,12 @@

7.6.51. Admin fetches executor con
-
{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value"}]},"executorVersion":1,"enabled":false,"uuid":"b60c002d-6882-41b7-9378-a1279f10fca9"}
+
{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value"}]},"executorVersion":1,"enabled":false,"uuid":"7f4f4bd0-dd02-4340-a2fd-854c158720cf"}
-

7.6.52. Admin updates executor configuration setup

+

7.6.53. Admin updates executor configuration setup

@@ -14505,7 +14761,7 @@

7.6.52. Admin updates execut

Definition

Table 111. https://localhost:8081/api/admin/config/executor/{uuid}Table 113. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -14535,7 +14791,7 @@

7.6.52. Admin updates execut

Path parameters

Table 112. General request informationTable 114. General request information
- +@@ -14640,7 +14896,7 @@

7.6.52. Admin updates execut
-
$ curl 'https://sechub.example.com/api/admin/config/executor/70e7df3d-e2c9-4416-b64e-4d93d5500933' -i -u 'user:secret' -X PUT \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/76b10e2d-c1a7-47ae-a611-32ce720ece9e' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -d '{"name":"New name","productIdentifier":"PDS_CODESCAN","executorVersion":1,"enabled":false,"setup":{"baseURL":"https://productNew.example.com","credentials":{"user":"env:EXAMPLE_NEW_USENAME","password":"env:EXAMPLE_NEW_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]}}'
@@ -14651,7 +14907,7 @@

7.6.52. Admin updates execut

-

7.6.53. Admin creates an execution profile

+

7.6.54. Admin creates an execution profile

@@ -14659,7 +14915,7 @@

7.6.53. Admin creates an execution p

Definition

Table 113. https://localhost:8081/api/admin/config/executor/{uuid}Table 115. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -14689,7 +14945,7 @@

7.6.53. Admin creates an execution p

Path parameters

Table 114. General request informationTable 116. General request information
- +@@ -14780,7 +15036,7 @@

7.6.53. Admin creates an execution p
-

7.6.54. Admin deletes execution profile

+

7.6.55. Admin deletes execution profile

@@ -14788,7 +15044,7 @@

7.6.54. Admin deletes execution profile

Definition

Table 115. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 117. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -14818,7 +15074,7 @@

7.6.54. Admin deletes execution profile

Path parameters

Table 116. General request informationTable 118. General request information
- +@@ -14869,7 +15125,7 @@

7.6.54. Admin deletes execution profile
-

7.6.55. Admin updates execution profile

+

7.6.56. Admin updates execution profile

@@ -14877,7 +15133,7 @@

7.6.55. Admin updates execution profile

Definition

Table 117. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 119. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -14907,7 +15163,7 @@

7.6.55. Admin updates execution profile

Path parameters

Table 118. General request informationTable 120. General request information
- +@@ -14984,7 +15240,7 @@

7.6.55. Admin updates execution profile
$ curl 'https://sechub.example.com/api/admin/config/execution/profile/existing-profile-1' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
-    -d '{"description":"changed description","configurations":[{"uuid":"44742c74-0b9b-46c2-afa7-1c0e8e7f3291","executorVersion":0,"enabled":false,"setup":{"credentials":{},"jobParameters":[]}}],"enabled":true}'
+ -d '{"description":"changed description","configurations":[{"uuid":"ffc9e7f5-b294-4078-8f8f-12b9ad5cd45b","executorVersion":0,"enabled":false,"setup":{"credentials":{},"jobParameters":[]}}],"enabled":true}'
@@ -14993,7 +15249,7 @@

7.6.55. Admin updates execution profile

-

7.6.56. Admin fetches execution profile

+

7.6.57. Admin fetches execution profile

@@ -15001,7 +15257,7 @@

7.6.56. Admin fetches execution profile

Definition

Table 119. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 121. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -15031,7 +15287,7 @@

7.6.56. Admin fetches execution profile

Path parameters

Table 120. General request informationTable 122. General request information
- +@@ -15140,12 +15396,12 @@

7.6.56. Admin fetches execution profile
-
{"description":"a description","enabled":true,"configurations":[{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]},"executorVersion":1,"enabled":false,"uuid":"ce989c37-b285-4975-a802-3930530d627b"}],"projectIds":["project-1","project-2"]}
+
{"description":"a description","enabled":true,"configurations":[{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]},"executorVersion":1,"enabled":false,"uuid":"ba0270e0-da2a-4a4c-bdb6-0354f3e8af8c"}],"projectIds":["project-1","project-2"]}
-

7.6.57. Admin fetches execution profile list

+

7.6.58. Admin fetches execution profile list

@@ -15153,7 +15409,7 @@

7.6.57. Admin fetches execution pr

Definition

Table 121. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 123. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -15255,7 +15511,7 @@

7.6.57. Admin fetches execution pr
-

7.6.58. Admin assigns execution profile to project

+

7.6.59. Admin assigns execution profile to project

@@ -15263,7 +15519,7 @@

7.6.58. Admin assigns execut

Definition

Table 122. General request informationTable 124. General request information
- +@@ -15293,7 +15549,7 @@

7.6.58. Admin assigns execut

Path parameters

Table 123. General request informationTable 125. General request information
- +@@ -15348,7 +15604,7 @@

7.6.58. Admin assigns execut
-

7.6.59. Admin unassigns execution profile from project

+

7.6.60. Admin unassigns execution profile from project

@@ -15356,7 +15612,7 @@

7.6.59. Admin unassigns

Definition

Table 124. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}Table 126. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}
- +@@ -15386,7 +15642,7 @@

7.6.59. Admin unassigns

Path parameters

Table 125. General request informationTable 127. General request information
- +@@ -15441,7 +15697,7 @@

7.6.59. Admin unassigns
-

7.6.60. Admin fetches auto cleanup configuration

+

7.6.61. Admin fetches auto cleanup configuration

@@ -15449,7 +15705,7 @@

7.6.60. Admin fetches auto cle

Definition

Table 126. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}Table 128. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}
- +@@ -15512,7 +15768,7 @@

7.6.60. Admin fetches auto cle
-

7.6.61. Admin updates auto cleanup configuration

+

7.6.62. Admin updates auto cleanup configuration

@@ -15520,7 +15776,7 @@

7.6.61. Admin updates auto cle

Definition

Table 127. General request informationTable 129. General request information
- +@@ -15580,7 +15836,7 @@

7.6.61. Admin updates auto cle
-

7.6.62. Admin starts encryption rotation

+

7.6.63. Admin starts encryption rotation

@@ -15588,7 +15844,7 @@

7.6.62. Admin starts encryption rotati

Definition

Table 128. General request informationTable 130. General request information
- +@@ -15652,7 +15908,7 @@

7.6.62. Admin starts encryption rotati
-

7.6.63. Admin fetches encryption status

+

7.6.64. Admin fetches encryption status

@@ -15660,7 +15916,7 @@

7.6.63. Admin fetches encryption status

Definition

Table 129. General request informationTable 131. General request information
- +@@ -15792,7 +16048,7 @@

7.6.63. Admin fetches encryption status
-

7.6.64. Admin disables job processing in scheduler

+

7.6.65. Admin disables job processing in scheduler

@@ -15800,7 +16056,7 @@

7.6.64. Admin disables job p

Definition

Table 130. General request informationTable 132. General request information
- +@@ -15859,7 +16115,7 @@

7.6.64. Admin disables job p
-

7.6.65. Admin enables scheduler job processing

+

7.6.66. Admin enables scheduler job processing

@@ -15867,7 +16123,7 @@

7.6.65. Admin enables scheduler

Definition

Table 131. General request informationTable 133. General request information
- +@@ -15926,7 +16182,7 @@

7.6.65. Admin enables scheduler
-

7.6.66. Admin get scheduler status

+

7.6.67. Admin get scheduler status

@@ -15934,7 +16190,7 @@

7.6.66. Admin get scheduler status

Definition

Table 132. General request informationTable 134. General request information
- +@@ -15993,7 +16249,7 @@

7.6.66. Admin get scheduler status

-

7.6.67. Admin lists status information

+

7.6.68. Admin lists status information

@@ -16001,7 +16257,7 @@

7.6.67. Admin lists status informationDefinition

Table 133. General request informationTable 135. General request information
- +@@ -16093,7 +16349,7 @@

7.6.67. Admin lists status information
-

7.6.68. Admin fetches server runtime data

+

7.6.69. Admin fetches server runtime data

@@ -16101,7 +16357,7 @@

7.6.68. Admin fetches server runtime

Definition

Table 134. General request informationTable 136. General request information
- +@@ -16173,7 +16429,7 @@

7.6.68. Admin fetches server runtime
-

7.6.69. User lists jobs for project

+

7.6.70. User lists jobs for project

@@ -16181,7 +16437,7 @@

7.6.69. User lists jobs for project

Definition

Table 135. General request informationTable 137. General request information
- +@@ -16211,7 +16467,7 @@

7.6.69. User lists jobs for project

Path parameters

Table 136. General request informationTable 138. General request information
- +@@ -16335,7 +16591,7 @@

7.6.69. User lists jobs for project

-
{"page":0,"totalPages":1,"content":[{"jobUUID":"048f9167-5b7a-41fb-a235-8e3a7e996efa","executedBy":"User1","created":"2024-08-08T07:48:50.319019742","started":"2024-08-08T07:50:50.319048296","ended":"2024-08-08T08:05:50.319059717","executionState":"ENDED","trafficLight":"GREEN","executionResult":"OK","metaData":{"labels":{"stage":"test"}}}]}
+
{"page":0,"totalPages":1,"content":[{"jobUUID":"70572d6d-79be-4cbc-887a-a01a3f67169d","executedBy":"User1","created":"2024-08-23T09:39:36.296296402","started":"2024-08-23T09:41:36.296322792","ended":"2024-08-23T09:56:36.296333331","executionState":"ENDED","trafficLight":"GREEN","executionResult":"OK","metaData":{"labels":{"stage":"test"}}}]}
@@ -17842,7 +18098,7 @@

8.2.3. General configuration

The next text blocks describe the keys available on SecHub:

Table 137. https://localhost:8081/api/project/{projectId}/jobsTable 139. https://localhost:8081/api/project/{projectId}/jobs
- +@@ -17870,7 +18126,7 @@

8.2.3. General configuration

Table 138. Scope 'administration'Table 140. Scope 'administration'
- +@@ -17892,7 +18148,7 @@

8.2.3. General configuration

Table 139. Scope 'anonymous'Table 141. Scope 'anonymous'
- +@@ -17924,7 +18180,7 @@

8.2.3. General configuration

Table 140. Scope 'checkmarx'Table 142. Scope 'checkmarx'
- +@@ -17956,7 +18212,7 @@

8.2.3. General configuration

Table 141. Scope 'initial'Table 143. Scope 'initial'
- +@@ -17978,7 +18234,7 @@

8.2.3. General configuration

Table 142. Scope 'migration'Table 144. Scope 'migration'
- +@@ -18000,7 +18256,7 @@

8.2.3. General configuration

Table 143. Scope 'mock'Table 145. Scope 'mock'
- +@@ -18077,7 +18333,7 @@

8.2.3. General configuration

Table 144. Scope 'nessus'Table 146. Scope 'nessus'
- +@@ -18149,7 +18405,7 @@

8.2.3. General configuration

Table 145. Scope 'netsparker'Table 147. Scope 'netsparker'
- +@@ -18171,7 +18427,7 @@

8.2.3. General configuration

Table 146. Scope 'new'Table 148. Scope 'new'
- +@@ -18203,7 +18459,7 @@

8.2.3. General configuration

Table 147. Scope 'notification'Table 149. Scope 'notification'
- +@@ -18260,7 +18516,7 @@

8.2.3. General configuration

Table 148. Scope 'p'Table 150. Scope 'p'
- +@@ -18302,7 +18558,7 @@

8.2.3. General configuration

Table 149. Scope 's'Table 151. Scope 's'
- +@@ -18339,7 +18595,7 @@

8.2.3. General configuration

Table 150. Scope 'scan'Table 152. Scope 'scan'
- +@@ -18401,7 +18657,7 @@

8.2.3. General configuration

Table 151. Scope 'scheduler'Table 153. Scope 'scheduler'
- +@@ -18468,7 +18724,7 @@

8.2.3. General configuration

Table 152. Scope 'sec'Table 154. Scope 'sec'
- +@@ -18490,7 +18746,7 @@

8.2.3. General configuration

Table 153. Scope 'security'Table 155. Scope 'security'
- +@@ -18512,7 +18768,7 @@

8.2.3. General configuration

Table 154. Scope 'server'Table 156. Scope 'server'
- +@@ -18599,7 +18855,7 @@

8.2.3. General configuration

Table 155. Scope 'storage'Table 157. Scope 'storage'
- +@@ -18631,7 +18887,7 @@

8.2.3. General configuration

Table 156. Scope 'system'Table 158. Scope 'system'
- +@@ -18663,7 +18919,7 @@

8.2.3. General configuration

8.2.4. Scheduling definitions

Table 157. Scope 'target'Table 159. Scope 'target'
- +@@ -18685,7 +18941,7 @@

8.2.4. Scheduling definitions

- +@@ -18707,7 +18963,7 @@

8.2.4. Scheduling definitions

Table 159. Scope 'scan'Table 161. Scope 'scan'
- +@@ -18742,7 +18998,7 @@

8.2.4. Scheduling definitions

8.2.5. Configuration properties for mocked adapters

Table 160. Scope 'schedule'Table 162. Scope 'schedule'
- +@@ -18764,7 +19020,7 @@

8.2.5. Configuration properties for mocked adapters

Table 161. Scope 'abstract'Table 163. Scope 'abstract'
- +@@ -20954,8 +21210,9 @@
9.7.1.2. Different kinds of
9.7.1.2.1. API centric
-

Define false positive handling in JSON by referencing a former SecHub job UUID and the -corresponding finding entry (by id) and post it to REST API.

+

Define false positive be done sending false positive information via JSON either +by referencing a former SecHub job UUID and the corresponding finding entry (by id) or +by specifying a project data section where specific patterns that match false positive findings are declared and post it to REST API.

JSON

@@ -20964,7 +21221,7 @@
9.7.1.2.1. API centr
{
   "apiVersion": "1.0", (1)
-  "type": "falsePositiveJobDataList", (2)
+  "type": "falsePositiveDataList", (2)
   "jobData": [
     {
       "jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd", (3)
@@ -20975,6 +21232,20 @@ 
9.7.1.2.1. API centr "jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd", "findingId": 15 } + ], + "projectData": [ (6) + { + "id": "unique-id", (7) + "comment": "It was verified that there is no SQL-injection vulnerability at this location", + "webScan": { (8) + "cweId": 89, (9) + "hostPatterns": [ "127.0.*.1", "api.example.com", "dev.*.example.com"], (10) + "urlPathPatterns": [ "/rest/products/search*", "/rest/users/profile" ], (11) + "protocols": [ "HTTPS", "WSS" ], (12) + "methods": [ "GET", "DELETE" ], (13) + "ports": [ "8080", "443" ] (14) + } + } ] }
@@ -21001,8 +21272,80 @@
9.7.1.2.1. API centr
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 162. Scope 'mocked'Table 164. Scope 'mocked'
5 comment (optional) are only to define why this is a false positive.
6projectData (optional) that can be used to mark more than a single finding as false positive. +Currently only available for web scans. This is not necessarily bound to a SecHub report, +but it might be easier to create this type of false positive configuration with a SecHub report after a scan.
7id that identifies this entry. If the same id is used again, +the existing false positive entry will be overwritten. The id is also mandatory to unmark this entry.
8webScan (optional) section can be used to define false positive patterns for web scans to provide more possibilities to the user.
9cweId is used to mark a certain type of finding as false positive. +When handling web scan project data this will be treated as a mandatory field, +but it can be omitted inside this configuration an will then match findings that do not have any cweId.
10hostPatterns are used to specify your hosts this entry shall be used for. This is a mandatory field which needs at least one entry. +Asterisks can be used as wildcards e.g. if you have different environments like '*.example.com', would match anything ending with '.example.com'.
11urlPathPatterns are also mandatory and there must be at least one entry. +Asterisks can be used here as wildcards as well. This can be useful to ignore random input of the scanner, +e.g. inside query parameters or REST API path variables.
12protocols (optional) can be used to further restrict the false positive matching, to specific communication protocols, like HTTPS, WSS, etc. +Like any other optional field, if this is missing it is simply ignored.
13methods (optional) can be used to further restrict the false positive matching, to specific request methods protocols, like GET, POST, etc. +Like any other optional field, if this is missing it is simply ignored.
14ports (optional) can be used to further restrict the false positive matching, to specific ports protocols. +Like any other optional field, if this is missing it is simply ignored.
+
+

There are some important information on the asterisk wildcard approach, regarding web scans:

+
+
+
    +
  1. +

    To be a false positive only one entry of each of the lists above must match the finding.

    +
  2. +
  3. +

    Specifying wildcards only inside hostPatterns or urlPathPatterns is not allowed.

    +
  4. +
  5. +

    Wildcards are only allowed inside mandatory parts, like hostPatterns or urlPathPatterns.

    +
  6. +
  7. +

    Wildcards tell the false positive handling to match anything until the next NOT wildcard character (asterisk).

    +
  8. +
  9. +

    Multiple wildcards can be used in one string.

    +
  10. +
  11. +

    No wildcards at the beginning or the end means the beginning or the end of the given part must match exactly otherwise it will not be matched as a false positive.

    +
  12. +
+
@@ -21011,13 +21354,21 @@
9.7.1.2.1. API centr
@@ -22390,7 +22741,7 @@

13. Glossary

diff --git a/docs/latest/sechub-client.html b/docs/latest/sechub-client.html index 365533918d..653c31f2a4 100644 --- a/docs/latest/sechub-client.html +++ b/docs/latest/sechub-client.html @@ -531,7 +531,7 @@
-

This is a very easy, generic approach - and also future-proof: The only dependency is to the job, +

The jobData approach is very easy, generic - and also future-proof: The only dependency is to the job, UUID, for which the report must still exist while the definition is done. Every false-positive in any kind of scan can be handled like that.

The REST controller logic does read the job result data and creates internally false positive -meta data. If we delete later the SecHub job it cannot destroy our false positive setup in SecHub.

+meta data. If we delete the SecHub job later it cannot destroy our false positive setup in SecHub.

+
+
+

The projectData approach is more powerful for the user. +Since it is more powerful with the wildcard approach it requires more intial setup from the user.

+
+
+

There are no dependencies because all information necessary to identify certain findings are specified via REST. +Each entry can be overridden or removed by the given id.

-

Documentation version: Client 1.6.1 modified (commit 1f05e69) - Build date: 20240808080534

+

Documentation version: Client 1.6.1 modified (commit 1a88b65) - Build date: 20240823095620


@@ -1372,7 +1372,7 @@
2.4.3.10. markFalsePositives
{
   "apiVersion": "1.0", (1)
-  "type": "falsePositiveJobDataList", (2)
+  "type": "falsePositiveDataList", (2)
   "jobData": [
     {
       "jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd", (3)
@@ -1383,6 +1383,20 @@ 
2.4.3.10. markFalsePositives
"jobUUID": "6cfa2ccf-da13-4dee-b529-0225ed9661bd", "findingId": 15 } + ], + "projectData": [ (6) + { + "id": "unique-id", (7) + "comment": "It was verified that there is no SQL-injection vulnerability at this location", + "webScan": { (8) + "cweId": 89, (9) + "hostPatterns": [ "127.0.*.1", "api.example.com", "dev.*.example.com"], (10) + "urlPathPatterns": [ "/rest/products/search*", "/rest/users/profile" ], (11) + "protocols": [ "HTTPS", "WSS" ], (12) + "methods": [ "GET", "DELETE" ], (13) + "ports": [ "8080", "443" ] (14) + } + } ] }
@@ -4262,7 +4276,7 @@
3.1.2.1. Example cod
diff --git a/docs/latest/sechub-developer-quickstart-guide.html b/docs/latest/sechub-developer-quickstart-guide.html index 39962fea61..84b50d79b4 100644 --- a/docs/latest/sechub-developer-quickstart-guide.html +++ b/docs/latest/sechub-developer-quickstart-guide.html @@ -531,7 +531,7 @@ @@ -2153,7 +2153,7 @@
5.2.2.3. Run a SecHub + PDS integra diff --git a/docs/latest/sechub-getting-started.html b/docs/latest/sechub-getting-started.html index 0349fe9790..f4d50c7052 100644 --- a/docs/latest/sechub-getting-started.html +++ b/docs/latest/sechub-getting-started.html @@ -531,7 +531,7 @@ @@ -1045,7 +1045,7 @@

1.2.7. Install SecHub’s diff --git a/docs/latest/sechub-operations.html b/docs/latest/sechub-operations.html index b52bab919e..9fb9a788aa 100644 --- a/docs/latest/sechub-operations.html +++ b/docs/latest/sechub-operations.html @@ -531,7 +531,7 @@ @@ -5583,7 +5588,7 @@
2.2.25.1. Code Scan variant
-
{"jobId":"e80bc191-1fab-4e51-9c53-44b956b37b88"}
+
{"jobId":"9d8a0959-0578-417c-a71b-243434efdacb"}
@@ -5762,7 +5767,7 @@
2.2.25.2. Code Sc
-
{"jobId":"278d510e-e7b2-4d07-b593-7fa77b54eef8"}
+
{"jobId":"1bd055ea-443d-4461-9e79-d56c8fbccab6"}
@@ -5921,7 +5926,7 @@
2.2.25.3. Secret scan variant
-
{"jobId":"07c86999-76c1-4a12-90b7-4b97a7632579"}
+
{"jobId":"2af233cb-e717-4426-8209-fa2b9bd7daca"}
@@ -6080,7 +6085,7 @@
2.2.25.4. License scan variant
-
{"jobId":"18b74d14-fd93-4beb-9ed0-623ba27171df"}
+
{"jobId":"cc1c6a6f-86b8-435f-b379-1f76addc21ab"}
@@ -6234,7 +6239,7 @@
2.2.25.5. Infrastructure s
-
{"jobId":"a47a9992-6b75-46db-a77a-5590b115e8e4"}
+
{"jobId":"541dbe04-d641-4b8b-9ac5-8fde01abf66d"}
@@ -6403,7 +6408,7 @@
2.2.25.6. Web scan anonymou
-
{"jobId":"ad2715a7-ed7c-49c5-9b0d-ef7b80f276c1"}
+
{"jobId":"0e3930f8-4911-4e4e-a278-aee540ec162e"}
@@ -6567,7 +6572,7 @@
2.2.25.7. Web sca
-
{"jobId":"f4542da9-59bb-41d2-a120-39a5f14e286a"}
+
{"jobId":"61090ac1-7f2d-423b-aa9d-eb0998ff1dc0"}
@@ -6726,7 +6731,7 @@
2.
-
{"jobId":"361d942a-c955-42ba-baea-41bfccfe08e3"}
+
{"jobId":"6f28ec92-7720-484b-b357-3cb7fddb5952"}
@@ -6900,7 +6905,7 @@
2.2.25.9. Web Scan login
-
{"jobId":"48c03859-a741-4e25-9ade-314a1583e45f"}
+
{"jobId":"98964e58-0c5e-4c44-a3a1-78db898ebf78"}
@@ -7094,7 +7099,7 @@
2.2.25.10. Web Sc
-
{"jobId":"046e0236-dd5f-4b07-8c57-3c45801b6c37"}
+
{"jobId":"5e8b7950-8e53-4d0b-9736-a4423fb46fc7"}
@@ -7258,7 +7263,7 @@
2.2.25.11. Web Scan headers v
-
{"jobId":"dd1b6f6b-7a47-408d-a919-0f06c9b43200"}
+
{"jobId":"a391b64e-a21b-40f0-92ad-c91480338e73"}
@@ -7347,7 +7352,7 @@

2.2.26. User uploads source code

-
$ curl 'https://sechub.example.com/api/project/project1/job/d26d431f-532e-403d-8649-41840afaf02a/sourcecode?checkSum=checkSumValue' -i -X POST \
+
$ curl 'https://sechub.example.com/api/project/project1/job/ab20be15-2b5e-4ec9-b8b2-36b4ad842bf8/sourcecode?checkSum=checkSumValue' -i -X POST \
     -H 'Content-Type: multipart/form-data;charset=UTF-8' \
     -F 'file=PK  
       �<M                       test1.txtPK  ?
@@ -7444,7 +7449,7 @@ 

2.2.27. User approves sechub job

-
$ curl 'https://sechub.example.com/api/project/project1/job/2599f5c1-4bb0-4ca2-9745-49411e356282/approve' -i -X PUT \
+
$ curl 'https://sechub.example.com/api/project/project1/job/e44c859f-66fa-4f41-bdeb-00ea47ad8438/approve' -i -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -7596,7 +7601,7 @@

2.2.28. User checks sechub job state

-
$ curl 'https://sechub.example.com/api/project/project1/job/acd54ae3-6a88-4002-85f0-c7026639380a' -i -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/job/aa96859a-509e-4761-9b1a-0fd448ac9275' -i -X GET \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -7605,7 +7610,7 @@

2.2.28. User checks sechub job state

-
{"jobUUID":"acd54ae3-6a88-4002-85f0-c7026639380a","owner":"CREATOR1","created":"","started":"2024-08-08T07:50:50.192109111","ended":"2024-08-08T08:05:50.192137775","state":"ENDED","result":"OK","trafficLight":"GREEN"}
+
{"jobUUID":"aa96859a-509e-4761-9b1a-0fd448ac9275","owner":"CREATOR1","created":"","started":"2024-08-23T09:41:36.176718254","ended":"2024-08-23T09:56:36.176745655","state":"ENDED","result":"OK","trafficLight":"GREEN"}
@@ -7680,7 +7685,7 @@
2.2.29.1. JSON variant
-
$ curl 'https://sechub.example.com/api/project/project1/report/5e4d6d16-930d-4a32-9277-b178d2e0a033' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/04b496b8-7bdb-4319-9bd5-d6a9ff143003' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/json'
@@ -7752,7 +7757,7 @@
2.2.29.2. HTML variant
-
$ curl 'https://sechub.example.com/api/project/project1/report/d2552d0b-e265-4673-ad90-e43e0f61a610' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/ec741b51-508d-4557-ba7f-8af620c6bb19' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/xhtml+xml'
@@ -7760,9 +7765,9 @@
2.2.29.2. HTML variant
-

2.2.30. User marks false positives for finished sechub job

+

2.2.30. User marks false positives

Definition

@@ -7856,7 +7861,7 @@

2.2.30. User marks f

type

String

-

The type of the json content. Currently only accepted value is 'falsePositiveJobDataList'.

+

The type of the json content. Currently only accepted value is 'falsePositiveDataList' but we also still accept the deprecated type 'falsePositiveJobDataList'.

jobData

@@ -7871,13 +7876,63 @@

2.2.30. User marks f

jobData[].findingId

Number

-

SecHub finding identifier - identifies problem inside the job which shall be markeda as a false positive. ATTENTION: at the moment only code scan false positive handling is supported. Infra and web scan findings will lead to a non accepted error!

+

SecHub finding identifier - identifies problem inside the job which shall be markeda as a false positive.

jobData[].comment

String

A comment describing why this is a false positive

+ +

projectData

+

Array

+

Porject data list containing false positive setup for the project

+ + +

projectData[].id

+

String

+

Identifier which is used to update or remove the respective false positive entry.

+ + +

projectData[].comment

+

String

+

A comment describing why this is a false positive.

+ + +

projectData[].webScan

+

Object

+

Defines a section for false positives which occur during webscans.

+ + +

projectData[].webScan.hostPatterns[]

+

Array

+

Defines a list of host patterns for false positives which occur during webscans. At least one entry must be present. Can be used with wildcards like '.host.com'. Each entry must contain more than just wildcards, '..' or '*' are not allowed.

+ + +

projectData[].webScan.urlPathPatterns[]

+

Array

+

Defines a list of urlPathPatterns for false positives which occur during webscans which make it easier e.g. to ignore query parameters. At least one entry must be present. Can be used with wildcards like '/api/users/'. Each entry must contain more than just wildcards, '//' or '' are not allowed.

+ + +

projectData[].webScan.methods[]

+

Array

+

Defines a list of (HTTP) methods for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all methods.

+ + +

projectData[].webScan.ports[]

+

Array

+

Defines a list of server ports for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all server ports.

+ + +

projectData[].webScan.protocols[]

+

Array

+

Defines a list of web request protocols like 'http', 'https', 'wss' for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all protocols.

+ + +

projectData[].webScan.cweId

+

Number

+

Defines a CWE ID for false positives which occur during webscans. This is mandatory, but can be empty. If it is not specified it matches the findings with no CWE IDs.

+
@@ -7890,7 +7945,7 @@

2.2.30. User marks f
$ curl 'https://sechub.example.com/api/project/project1/false-positives' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
-    -d '{"apiVersion":"1.0","type":"falsePositiveJobDataList","jobData":[{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"an optional comment why this is a false positive..."}]}'
+ -d '{"apiVersion":"1.0","type":"falsePositiveDataList","jobData":[{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"an optional comment why this is a false positive..."}],"projectData":[{"id":"unique-identifier","webScan":{"cweId":564,"ports":["8443","8080"],"protocols":["HTTP","HTTPS"],"urlPathPatterns":["/rest/api/project/*","/other/rest/api/"],"hostPatterns":["sub.host.com","*.other.host.com"],"methods":["GET","POST"]},"comment":"an optional comment for this false positive project entry"}]}'

@@ -8198,6 +8253,56 @@

2.2.32. User fetch

String

A comment from author describing why this was marked as a false positive

+ +

falsePositives[].projectData

+

Object

+

Porject data list containing false positive setup for the project.

+ + +

falsePositives[].projectData.id

+

String

+

Identifier which is used to update or remove the respective false positive entry.

+ + +

falsePositives[].projectData.comment

+

String

+

A comment describing why this is a false positive.

+ + +

falsePositives[].projectData.webScan

+

Object

+

Defines a section for false positives which occur during webscans.

+ + +

falsePositives[].projectData.webScan.hostPatterns[]

+

Array

+

Defines a list of host patterns for false positives which occur during webscans. At least one entry must be present. Can be used with wildcards like '.host.com'. Each entry must contain more than just wildcards, '..' or '*' are not allowed.

+ + +

falsePositives[].projectData.webScan.urlPathPatterns[]

+

Array

+

Defines a list of urlPathPatterns for false positives which occur during webscans which make it easier e.g. to ignore query parameters. At least one entry must be present. Can be used with wildcards like '/api/users/'. Each entry must contain more than just wildcards, '//' or '' are not allowed.

+ + +

falsePositives[].projectData.webScan.methods[]

+

Array

+

Defines a list of (HTTP) methods for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all methods.

+ + +

falsePositives[].projectData.webScan.ports[]

+

Array

+

Defines a list of server ports for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all server ports.

+ + +

falsePositives[].projectData.webScan.protocols[]

+

Array

+

Defines a list of web request protocols like 'http', 'https', 'wss' for false positives which occur during webscans. This is optional and if nothing is specified, the entry applies to all protocols.

+ + +

falsePositives[].projectData.webScan.cweId

+

Number

+

Defines a CWE ID for false positives which occur during webscans. This is mandatory, but can be empty. If it is not specified it matches the findings with no CWE IDs.

+
@@ -8216,7 +8321,7 @@

2.2.32. User fetch

-
{"falsePositives":[{"jobData":{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"Only used in documentation build not in deployment"},"author":"developer1","metaData":{"scanType":"codeScan","name":"Absolute Path Traversal","severity":"MEDIUM","code":{"start":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"args","sourceCode":"\tpublic static void main(String[] args) throws Exception {"},"end":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"File","sourceCode":"\t\tFile documentsGenFolder = new File(path);"}},"cweId":36},"created":"2020-06-12 11:53:15"}]}
+
{"falsePositives":[{"jobData":{"jobUUID":"f1d02a9d-5e1b-4f52-99e5-401854ccf936","findingId":42,"comment":"Only used in documentation build not in deployment"},"author":"developer1","metaData":{"scanType":"codeScan","name":"Absolute Path Traversal","severity":"MEDIUM","code":{"start":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"args","sourceCode":"\tpublic static void main(String[] args) throws Exception {"},"end":{"location":"java/com/mercedesbenz/sechub/docgen/AsciidocGenerator.java","relevantPart":"File","sourceCode":"\t\tFile documentsGenFolder = new File(path);"}},"cweId":36},"projectData":{"id":"unique-identifier","webScan":{"cweId":564,"ports":["8443","8080"],"protocols":["HTTP","HTTPS"],"urlPathPatterns":["/rest/api/project/*","/other/rest/api/"],"hostPatterns":["sub.host.com","*.other.host.com"],"methods":["GET","POST"]},"comment":"an optional comment for this false positive project entry"},"created":"2020-06-12 11:53:15"}]}

@@ -8310,7 +8415,7 @@

2.2.33. User uploads binaries

-
$ curl 'https://sechub.example.com/api/project/project1/job/897847f1-3e25-44cc-a4cf-67508dbd295a/binaries' -i -X POST \
+
$ curl 'https://sechub.example.com/api/project/project1/job/4c239794-a2fe-4c06-93c1-aa81672f8749/binaries' -i -X POST \
     -H 'Content-Type: multipart/form-data;charset=UTF-8' \
     -H 'x-file-size: 10240' \
     -F 'file=test1.txt                                                                                           0000664 0001750 0001750 00000000000 13353454574 012170  0                                                                                                    ustar   albert                          albert                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ' \
@@ -8391,14 +8496,106 @@ 

2.2.34. User downloads job rep

-
$ curl 'https://sechub.example.com/api/project/project1/report/spdx/28097c41-5d4d-4355-a509-ce22bdb69537' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/project/project1/report/spdx/28d9d710-6053-46a3-ac91-8b7fc4ede1e0' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -H 'Accept: application/json'
-

2.2.35. User self registration

+

2.2.35. User unmarks existing false positive project data definitons

+ +
+

Definition

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + +
Table 85. General request information
Value

Path

/api/project/{projectId}/false-positive/project-data/{id}

Method

DELETE

Status code

204 NO_CONTENT

+
+

Path parameters

+
+ + ++++ + + + + + + + + + + + + + + + + +
Table 86. https://localhost:8081/api/project/{projectId}/false-positive/project-data/{id}
ParameterDescription

projectId

The project id

id

Identifier which is used to remove the respective false positive entry.

+
+

Request headers

+
+ ++++ + + + + + + +
NameDescription
+
+

Example

+
+
+

Curl request

+
+
+
+
$ curl 'https://sechub.example.com/api/project/project1/false-positive/project-data/unique-identifier' -i -u 'user:secret' -X DELETE
+
+
+
+

Response body
+(empty)

+
+
+
+

2.2.36. User self registration

REST API for usecase UC_001-User self registration

@@ -8406,7 +8603,7 @@

2.2.35. User self registration

Definition

- +@@ -8485,7 +8682,7 @@

2.2.35. User self registration

-

2.2.36. Admin lists open user signups

+

2.2.37. Admin lists open user signups

@@ -8493,7 +8690,7 @@

2.2.36. Admin lists open user signups

Definition

Table 85. General request informationTable 87. General request information
- +@@ -8589,7 +8786,7 @@

2.2.36. Admin lists open user signups

-

2.2.37. Admin applies self registration

+

2.2.38. Admin applies self registration

@@ -8597,7 +8794,7 @@

2.2.37. Admin applies self registration

Definition

Table 86. General request informationTable 88. General request information
- +@@ -8627,7 +8824,7 @@

2.2.37. Admin applies self registration

Path parameters

Table 87. General request informationTable 89. General request information
- +@@ -8677,7 +8874,7 @@

2.2.37. Admin applies self registration
-

2.2.38. Admin deletes user signup

+

2.2.39. Admin deletes user signup

REST API for usecase UC_019-Admin deletes user signup

@@ -8685,7 +8882,7 @@

2.2.38. Admin deletes user signup

Definition

Table 88. https://localhost:8081/api/admin/signup/accept/{userId}Table 90. https://localhost:8081/api/admin/signup/accept/{userId}
- +@@ -8715,7 +8912,7 @@

2.2.38. Admin deletes user signup

Path parameters

Table 89. General request informationTable 91. General request information
- +@@ -8765,7 +8962,7 @@

2.2.38. Admin deletes user signup

-

2.2.39. User requests new API token

+

2.2.40. User requests new API token

@@ -8773,7 +8970,7 @@

2.2.39. User requests new API token

Definition

Table 90. https://localhost:8081/api/admin/signup/{userId}Table 92. https://localhost:8081/api/admin/signup/{userId}
- +@@ -8803,7 +9000,7 @@

2.2.39. User requests new API token

Path parameters

Table 91. General request informationTable 93. General request information
- +@@ -8839,7 +9036,7 @@

2.2.39. User requests new API token

-

2.2.40. Admin lists all running jobs

+

2.2.41. Admin lists all running jobs

@@ -8847,7 +9044,7 @@

2.2.40. Admin lists all running jobs

Definition

Table 92. https://localhost:8081/api/anonymous/refresh/apitoken/{emailAddress}Table 94. https://localhost:8081/api/anonymous/refresh/apitoken/{emailAddress}
- +@@ -8949,12 +9146,12 @@

2.2.40. Admin lists all running jobs

-
[{"jobUUID":"1761a2a9-37a9-48e1-98e5-63e3c2785c67","projectId":"project-name","owner":"owner-userid","status":"RUNNING","since":"2024-08-08T08:05:55.044912463"}]
+
[{"jobUUID":"c739e0cc-c0fc-40dc-bf9d-410b963cb727","projectId":"project-name","owner":"owner-userid","status":"RUNNING","since":"2024-08-23T09:56:40.748649884"}]
-

2.2.41. Admin cancels a job

+

2.2.42. Admin cancels a job

REST API for usecase UC_034-Admin cancels a job

@@ -8962,7 +9159,7 @@

2.2.41. Admin cancels a job

Definition

Table 93. General request informationTable 95. General request information
- +@@ -8992,7 +9189,7 @@

2.2.41. Admin cancels a job

Path parameters

Table 94. General request informationTable 96. General request information
- +@@ -9033,7 +9230,7 @@

2.2.41. Admin cancels a job

-
$ curl 'https://sechub.example.com/api/admin/jobs/cancel/08eaf3b6-4d6e-4ad9-a7ac-7d88b4884d13' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/cancel/0449764d-8f50-4674-9296-feea9f6c6e6e' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -9043,7 +9240,7 @@

2.2.41. Admin cancels a job

-

2.2.42. Admin restarts a job

+

2.2.43. Admin restarts a job

REST API for usecase UC_041-Admin restarts a job

@@ -9051,7 +9248,7 @@

2.2.42. Admin restarts a job

Definition

Table 95. https://localhost:8081/api/admin/jobs/cancel/{jobUUID}Table 97. https://localhost:8081/api/admin/jobs/cancel/{jobUUID}
- +@@ -9081,7 +9278,7 @@

2.2.42. Admin restarts a job

Path parameters

Table 96. General request informationTable 98. General request information
- +@@ -9122,7 +9319,7 @@

2.2.42. Admin restarts a job

-
$ curl 'https://sechub.example.com/api/admin/jobs/restart/98470906-23a7-4233-8228-4e213cb5b173' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/restart/96a0df4a-d99f-4ec2-aebf-ca7686ee893f' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -9132,7 +9329,7 @@

2.2.42. Admin restarts a job

-

2.2.43. Admin restarts a job (hard)

+

2.2.44. Admin restarts a job (hard)

@@ -9140,7 +9337,7 @@

2.2.43. Admin restarts a job (hard)

Definition

Table 97. https://localhost:8081/api/admin/jobs/restart/{jobUUID}Table 99. https://localhost:8081/api/admin/jobs/restart/{jobUUID}
- +@@ -9170,7 +9367,7 @@

2.2.43. Admin restarts a job (hard)

Path parameters

Table 98. General request informationTable 100. General request information
- +@@ -9211,7 +9408,7 @@

2.2.43. Admin restarts a job (hard)

-
$ curl 'https://sechub.example.com/api/admin/jobs/restart-hard/c3a07e23-27f4-4a02-9313-c5e8ee6aa8f7' -i -u 'user:secret' -X POST \
+
$ curl 'https://sechub.example.com/api/admin/jobs/restart-hard/a836178f-8a32-428d-887d-1967851dfa1a' -i -u 'user:secret' -X POST \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -9221,7 +9418,7 @@

2.2.43. Admin restarts a job (hard)

-

2.2.44. User defines mock data configuration for project

+

2.2.45. User defines mock data configuration for project

@@ -9229,7 +9426,7 @@

2.2.44. User defines m

Definition

Table 99. https://localhost:8081/api/admin/jobs/restart-hard/{jobUUID}Table 101. https://localhost:8081/api/admin/jobs/restart-hard/{jobUUID}
- +@@ -9290,7 +9487,7 @@

2.2.44. User defines m
-

2.2.45. User retrieves mock data configuration for project

+

2.2.46. User retrieves mock data configuration for project

@@ -9298,7 +9495,7 @@

2.2.45. User retriev

Definition

Table 100. General request informationTable 102. General request information
- +@@ -9362,7 +9559,7 @@

2.2.45. User retriev
-

2.2.46. Admin updates mapping configuration

+

2.2.47. Admin updates mapping configuration

@@ -9370,7 +9567,7 @@

2.2.46. Admin updates mapping confi

Definition

Table 101. General request informationTable 103. General request information
- +@@ -9400,7 +9597,7 @@

2.2.46. Admin updates mapping confi

Path parameters

Table 102. General request informationTable 104. General request information
- +@@ -9486,7 +9683,7 @@

2.2.46. Admin updates mapping confi
-

2.2.47. Admin fetches mapping configuration

+

2.2.48. Admin fetches mapping configuration

@@ -9494,7 +9691,7 @@

2.2.47. Admin fetches mapping confi

Definition

Table 103. https://localhost:8081/api/admin/config/mapping/{mappingId}Table 105. https://localhost:8081/api/admin/config/mapping/{mappingId}
- +@@ -9524,7 +9721,7 @@

2.2.47. Admin fetches mapping confi

Path parameters

Table 104. General request informationTable 106. General request information
- +@@ -9613,7 +9810,7 @@

2.2.47. Admin fetches mapping confi
-

2.2.48. Admin creates an executor configuration

+

2.2.49. Admin creates an executor configuration

@@ -9621,7 +9818,7 @@

2.2.48. Admin creates an execut

Definition

Table 105. https://localhost:8081/api/admin/config/mapping/{mappingId}Table 107. https://localhost:8081/api/admin/config/mapping/{mappingId}
- +@@ -9744,12 +9941,12 @@

2.2.48. Admin creates an execut
-
19a513e8-f664-43f3-ad0e-ec881c7762f7
+
885d3e89-2293-416d-a050-0f9748a4f27e
-

2.2.49. Admin deletes executor configuration

+

2.2.50. Admin deletes executor configuration

@@ -9757,7 +9954,7 @@

2.2.49. Admin deletes executor con

Definition

Table 106. General request informationTable 108. General request information
- +@@ -9787,7 +9984,7 @@

2.2.49. Admin deletes executor con

Path parameters

Table 107. General request informationTable 109. General request information
- +@@ -9828,7 +10025,7 @@

2.2.49. Admin deletes executor con
-
$ curl 'https://sechub.example.com/api/admin/config/executor/22fb2f08-7b58-4d57-acbb-00f12619c6e1' -i -u 'user:secret' -X DELETE \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/1d01ca8b-14f8-40f2-b55a-8899942e3cd4' -i -u 'user:secret' -X DELETE \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -9838,7 +10035,7 @@

2.2.49. Admin deletes executor con
-

2.2.50. Admin fetches executor configuration list

+

2.2.51. Admin fetches executor configuration list

@@ -9846,7 +10043,7 @@

2.2.50. Admin fetches executo

Definition

Table 108. https://localhost:8081/api/admin/config/executor/{uuid}Table 110. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -9943,12 +10140,12 @@

2.2.50. Admin fetches executo
-
{"executorConfigurations":[{"uuid":"7d298d34-1148-4803-975d-226862654d0b","name":"example configuration","enabled":true}],"type":"executorConfigurationList"}
+
{"executorConfigurations":[{"uuid":"271e5de2-6cb6-4b4a-a3b0-172f1b964f04","name":"example configuration","enabled":true}],"type":"executorConfigurationList"}
-

2.2.51. Admin fetches executor configuration

+

2.2.52. Admin fetches executor configuration

@@ -9956,7 +10153,7 @@

2.2.51. Admin fetches executor con

Definition

Table 109. General request informationTable 111. General request information
- +@@ -9986,7 +10183,7 @@

2.2.51. Admin fetches executor con

Path parameters

Table 110. General request informationTable 112. General request information
- +@@ -10096,7 +10293,7 @@

2.2.51. Admin fetches executor con
-
$ curl 'https://sechub.example.com/api/admin/config/executor/b60c002d-6882-41b7-9378-a1279f10fca9' -i -u 'user:secret' -X GET \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/7f4f4bd0-dd02-4340-a2fd-854c158720cf' -i -u 'user:secret' -X GET \
     -H 'Content-Type: application/json;charset=UTF-8'
@@ -10105,12 +10302,12 @@

2.2.51. Admin fetches executor con
-
{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value"}]},"executorVersion":1,"enabled":false,"uuid":"b60c002d-6882-41b7-9378-a1279f10fca9"}
+
{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value"}]},"executorVersion":1,"enabled":false,"uuid":"7f4f4bd0-dd02-4340-a2fd-854c158720cf"}
-

2.2.52. Admin updates executor configuration setup

+

2.2.53. Admin updates executor configuration setup

@@ -10118,7 +10315,7 @@

2.2.52. Admin updates execut

Definition

Table 111. https://localhost:8081/api/admin/config/executor/{uuid}Table 113. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -10148,7 +10345,7 @@

2.2.52. Admin updates execut

Path parameters

Table 112. General request informationTable 114. General request information
- +@@ -10253,7 +10450,7 @@

2.2.52. Admin updates execut
-
$ curl 'https://sechub.example.com/api/admin/config/executor/70e7df3d-e2c9-4416-b64e-4d93d5500933' -i -u 'user:secret' -X PUT \
+
$ curl 'https://sechub.example.com/api/admin/config/executor/76b10e2d-c1a7-47ae-a611-32ce720ece9e' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
     -d '{"name":"New name","productIdentifier":"PDS_CODESCAN","executorVersion":1,"enabled":false,"setup":{"baseURL":"https://productNew.example.com","credentials":{"user":"env:EXAMPLE_NEW_USENAME","password":"env:EXAMPLE_NEW_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]}}'
@@ -10264,7 +10461,7 @@

2.2.52. Admin updates execut

-

2.2.53. Admin creates an execution profile

+

2.2.54. Admin creates an execution profile

@@ -10272,7 +10469,7 @@

2.2.53. Admin creates an execution p

Definition

Table 113. https://localhost:8081/api/admin/config/executor/{uuid}Table 115. https://localhost:8081/api/admin/config/executor/{uuid}
- +@@ -10302,7 +10499,7 @@

2.2.53. Admin creates an execution p

Path parameters

Table 114. General request informationTable 116. General request information
- +@@ -10393,7 +10590,7 @@

2.2.53. Admin creates an execution p
-

2.2.54. Admin deletes execution profile

+

2.2.55. Admin deletes execution profile

@@ -10401,7 +10598,7 @@

2.2.54. Admin deletes execution profile

Definition

Table 115. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 117. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -10431,7 +10628,7 @@

2.2.54. Admin deletes execution profile

Path parameters

Table 116. General request informationTable 118. General request information
- +@@ -10482,7 +10679,7 @@

2.2.54. Admin deletes execution profile
-

2.2.55. Admin updates execution profile

+

2.2.56. Admin updates execution profile

@@ -10490,7 +10687,7 @@

2.2.55. Admin updates execution profile

Definition

Table 117. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 119. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -10520,7 +10717,7 @@

2.2.55. Admin updates execution profile

Path parameters

Table 118. General request informationTable 120. General request information
- +@@ -10597,7 +10794,7 @@

2.2.55. Admin updates execution profile
$ curl 'https://sechub.example.com/api/admin/config/execution/profile/existing-profile-1' -i -u 'user:secret' -X PUT \
     -H 'Content-Type: application/json;charset=UTF-8' \
-    -d '{"description":"changed description","configurations":[{"uuid":"44742c74-0b9b-46c2-afa7-1c0e8e7f3291","executorVersion":0,"enabled":false,"setup":{"credentials":{},"jobParameters":[]}}],"enabled":true}'
+ -d '{"description":"changed description","configurations":[{"uuid":"ffc9e7f5-b294-4078-8f8f-12b9ad5cd45b","executorVersion":0,"enabled":false,"setup":{"credentials":{},"jobParameters":[]}}],"enabled":true}'
@@ -10606,7 +10803,7 @@

2.2.55. Admin updates execution profile

-

2.2.56. Admin fetches execution profile

+

2.2.57. Admin fetches execution profile

@@ -10614,7 +10811,7 @@

2.2.56. Admin fetches execution profile

Definition

Table 119. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 121. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -10644,7 +10841,7 @@

2.2.56. Admin fetches execution profile

Path parameters

Table 120. General request informationTable 122. General request information
- +@@ -10753,12 +10950,12 @@

2.2.56. Admin fetches execution profile
-
{"description":"a description","enabled":true,"configurations":[{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]},"executorVersion":1,"enabled":false,"uuid":"ce989c37-b285-4975-a802-3930530d627b"}],"projectIds":["project-1","project-2"]}
+
{"description":"a description","enabled":true,"configurations":[{"name":"New name","productIdentifier":"PDS_CODESCAN","setup":{"baseURL":"https://product.example.com","credentials":{"user":"env:EXAMPLE_USENAME","password":"env:EXAMPLE_PASSWORD"},"jobParameters":[{"key":"example.key1","value":"A value but changed. Remark: the other parameter (example.key2) has been removed by this call"}]},"executorVersion":1,"enabled":false,"uuid":"ba0270e0-da2a-4a4c-bdb6-0354f3e8af8c"}],"projectIds":["project-1","project-2"]}
-

2.2.57. Admin fetches execution profile list

+

2.2.58. Admin fetches execution profile list

@@ -10766,7 +10963,7 @@

2.2.57. Admin fetches execution pr

Definition

Table 121. https://localhost:8081/api/admin/config/execution/profile/{profileId}Table 123. https://localhost:8081/api/admin/config/execution/profile/{profileId}
- +@@ -10868,7 +11065,7 @@

2.2.57. Admin fetches execution pr
-

2.2.58. Admin assigns execution profile to project

+

2.2.59. Admin assigns execution profile to project

@@ -10876,7 +11073,7 @@

2.2.58. Admin assigns execut

Definition

Table 122. General request informationTable 124. General request information
- +@@ -10906,7 +11103,7 @@

2.2.58. Admin assigns execut

Path parameters

Table 123. General request informationTable 125. General request information
- +@@ -10961,7 +11158,7 @@

2.2.58. Admin assigns execut
-

2.2.59. Admin unassigns execution profile from project

+

2.2.60. Admin unassigns execution profile from project

@@ -10969,7 +11166,7 @@

2.2.59. Admin unassigns

Definition

Table 124. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}Table 126. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}
- +@@ -10999,7 +11196,7 @@

2.2.59. Admin unassigns

Path parameters

Table 125. General request informationTable 127. General request information
- +@@ -11054,7 +11251,7 @@

2.2.59. Admin unassigns
-

2.2.60. Admin fetches auto cleanup configuration

+

2.2.61. Admin fetches auto cleanup configuration

@@ -11062,7 +11259,7 @@

2.2.60. Admin fetches auto cle

Definition

Table 126. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}Table 128. https://localhost:8081/api/admin/config/execution/profile/{profileId}/project/{projectId}
- +@@ -11125,7 +11322,7 @@

2.2.60. Admin fetches auto cle
-

2.2.61. Admin updates auto cleanup configuration

+

2.2.62. Admin updates auto cleanup configuration

@@ -11133,7 +11330,7 @@

2.2.61. Admin updates auto cle

Definition

Table 127. General request informationTable 129. General request information
- +@@ -11193,7 +11390,7 @@

2.2.61. Admin updates auto cle
-

2.2.62. Admin starts encryption rotation

+

2.2.63. Admin starts encryption rotation

@@ -11201,7 +11398,7 @@

2.2.62. Admin starts encryption rotati

Definition

Table 128. General request informationTable 130. General request information
- +@@ -11265,7 +11462,7 @@

2.2.62. Admin starts encryption rotati
-

2.2.63. Admin fetches encryption status

+

2.2.64. Admin fetches encryption status

@@ -11273,7 +11470,7 @@

2.2.63. Admin fetches encryption status

Definition

Table 129. General request informationTable 131. General request information
- +@@ -11405,7 +11602,7 @@

2.2.63. Admin fetches encryption status
-

2.2.64. Admin disables job processing in scheduler

+

2.2.65. Admin disables job processing in scheduler

@@ -11413,7 +11610,7 @@

2.2.64. Admin disables job p

Definition

Table 130. General request informationTable 132. General request information
- +@@ -11472,7 +11669,7 @@

2.2.64. Admin disables job p
-

2.2.65. Admin enables scheduler job processing

+

2.2.66. Admin enables scheduler job processing

@@ -11480,7 +11677,7 @@

2.2.65. Admin enables scheduler

Definition

Table 131. General request informationTable 133. General request information
- +@@ -11539,7 +11736,7 @@

2.2.65. Admin enables scheduler
-

2.2.66. Admin get scheduler status

+

2.2.67. Admin get scheduler status

@@ -11547,7 +11744,7 @@

2.2.66. Admin get scheduler status

Definition

Table 132. General request informationTable 134. General request information
- +@@ -11606,7 +11803,7 @@

2.2.66. Admin get scheduler status

-

2.2.67. Admin lists status information

+

2.2.68. Admin lists status information

@@ -11614,7 +11811,7 @@

2.2.67. Admin lists status informationDefinition

Table 133. General request informationTable 135. General request information
- +@@ -11706,7 +11903,7 @@

2.2.67. Admin lists status information
-

2.2.68. Admin fetches server runtime data

+

2.2.69. Admin fetches server runtime data

@@ -11714,7 +11911,7 @@

2.2.68. Admin fetches server runtime

Definition

Table 134. General request informationTable 136. General request information
- +@@ -11786,7 +11983,7 @@

2.2.68. Admin fetches server runtime
-

2.2.69. User lists jobs for project

+

2.2.70. User lists jobs for project

@@ -11794,7 +11991,7 @@

2.2.69. User lists jobs for project

Definition

Table 135. General request informationTable 137. General request information
- +@@ -11824,7 +12021,7 @@

2.2.69. User lists jobs for project

Path parameters

Table 136. General request informationTable 138. General request information
- +@@ -11948,7 +12145,7 @@

2.2.69. User lists jobs for project

-
{"page":0,"totalPages":1,"content":[{"jobUUID":"048f9167-5b7a-41fb-a235-8e3a7e996efa","executedBy":"User1","created":"2024-08-08T07:48:50.319019742","started":"2024-08-08T07:50:50.319048296","ended":"2024-08-08T08:05:50.319059717","executionState":"ENDED","trafficLight":"GREEN","executionResult":"OK","metaData":{"labels":{"stage":"test"}}}]}
+
{"page":0,"totalPages":1,"content":[{"jobUUID":"70572d6d-79be-4cbc-887a-a01a3f67169d","executedBy":"User1","created":"2024-08-23T09:39:36.296296402","started":"2024-08-23T09:41:36.296322792","ended":"2024-08-23T09:56:36.296333331","executionState":"ENDED","trafficLight":"GREEN","executionResult":"OK","metaData":{"labels":{"stage":"test"}}}]}
@@ -12343,7 +12540,7 @@
4.1.1.5. Sechub execution

UC_011-User starts scan by client

  • -

    UC_044-User marks false positives for finished sechub job

    +

    UC_044-User marks false positives

  • UC_045-User unmarks existing false positive definitons

    @@ -12357,6 +12554,9 @@
    4.1.1.5. Sechub execution
  • UC_070-User downloads job report in SPDX format

  • +
  • +

    UC_078-User unmarks existing false positive project data definitons

    +
  • @@ -15434,13 +15634,17 @@

    4.1.44. UC_043-Admin receives notification about

    Table 137. https://localhost:8081/api/project/{projectId}/jobsTable 139. https://localhost:8081/api/project/{projectId}/jobs
    -

    4.1.45. UC_044-User marks false positives for finished sechub job

    -