Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

public class FdpClient implements FdpClientInterface {
private final HttpClient client;
Expand All @@ -52,6 +53,20 @@ private void isAuthenticated() {
}
}

/**
* FDP-supplied ids are embedded in outgoing request URIs; require a well-formed UUID
* so a malicious/compromised FDP response can't inject additional path/query/fragment components.
*/
Comment thread
Copilot marked this conversation as resolved.
private static String validatedId(String id) {
try {
return UUID.fromString(id).toString();
} catch (IllegalArgumentException | NullPointerException e) {
String safeId = id == null ? "null" : id.replaceAll("[\\r\\n\\t]", "_");
if (safeId.length() > 100) safeId = safeId.substring(0, 100) + "...";
throw new FdpClientException("FDP returned an invalid id (expected UUID): " + safeId, e);
}
}
Comment thread
Copilot marked this conversation as resolved.

public LoginResponseDto getAuthToken(LoginRequestDto loginRequest) {
logger.info("Connecting to FDP at {} as {} ", hostname, loginRequest.email());

Expand Down Expand Up @@ -169,7 +184,7 @@ public void updateSchema(ShapeTask task, UpdateSchemaRequestDto updateSchemaRequ
try {
isAuthenticated();

URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/draft");
URI uri = new URI(this.hostname + "/metadata-schemas/" + validatedId(task.uuid) + "/draft");

HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(
this.objectMapper.writeValueAsString(updateSchemaRequest)
Expand Down Expand Up @@ -202,7 +217,7 @@ public void releaseSchema(ShapeTask task, ReleaseSchemaRequestDto releaseSchemaR
try {
isAuthenticated();

URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/versions");
URI uri = new URI(this.hostname + "/metadata-schemas/" + validatedId(task.uuid) + "/versions");

HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(
this.objectMapper.writeValueAsString(releaseSchemaRequest)
Expand Down Expand Up @@ -268,7 +283,7 @@ public ResourceResponseDto fetchResource(String resourceId){
try {
isAuthenticated();

URI uri = new URI(this.hostname + "/resource-definitions/" + resourceId);
URI uri = new URI(this.hostname + "/resource-definitions/" + validatedId(resourceId));

HttpRequest request = HttpRequest.newBuilder()
.GET()
Expand Down Expand Up @@ -337,7 +352,7 @@ public void updateResource(ResourceTask task, ResourceResponseDto resourceRespon
try {
isAuthenticated();

URI uri = new URI(this.hostname + "/resource-definitions/" + task.UUID);
URI uri = new URI(this.hostname + "/resource-definitions/" + validatedId(task.UUID));

HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(
this.objectMapper.writeValueAsString(resourceResponse)
Expand Down