Skip to content

Commit 525e5b0

Browse files
fix(sdk): reject key access entries without URLs (#423)
## Summary - reject malformed key access entries whose URL is missing before TDF load planning - add regression coverage for the malformed manifest found by the main-branch fuzz run - move reader configuration creation outside the AssertJ exception lambda to satisfy static analysis ## Rationale The fuzz failure after #422 was not caused by the empty-manifest validation itself. That fix allowed the corpus to proceed, exposing a separate malformed-manifest path: a key access entry with a missing URL reached Autoconfigure.KeySplitStep and triggered a NullPointerException. This change rejects that manifest with an IllegalArgumentException during manifest validation. Failed job: https://github.com/opentdf/java-sdk/actions/runs/39472084130/job/118798445562 Tracking issue: https://virtru.atlassian.net/browse/DSPX-5073 ## Test plan - mvn -pl sdk -am test -Dtest='ManifestTest,TDFReaderTest' -Dsurefire.failIfNoSpecifiedTests=false (38 tests passed) - mvn -pl sdk -am test -Dtest='Fuzzing#fuzzTDF' -Dsurefire.failIfNoSpecifiedTests=false, replaying the exact crash artifact from the failed job (9 corpus tests passed) ## Public API No public API changes. Signed-off-by: Elizabeth Healy <ehealy@virtru.com>
1 parent 762fe40 commit 525e5b0

3 files changed

Lines changed: 15 additions & 1 deletion

File tree

‎sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,8 @@ protected static Manifest readManifest(String manifestJson) {
799799
for (Manifest.KeyAccess keyAccess : result.encryptionInformation.keyAccessObj) {
800800
if (keyAccess == null) {
801801
throw new IllegalArgumentException("Invalid null KeyAccess in manifest");
802+
} else if (keyAccess.url == null) {
803+
throw new IllegalArgumentException("Invalid KeyAccess with null url in manifest");
802804
}
803805
}
804806

‎sdk/src/test/java/io/opentdf/platform/sdk/ManifestTest.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.stream.Stream;
1515

1616
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819

1920
public class ManifestTest {
@@ -260,6 +261,16 @@ void testAbsentDefaultsLeaveSegmentSizesAtZero() {
260261
assertThat(segment.encryptedSegmentSize).isZero();
261262
}
262263

264+
@Test
265+
void rejectsKeyAccessWithoutUrl() {
266+
String manifest = manifestWithSegments("{ \"hash\": \"aGFzaDA=\" }")
267+
.replace(" \"url\": \"http://localhost:65432/kas\",", "");
268+
269+
assertThatThrownBy(() -> Manifest.readManifest(manifest))
270+
.isInstanceOf(IllegalArgumentException.class)
271+
.hasMessage("Invalid KeyAccess with null url in manifest");
272+
}
273+
263274
@Test
264275
void testReadingManifestWithObjectStatementValue() throws IOException {
265276
final Manifest manifest;

‎sdk/src/test/java/io/opentdf/platform/sdk/TDFReaderTest.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ void rejectsEmptyManifest(String manifest) throws IOException {
8989
TDFWriter.TDF_PAYLOAD_FILE_NAME, PAYLOAD,
9090
"0.manifest.json", manifest)) {
9191
var tdf = new TDF(new FakeServicesBuilder().setKas(TDFTest.kas).build());
92+
var readerConfig = Config.newTDFReaderConfig();
9293

93-
assertThatThrownBy(() -> tdf.loadTDF(tdfBytes, Config.newTDFReaderConfig()))
94+
assertThatThrownBy(() -> tdf.loadTDF(tdfBytes, readerConfig))
9495
.isInstanceOf(IllegalArgumentException.class)
9596
.hasMessage("Manifest is empty");
9697
}

0 commit comments

Comments
 (0)