Skip to content

Commit 2bb77cd

Browse files
committed
chore: fuzz test
1 parent 41f0a00 commit 2bb77cd

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

test-server/java-tests/src/it/java/software/amazon/encryption/s3/RoundTripTests.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import java.nio.charset.StandardCharsets;
1616
import java.security.KeyPair;
1717
import java.security.KeyPairGenerator;
18+
import java.util.Base64;
1819
import java.util.HashMap;
1920
import java.util.List;
2021
import java.util.Map;
22+
import java.util.Random;
2123

2224
import com.amazonaws.services.s3.AmazonS3EncryptionClientV2;
2325
import com.amazonaws.services.s3.AmazonS3EncryptionV2;
@@ -28,6 +30,7 @@
2830
import org.junit.jupiter.params.provider.MethodSource;
2931
import org.opentest4j.TestAbortedException;
3032
import software.amazon.awssdk.core.ResponseBytes;
33+
import software.amazon.awssdk.core.sync.RequestBody;
3134
import software.amazon.awssdk.services.s3.S3Client;
3235
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
3336
import software.amazon.encryption.s3.TestUtils.LanguageServerTarget;
@@ -59,6 +62,87 @@ public static void setup() {
5962
validateServersRunning();
6063
}
6164

65+
/**
66+
* Verifies input validation via fuzzing of commitment parameters.
67+
* - Iterates multiple times with random garbage in critical metadata fields.
68+
* - Ensures client handles invalid input gracefully (throws exception, doesn't
69+
* crash).
70+
*/
71+
@ParameterizedTest(name = "{displayName}: Fuzzing {0}")
72+
@MethodSource("software.amazon.encryption.s3.TestUtils#improvedClientsForTest")
73+
public void testCommitmentParameterFuzzing(TestUtils.LanguageServerTarget target) throws Exception {
74+
S3ECTestServerClient testClient = TestUtils.testServerClientFor(target);
75+
final String objectKey = TestUtils.appendTestSuffix("fuzzing-" + target);
76+
final String testInput = "fuzzing metadata";
77+
KeyMaterial kmsKeyArn = KeyMaterial.builder().kmsKeyId(TestUtils.KMS_KEY_ARN).build();
78+
79+
// 1. Create Valid Object
80+
String clientId = testClient.createClient(CreateClientInput.builder()
81+
.config(S3ECConfig.builder()
82+
.keyMaterial(kmsKeyArn)
83+
.commitmentPolicy(CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
84+
.build())
85+
.build()).getClientId();
86+
87+
testClient.putObject(PutObjectInput.builder()
88+
.clientID(clientId)
89+
.bucket(TestUtils.BUCKET)
90+
.key(objectKey)
91+
.body(ByteBuffer.wrap(testInput.getBytes(StandardCharsets.UTF_8)))
92+
.build());
93+
94+
// 2. Get Original Metadata
95+
S3Client s3Client = S3Client.create();
96+
ResponseBytes<GetObjectResponse> objectBytes = s3Client
97+
.getObjectAsBytes(b -> b.bucket(TestUtils.BUCKET).key(objectKey));
98+
Map<String, String> originalMetadata = objectBytes.response().metadata();
99+
100+
// 3. Fuzzing Loop
101+
Random random = new Random();
102+
String[] fieldsToFuzz = { "x-amz-c", "x-amz-i", "x-amz-3" };
103+
104+
for (int i = 0; i < 20; i++) {
105+
String field = fieldsToFuzz[random.nextInt(fieldsToFuzz.length)];
106+
Map<String, String> fuzzedMetadata = new HashMap<>(originalMetadata);
107+
108+
// Generate random garbage
109+
byte[] garbage = new byte[random.nextInt(50) + 1];
110+
random.nextBytes(garbage);
111+
String garbageStr = Base64.getEncoder().encodeToString(garbage);
112+
113+
// Occasionally inject non-Base64 garbage
114+
if (random.nextBoolean()) {
115+
garbageStr = "INVALID_BASE64_!@#$%^&*()";
116+
}
117+
118+
fuzzedMetadata.put(field, garbageStr);
119+
120+
// Upload with fuzzed metadata
121+
s3Client.putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest.builder()
122+
.bucket(TestUtils.BUCKET)
123+
.key(objectKey) // Overwrite
124+
.metadata(fuzzedMetadata)
125+
.build(),
126+
RequestBody.fromBytes(objectBytes.asByteArray()));
127+
128+
// Attempt Decryption
129+
try {
130+
testClient.getObject(GetObjectInput.builder()
131+
.clientID(clientId)
132+
.bucket(TestUtils.BUCKET)
133+
.key(objectKey)
134+
.build());
135+
fail("Should fail with fuzzed metadata field: " + field);
136+
} catch (S3EncryptionClientError e) {
137+
// Expected
138+
}
139+
}
140+
141+
// cleanup
142+
s3Client.close();
143+
}
144+
145+
62146
@ParameterizedTest(name = "{displayName} for Encrypt: {0}, Decrypt: {1}")
63147
@MethodSource("software.amazon.encryption.s3.TestUtils#crossLanguageClients")
64148
public void crossLanguageTestKms(LanguageServerTarget encLang, LanguageServerTarget decLang) {

0 commit comments

Comments
 (0)