Skip to content

Commit 4778763

Browse files
committed
feat!: #7510 Display a dedicated message when receiving an HTTP 403
BREAKING CHANGE: adds a new checked exception as a return type of the utils module public API
1 parent b231423 commit 4778763

File tree

9 files changed

+66
-13
lines changed

9 files changed

+66
-13
lines changed

core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.owasp.dependencycheck.utils.Downloader;
3535
import org.owasp.dependencycheck.utils.FileFilterBuilder;
3636
import org.owasp.dependencycheck.utils.FileUtils;
37+
import org.owasp.dependencycheck.utils.ForbiddenException;
3738
import org.owasp.dependencycheck.utils.InvalidSettingException;
3839
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
3940
import org.owasp.dependencycheck.utils.Settings;
@@ -313,6 +314,12 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy
313314
final String message = "Could not connect to Central search. Analysis failed.";
314315
LOGGER.error(message, ioe);
315316
throw new AnalysisException(message, ioe);
317+
} catch (ForbiddenException e) {
318+
final String message = "Connection to Central search refused. This is most likely not a problem with " +
319+
"Dependency-Check itself and is related to network connectivity. Please check " +
320+
"https://central.sonatype.org/faq/403-error-central/.";
321+
LOGGER.error(message);
322+
throw new AnalysisException(message, e);
316323
}
317324
}
318325

@@ -330,7 +337,8 @@ public void analyzeDependency(Dependency dependency, Engine engine) throws Analy
330337
* @throws TooManyRequestsException if Central has received too many
331338
* requests.
332339
*/
333-
protected List<MavenArtifact> fetchMavenArtifacts(Dependency dependency) throws IOException, TooManyRequestsException {
340+
protected List<MavenArtifact> fetchMavenArtifacts(Dependency dependency) throws IOException,
341+
TooManyRequestsException, ForbiddenException {
334342
IOException lastException = null;
335343
long sleepingTimeBetweenRetriesInMillis = BASE_RETRY_WAIT;
336344
int triesLeft = numberOfRetries;

core/src/main/java/org/owasp/dependencycheck/data/artifactory/ArtifactorySearch.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.owasp.dependencycheck.dependency.Dependency;
3434
import org.owasp.dependencycheck.utils.Checksum;
3535
import org.owasp.dependencycheck.utils.Downloader;
36+
import org.owasp.dependencycheck.utils.ForbiddenException;
3637
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
3738
import org.owasp.dependencycheck.utils.Settings;
3839
import org.owasp.dependencycheck.utils.TooManyRequestsException;
@@ -116,6 +117,8 @@ public List<MavenArtifact> search(Dependency dependency) throws IOException {
116117
throw new IOException(msg.append(" (400): Invalid URL").toString(), e);
117118
} catch (ResourceNotFoundException e) {
118119
throw new IOException(msg.append(" (404): Not found").toString(), e);
120+
} catch (ForbiddenException e) {
121+
throw new IOException(msg.append(" (403): Forbidden").toString(), e);
119122
}
120123
}
121124

core/src/main/java/org/owasp/dependencycheck/data/central/CentralSearch.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.hc.core5.http.message.BasicHeader;
2222
import org.owasp.dependencycheck.utils.DownloadFailedException;
2323
import org.owasp.dependencycheck.utils.Downloader;
24+
import org.owasp.dependencycheck.utils.ForbiddenException;
2425
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
2526
import org.owasp.dependencycheck.utils.TooManyRequestsException;
2627
import java.io.FileNotFoundException;
@@ -135,7 +136,7 @@ public CentralSearch(Settings settings) throws MalformedURLException {
135136
* @throws TooManyRequestsException if Central has received too many
136137
* requests.
137138
*/
138-
public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRequestsException {
139+
public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRequestsException, ForbiddenException {
139140
if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
140141
throw new IllegalArgumentException("Invalid SHA1 format");
141142
}
@@ -180,6 +181,9 @@ public List<MavenArtifact> searchSha1(String sha1) throws IOException, TooManyRe
180181
} catch (URISyntaxException e) {
181182
final String errorMessage = "Could not convert central search URL to a URI " + e.getMessage();
182183
throw new IOException(errorMessage, e);
184+
} catch (ForbiddenException e) {
185+
final String errorMessage = "Forbidden access to MavenCentral " + e.getMessage();
186+
throw new ForbiddenException(errorMessage, e);
183187
}
184188
if (cache != null) {
185189
cache.put(sha1, result);

core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV2Search.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.hc.core5.http.message.BasicHeader;
3535
import org.owasp.dependencycheck.utils.DownloadFailedException;
3636
import org.owasp.dependencycheck.utils.Downloader;
37+
import org.owasp.dependencycheck.utils.ForbiddenException;
3738
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
3839
import org.owasp.dependencycheck.utils.Settings;
3940

@@ -147,7 +148,7 @@ public MavenArtifact searchSha1(String sha1) throws IOException {
147148
throw new IOException("Could not connect to Nexus");
148149
} catch (ResourceNotFoundException e) {
149150
throw new FileNotFoundException("Artifact not found in Nexus");
150-
} catch (XPathExpressionException | URISyntaxException e) {
151+
} catch (XPathExpressionException | URISyntaxException | ForbiddenException e) {
151152
throw new IOException(e.getMessage(), e);
152153
}
153154
}
@@ -163,7 +164,7 @@ public boolean preflightRequest() {
163164
LOGGER.warn("Pre-flight request to Nexus failed; expected root node name of status, got {}", doc.getDocumentElement().getNodeName());
164165
return false;
165166
}
166-
} catch (IOException | TooManyRequestsException | ResourceNotFoundException | URISyntaxException e) {
167+
} catch (IOException | TooManyRequestsException | ResourceNotFoundException | URISyntaxException | ForbiddenException e) {
167168
LOGGER.warn("Pre-flight request to Nexus failed: ", e);
168169
return false;
169170
}

core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusV3Search.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.jetbrains.annotations.Nullable;
2828
import org.owasp.dependencycheck.utils.DownloadFailedException;
2929
import org.owasp.dependencycheck.utils.Downloader;
30+
import org.owasp.dependencycheck.utils.ForbiddenException;
3031
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
3132
import org.owasp.dependencycheck.utils.Settings;
3233
import org.owasp.dependencycheck.utils.TooManyRequestsException;
@@ -146,7 +147,7 @@ private String retrievePageAndAddMatchingArtifact(CloseableHttpClient client, Li
146147
try {
147148
return Downloader.getInstance().fetchAndHandle(client, url, handler, List.of(new BasicHeader(HttpHeaders.ACCEPT,
148149
ContentType.APPLICATION_JSON)));
149-
} catch (TooManyRequestsException | ResourceNotFoundException | DownloadFailedException e) {
150+
} catch (TooManyRequestsException | ResourceNotFoundException | DownloadFailedException | ForbiddenException e) {
150151
if (LOGGER.isDebugEnabled()) {
151152
int responseCode = -1;
152153
String responseMessage = "";

core/src/main/java/org/owasp/dependencycheck/data/update/KnownExploitedDataSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.owasp.dependencycheck.data.update.exception.CorruptedDatastreamException;
3636
import org.owasp.dependencycheck.data.update.exception.UpdateException;
3737
import org.owasp.dependencycheck.utils.Downloader;
38+
import org.owasp.dependencycheck.utils.ForbiddenException;
3839
import org.owasp.dependencycheck.utils.ResourceNotFoundException;
3940
import org.owasp.dependencycheck.utils.Settings;
4041
import org.owasp.dependencycheck.utils.TooManyRequestsException;
@@ -102,7 +103,7 @@ public KnownExploitedVulnerabilitiesSchema handleEntity(HttpEntity entity) throw
102103
dbProperties.save(DatabaseProperties.KEV_LAST_CHECKED, Long.toString(System.currentTimeMillis() / 1000));
103104
return true;
104105
} catch (TooManyRequestsException | ResourceNotFoundException | IOException | DatabaseException
105-
| SQLException | URISyntaxException ex) {
106+
| SQLException | URISyntaxException | ForbiddenException ex) {
106107
throw new UpdateException(ex);
107108
}
108109
}

core/src/test/java/org/owasp/dependencycheck/analyzer/CentralAnalyzerTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.junit.Test;
2222
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
2323
import org.owasp.dependencycheck.data.central.CentralSearch;
24+
import org.owasp.dependencycheck.utils.ForbiddenException;
2425
import org.owasp.dependencycheck.utils.TooManyRequestsException;
2526
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
2627
import org.owasp.dependencycheck.dependency.Dependency;
@@ -50,7 +51,7 @@ public class CentralAnalyzerTest extends BaseTest {
5051

5152
@Test
5253
@SuppressWarnings("PMD.NonStaticInitializer")
53-
public void testFetchMavenArtifactsWithoutException() throws IOException, TooManyRequestsException {
54+
public void testFetchMavenArtifactsWithoutException() throws IOException, TooManyRequestsException, ForbiddenException {
5455
CentralAnalyzer instance = new CentralAnalyzer();
5556
instance.setCentralSearch(centralSearch);
5657
when(dependency.getSha1sum()).thenReturn(SHA1_SUM);
@@ -64,7 +65,7 @@ public void testFetchMavenArtifactsWithoutException() throws IOException, TooMan
6465
@Test(expected = FileNotFoundException.class)
6566
@SuppressWarnings("PMD.NonStaticInitializer")
6667
public void testFetchMavenArtifactsRethrowsFileNotFoundException()
67-
throws IOException, TooManyRequestsException {
68+
throws IOException, TooManyRequestsException, ForbiddenException {
6869
CentralAnalyzer instance = new CentralAnalyzer();
6970
instance.setCentralSearch(centralSearch);
7071
when(dependency.getSha1sum()).thenReturn(SHA1_SUM);
@@ -75,7 +76,7 @@ public void testFetchMavenArtifactsRethrowsFileNotFoundException()
7576
@Test(expected = IOException.class)
7677
@SuppressWarnings("PMD.NonStaticInitializer")
7778
public void testFetchMavenArtifactsAlwaysThrowsIOException()
78-
throws IOException, TooManyRequestsException {
79+
throws IOException, TooManyRequestsException, ForbiddenException {
7980
getSettings().setInt(Settings.KEYS.ANALYZER_CENTRAL_RETRY_COUNT, 1);
8081
getSettings().setBoolean(Settings.KEYS.ANALYZER_CENTRAL_USE_CACHE, false);
8182
CentralAnalyzer instance = new CentralAnalyzer();

utils/src/main/java/org/owasp/dependencycheck/utils/Downloader.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ public CloseableHttpClient getHttpClient(boolean useProxy) {
649649
* @throws ResourceNotFoundException When HTTP status 404 is encountered
650650
*/
651651
public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler)
652-
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
652+
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
653653
return fetchAndHandle(url, handler, Collections.emptyList(), true);
654654
}
655655

@@ -666,7 +666,7 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
666666
* @throws ResourceNotFoundException When HTTP status 404 is encountered
667667
*/
668668
public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler, @NotNull List<Header> hdr)
669-
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
669+
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
670670
return fetchAndHandle(url, handler, hdr, true);
671671
}
672672

@@ -684,7 +684,7 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
684684
* @throws ResourceNotFoundException When HTTP status 404 is encountered
685685
*/
686686
public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler<T> handler, @NotNull List<Header> hdr, boolean useProxy)
687-
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException {
687+
throws IOException, TooManyRequestsException, ResourceNotFoundException, URISyntaxException, ForbiddenException {
688688
final T data;
689689
if ("file".equals(url.getProtocol())) {
690690
final Path p = Paths.get(url.toURI());
@@ -717,7 +717,8 @@ public <T> T fetchAndHandle(@NotNull URL url, @NotNull HttpClientResponseHandler
717717
* @throws ResourceNotFoundException When HTTP status 404 is encountered
718718
*/
719719
public <T> T fetchAndHandle(@NotNull CloseableHttpClient client, @NotNull URL url, @NotNull HttpClientResponseHandler<T> handler,
720-
@NotNull List<Header> hdr) throws IOException, TooManyRequestsException, ResourceNotFoundException {
720+
@NotNull List<Header> hdr) throws IOException, TooManyRequestsException,
721+
ResourceNotFoundException, ForbiddenException {
721722
try {
722723
final String theProtocol = url.getProtocol();
723724
if (!("http".equals(theProtocol) || "https".equals(theProtocol))) {
@@ -732,6 +733,9 @@ public <T> T fetchAndHandle(@NotNull CloseableHttpClient client, @NotNull URL ur
732733
} catch (HttpResponseException hre) {
733734
final String messageFormat = "%s - Server status: %d - Server reason: %s";
734735
switch (hre.getStatusCode()) {
736+
case 403:
737+
throw new ForbiddenException(String.format(messageFormat, url, hre.getStatusCode(),
738+
hre.getReasonPhrase()));
735739
case 404:
736740
throw new ResourceNotFoundException(String.format(messageFormat, url, hre.getStatusCode(), hre.getReasonPhrase()));
737741
case 429:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.owasp.dependencycheck.utils;
20+
21+
public class ForbiddenException extends Exception {
22+
23+
public ForbiddenException(String message) {
24+
super(message);
25+
}
26+
27+
public ForbiddenException(String message, ForbiddenException cause) {
28+
super(message, cause);
29+
}
30+
}

0 commit comments

Comments
 (0)