From 4bc0eec69fe956522b9c633e22b6334eb817f6b8 Mon Sep 17 00:00:00 2001 From: Aaron Lew <64337293+aaronlew02@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:26:51 -0400 Subject: [PATCH 1/2] Replace URI.resolve with URIFormat.appendPath Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com> --- .../java/dev/sigstore/rekor/client/RekorClientHttp.java | 9 +++++---- .../dev/sigstore/rekor/v2/client/RekorV2ClientHttp.java | 3 ++- .../test/java/dev/sigstore/testing/FulcioWrapper.java | 6 +++++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sigstore-java/src/main/java/dev/sigstore/rekor/client/RekorClientHttp.java b/sigstore-java/src/main/java/dev/sigstore/rekor/client/RekorClientHttp.java index 11f27c542..d77e6a972 100644 --- a/sigstore-java/src/main/java/dev/sigstore/rekor/client/RekorClientHttp.java +++ b/sigstore-java/src/main/java/dev/sigstore/rekor/client/RekorClientHttp.java @@ -25,6 +25,7 @@ import com.google.api.client.util.Preconditions; import dev.sigstore.http.HttpClients; import dev.sigstore.http.HttpParams; +import dev.sigstore.http.URIFormat; import dev.sigstore.json.JsonParseException; import dev.sigstore.trustroot.Service; import java.io.IOException; @@ -79,7 +80,7 @@ public RekorClientHttp build() { @Override public RekorResponse putEntry(HashedRekordRequest hashedRekordRequest) throws IOException, RekorParseException { - URI rekorPutEndpoint = uri.resolve(REKOR_ENTRIES_PATH); + URI rekorPutEndpoint = URIFormat.appendPath(uri, REKOR_ENTRIES_PATH); HttpRequest req = HttpClients.newRequestFactory(httpParams) @@ -100,7 +101,7 @@ public RekorResponse putEntry(HashedRekordRequest hashedRekordRequest) resp.parseAsString())); } - URI rekorEntryUri = uri.resolve(resp.getHeaders().getLocation()); + URI rekorEntryUri = URIFormat.appendPath(uri, resp.getHeaders().getLocation()); String entry = resp.parseAsString(); return RekorResponse.newRekorResponse(rekorEntryUri, entry); } @@ -113,7 +114,7 @@ public Optional getEntry(HashedRekordRequest hashedRekordRequest) @Override public Optional getEntry(String UUID) throws IOException, RekorParseException { - URI getEntryURI = uri.resolve(REKOR_ENTRIES_PATH + "/" + UUID); + URI getEntryURI = URIFormat.appendPath(uri, REKOR_ENTRIES_PATH + "/" + UUID); HttpRequest req = HttpClients.newRequestFactory(httpParams).buildGetRequest(new GenericUrl(getEntryURI)); req.getHeaders().set("Accept", "application/json"); @@ -132,7 +133,7 @@ public Optional getEntry(String UUID) throws IOException, RekorParse public List searchEntry( String email, String hash, String publicKeyFormat, String publicKeyContent) throws IOException, JsonParseException { - URI rekorSearchEndpoint = uri.resolve(REKOR_INDEX_SEARCH_PATH); + URI rekorSearchEndpoint = URIFormat.appendPath(uri, REKOR_INDEX_SEARCH_PATH); HashMap publicKeyParams = null; if (publicKeyContent != null) { diff --git a/sigstore-java/src/main/java/dev/sigstore/rekor/v2/client/RekorV2ClientHttp.java b/sigstore-java/src/main/java/dev/sigstore/rekor/v2/client/RekorV2ClientHttp.java index ec4b11e16..c000ae1c2 100644 --- a/sigstore-java/src/main/java/dev/sigstore/rekor/v2/client/RekorV2ClientHttp.java +++ b/sigstore-java/src/main/java/dev/sigstore/rekor/v2/client/RekorV2ClientHttp.java @@ -24,6 +24,7 @@ import dev.sigstore.http.HttpClients; import dev.sigstore.http.HttpParams; import dev.sigstore.http.ImmutableHttpParams; +import dev.sigstore.http.URIFormat; import dev.sigstore.proto.rekor.v2.CreateEntryRequest; import dev.sigstore.proto.rekor.v2.DSSERequestV002; import dev.sigstore.proto.rekor.v2.HashedRekordRequestV002; @@ -88,7 +89,7 @@ public RekorEntry putEntry(DSSERequestV002 dsseRequest) throws IOException, Reko } private RekorEntry putEntry(CreateEntryRequest request) throws IOException, RekorParseException { - URI rekorPutEndpoint = uri.resolve(REKOR_ENTRIES_PATH); + URI rekorPutEndpoint = URIFormat.appendPath(uri, REKOR_ENTRIES_PATH); String jsonPayload = JsonFormat.printer().print(request); diff --git a/sigstore-java/src/test/java/dev/sigstore/testing/FulcioWrapper.java b/sigstore-java/src/test/java/dev/sigstore/testing/FulcioWrapper.java index 884a734a5..0a8669cfd 100644 --- a/sigstore-java/src/test/java/dev/sigstore/testing/FulcioWrapper.java +++ b/sigstore-java/src/test/java/dev/sigstore/testing/FulcioWrapper.java @@ -17,6 +17,7 @@ import com.google.gson.Gson; import dev.sigstore.encryption.certificates.Certificates; +import dev.sigstore.http.URIFormat; import dev.sigstore.trustroot.Service; import java.io.IOException; import java.net.URI; @@ -56,7 +57,10 @@ public Service getGrpcService() { public CertPath getTrustBundle() throws CertificateException, IOException, InterruptedException { HttpRequest req = - HttpRequest.newBuilder().uri(getURI().resolve("/api/v2/trustBundle")).GET().build(); + HttpRequest.newBuilder() + .uri(URIFormat.appendPath(getURI(), "/api/v2/trustBundle")) + .GET() + .build(); HttpResponse response = HttpClient.newHttpClient().send(req, BodyHandlers.ofString()); TrustBundle tb = new Gson().fromJson(response.body(), TrustBundle.class); From b232b9749bde53aa3c25f3b9747e7e76c257428b Mon Sep 17 00:00:00 2001 From: Aaron Lew <64337293+aaronlew02@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:53:00 -0400 Subject: [PATCH 2/2] Ban URI.resolve in favor of URIFormat.appendPath Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com> --- config/forbiddenApis.txt | 2 ++ sigstore-java/src/main/java/dev/sigstore/http/URIFormat.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/forbiddenApis.txt b/config/forbiddenApis.txt index 99f15861f..26e39614d 100644 --- a/config/forbiddenApis.txt +++ b/config/forbiddenApis.txt @@ -1,3 +1,5 @@ com.google.protobuf.util.JsonFormat#parser() @ Use dev.sigstore.json.ProtoJson#parser() instead dev.sigstore.http.HttpClients#newHttpTransport(dev.sigstore.http.HttpParams) @ Use dev.sigstore.http.HttpClients#newRequestFactory(...) instead com.google.gson.GsonBuilder @ Use dev.sigstore.json.GsonSupplier.GSON instead +java.net.URI#resolve(java.lang.String) @ Use dev.sigstore.http.URIFormat#appendPath(java.net.URI, java.lang.String) instead +java.net.URI#resolve(java.net.URI) @ Use dev.sigstore.http.URIFormat#appendPath(java.net.URI, java.lang.String) instead diff --git a/sigstore-java/src/main/java/dev/sigstore/http/URIFormat.java b/sigstore-java/src/main/java/dev/sigstore/http/URIFormat.java index 476de0886..10ac3f33f 100644 --- a/sigstore-java/src/main/java/dev/sigstore/http/URIFormat.java +++ b/sigstore-java/src/main/java/dev/sigstore/http/URIFormat.java @@ -15,6 +15,7 @@ */ package dev.sigstore.http; +import dev.sigstore.forbidden.SuppressForbidden; import java.net.URI; import java.net.URISyntaxException; @@ -64,6 +65,7 @@ public static URI addTrailingSlash(URI input) { * @param path the path segment to append (e.g., "users" or "/users"). * @return a new URI with the path appended (e.g., "http://example.com/api/users"). */ + @SuppressForbidden(reason = "URI#resolve") public static URI appendPath(URI base, String path) { String relativePath = path.replaceAll("^/+", "");