From 80636b1e41760093ed3872ab554bd131c9e549a7 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 25 Mar 2025 07:31:55 +0000 Subject: [PATCH 1/5] Validate AWS signer region and service in tests Extends the predicate in `AwsCredentialsUtils` to verify that we are using a proper AWS v4 signature complete with the correct region and service, rather than just looking for the access key as a substring. --- .../RepositoryS3BasicCredentialsRestIT.java | 2 +- .../RepositoryS3RestReloadCredentialsIT.java | 7 +++- .../RepositoryS3SessionCredentialsRestIT.java | 2 +- .../repositories/s3/S3BlobContainer.java | 5 ++- .../s3/RepositoryS3ClientYamlTestSuiteIT.java | 2 +- ...ryEc2EnvironmentVariableCredentialsIT.java | 2 +- .../DiscoveryEc2KeystoreCredentialsIT.java | 2 +- ...coveryEc2KeystoreSessionCredentialsIT.java | 2 +- ...scoveryEc2SystemPropertyCredentialsIT.java | 2 +- .../java/fixture/aws/AwsCredentialsUtils.java | 34 ++++++++++++++----- .../main/java/fixture/s3/S3HttpFixture.java | 2 +- ...earchableSnapshotsCredentialsReloadIT.java | 7 +++- 12 files changed, 50 insertions(+), 19 deletions(-) diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java index 10901424512a3..cd17138a16fea 100644 --- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java +++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java @@ -33,7 +33,7 @@ public class RepositoryS3BasicCredentialsRestIT extends AbstractRepositoryS3Rest private static final String SECRET_KEY = PREFIX + "secret-key"; private static final String CLIENT = "basic_credentials_client"; - private static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, fixedAccessKey(ACCESS_KEY)); + private static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, fixedAccessKey(ACCESS_KEY, "*", "s3")); public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .module("repository-s3") diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java index 065d1c6c9ea27..0d133b30b5e39 100644 --- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java +++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java @@ -39,7 +39,12 @@ public class RepositoryS3RestReloadCredentialsIT extends ESRestTestCase { private static volatile String repositoryAccessKey; - public static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, mutableAccessKey(() -> repositoryAccessKey)); + public static final S3HttpFixture s3Fixture = new S3HttpFixture( + true, + BUCKET, + BASE_PATH, + mutableAccessKey(() -> repositoryAccessKey, "*", "s3") + ); private static final MutableSettingsProvider keystoreSettings = new MutableSettingsProvider(); diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java index a8009d594926f..c0b5aa989281c 100644 --- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java +++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java @@ -38,7 +38,7 @@ public class RepositoryS3SessionCredentialsRestIT extends AbstractRepositoryS3Re true, BUCKET, BASE_PATH, - fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN) + fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN, "*", "s3") ); public static ElasticsearchCluster cluster = ElasticsearchCluster.local() diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java index d7f5a6e6dfe36..591ef20513987 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java @@ -469,7 +469,10 @@ void executeSingleUpload( S3BlobStore.configureRequestForMetrics(putRequest, blobStore, Operation.PUT_OBJECT, purpose); try (AmazonS3Reference clientReference = s3BlobStore.clientReference()) { - SocketAccess.doPrivilegedVoid(() -> { clientReference.client().putObject(putRequest); }); + SocketAccess.doPrivilegedVoid(() -> { + // WIP + clientReference.client().putObject(putRequest); + }); } catch (final AmazonClientException e) { throw new IOException("Unable to upload object [" + blobName + "] using a single upload", e); } diff --git a/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java b/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java index 89919f0f3ddf1..c0b7b447f8860 100644 --- a/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java +++ b/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java @@ -36,7 +36,7 @@ public class RepositoryS3ClientYamlTestSuiteIT extends AbstractRepositoryS3Clien true, "bucket", "base_path_integration_tests", - fixedAccessKey(ACCESS_KEY) + fixedAccessKey(ACCESS_KEY, "*", "s3") ); public static ElasticsearchCluster cluster = ElasticsearchCluster.local() diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java index 7fc5a2b4bcfae..620aa3d9b7282 100644 --- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java +++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java @@ -29,7 +29,7 @@ public class DiscoveryEc2EnvironmentVariableCredentialsIT extends DiscoveryEc2Cl private static final String ACCESS_KEY = PREFIX + "-access-key"; private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture( - fixedAccessKey(ACCESS_KEY), + fixedAccessKey(ACCESS_KEY, REGION, "ec2"), DiscoveryEc2EnvironmentVariableCredentialsIT::getAvailableTransportEndpoints ); diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java index c198ae5903ad4..8721b944d87de 100644 --- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java +++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java @@ -29,7 +29,7 @@ public class DiscoveryEc2KeystoreCredentialsIT extends DiscoveryEc2ClusterFormat private static final String ACCESS_KEY = PREFIX + "-access-key"; private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture( - fixedAccessKey(ACCESS_KEY), + fixedAccessKey(ACCESS_KEY, REGION, "ec2"), DiscoveryEc2KeystoreCredentialsIT::getAvailableTransportEndpoints ); diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java index e26ca0889e7b5..5e38f80d22611 100644 --- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java +++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java @@ -30,7 +30,7 @@ public class DiscoveryEc2KeystoreSessionCredentialsIT extends DiscoveryEc2Cluste private static final String SESSION_TOKEN = PREFIX + "-session-token"; private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture( - fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN), + fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN, REGION, "ec2"), DiscoveryEc2KeystoreSessionCredentialsIT::getAvailableTransportEndpoints ); diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java index 28ca11696569b..745cd0a76b4ff 100644 --- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java +++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java @@ -29,7 +29,7 @@ public class DiscoveryEc2SystemPropertyCredentialsIT extends DiscoveryEc2Cluster private static final String ACCESS_KEY = PREFIX + "-access-key"; private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture( - fixedAccessKey(ACCESS_KEY), + fixedAccessKey(ACCESS_KEY, REGION, "ec2"), DiscoveryEc2SystemPropertyCredentialsIT::getAvailableTransportEndpoints ); diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java index 9000e06ca1350..5edebbfe86142 100644 --- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java +++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java @@ -26,24 +26,42 @@ public enum AwsCredentialsUtils { /** * @return an authorization predicate that ensures the access key matches the given values. */ - public static BiPredicate fixedAccessKey(String accessKey) { - return mutableAccessKey(() -> accessKey); + public static BiPredicate fixedAccessKey(String accessKey, String region, String service) { + return mutableAccessKey(() -> accessKey, region, service); } /** - * @return an authorization predicate that ensures the access key matches one supplied by the given supplier. + * @return an authorization predicate that ensures the authorization header matches the access key supplied by the given supplier, + * and the given region and service name. */ - public static BiPredicate mutableAccessKey(Supplier accessKeySupplier) { - return (authorizationHeader, sessionTokenHeader) -> authorizationHeader != null - && authorizationHeader.contains(accessKeySupplier.get()); + public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String service) { + return (authorizationHeader, sessionTokenHeader) -> { + if (authorizationHeader == null) { + return false; + } + + final var accessKey = accessKeySupplier.get(); + final var expectedPrefix = "AWS4-HMAC-SHA256 Credential=" + accessKey + "/"; + if (authorizationHeader.startsWith(expectedPrefix) == false) { + return false; + } + + if (region.equals("*")) { + // skip region validation; TODO eliminate this when region is fixed in all tests + return authorizationHeader.contains("/" + service + "/aws4_request, "); + } + + final var remainder = authorizationHeader.substring(expectedPrefix.length() + 8 /* YYYYMMDD not validated */); + return remainder.startsWith("/" + region + "/" + service + "/aws4_request, "); + }; } /** * @return an authorization predicate that ensures the access key and session token both match the given values. */ - public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken) { + public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken, String region, String service) { Objects.requireNonNull(sessionToken); - final var accessKeyPredicate = fixedAccessKey(accessKey); + final var accessKeyPredicate = fixedAccessKey(accessKey, region, service); return (authorizationHeader, sessionTokenHeader) -> accessKeyPredicate.test(authorizationHeader, sessionTokenHeader) && sessionToken.equals(sessionTokenHeader); } diff --git a/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java b/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java index 538c57bc2bdea..2cb9627d4a087 100644 --- a/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java +++ b/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java @@ -33,7 +33,7 @@ public class S3HttpFixture extends ExternalResource { private final BiPredicate authorizationPredicate; public S3HttpFixture(boolean enabled) { - this(enabled, "bucket", "base_path_integration_tests", fixedAccessKey("s3_test_access_key")); + this(enabled, "bucket", "base_path_integration_tests", fixedAccessKey("s3_test_access_key", "*", "s3")); } public S3HttpFixture(boolean enabled, String bucket, String basePath, BiPredicate authorizationPredicate) { diff --git a/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java b/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java index bb5df5d37dba3..5889140bf2bab 100644 --- a/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java +++ b/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java @@ -47,7 +47,12 @@ public class S3SearchableSnapshotsCredentialsReloadIT extends ESRestTestCase { private static volatile String repositoryAccessKey; - public static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, mutableAccessKey(() -> repositoryAccessKey)); + public static final S3HttpFixture s3Fixture = new S3HttpFixture( + true, + BUCKET, + BASE_PATH, + mutableAccessKey(() -> repositoryAccessKey, "*", "s3") + ); private static final MutableSettingsProvider keystoreSettings = new MutableSettingsProvider(); From 2bceca53faecb63419a3c8304f6e02814f2e059d Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 25 Mar 2025 07:59:54 +0000 Subject: [PATCH 2/5] Comments --- .../src/main/java/fixture/aws/AwsCredentialsUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java index 5edebbfe86142..a8e5cf0d6b9d9 100644 --- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java +++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java @@ -24,7 +24,7 @@ public enum AwsCredentialsUtils { ; /** - * @return an authorization predicate that ensures the access key matches the given values. + * @return an authorization predicate that ensures the authorization header matches the given access key, region and service name. */ public static BiPredicate fixedAccessKey(String accessKey, String region, String service) { return mutableAccessKey(() -> accessKey, region, service); @@ -32,7 +32,7 @@ public static BiPredicate fixedAccessKey(String accessKey, Strin /** * @return an authorization predicate that ensures the authorization header matches the access key supplied by the given supplier, - * and the given region and service name. + * and also matches the given region and service name. */ public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String service) { return (authorizationHeader, sessionTokenHeader) -> { @@ -57,7 +57,7 @@ public static BiPredicate mutableAccessKey(Supplier acce } /** - * @return an authorization predicate that ensures the access key and session token both match the given values. + * @return an authorization predicate that ensures the access key, session token, region and service name all match the given values. */ public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken, String region, String service) { Objects.requireNonNull(sessionToken); From ee224857cdceb4c6c7bf76367ad3b13edbea8f16 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 25 Mar 2025 08:02:32 +0000 Subject: [PATCH 3/5] Links --- .../src/main/java/fixture/aws/AwsCredentialsUtils.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java index a8e5cf0d6b9d9..956ae601cdbe3 100644 --- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java +++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java @@ -25,6 +25,7 @@ public enum AwsCredentialsUtils { /** * @return an authorization predicate that ensures the authorization header matches the given access key, region and service name. + * @see AWS v4 Signatures */ public static BiPredicate fixedAccessKey(String accessKey, String region, String service) { return mutableAccessKey(() -> accessKey, region, service); @@ -33,6 +34,7 @@ public static BiPredicate fixedAccessKey(String accessKey, Strin /** * @return an authorization predicate that ensures the authorization header matches the access key supplied by the given supplier, * and also matches the given region and service name. + * @see AWS v4 Signatures */ public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String service) { return (authorizationHeader, sessionTokenHeader) -> { @@ -58,6 +60,7 @@ public static BiPredicate mutableAccessKey(Supplier acce /** * @return an authorization predicate that ensures the access key, session token, region and service name all match the given values. + * @see AWS v4 Signatures */ public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken, String region, String service) { Objects.requireNonNull(sessionToken); From 30dfaabf696cc69e2e0efb23a68c2ce0aee5874e Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 25 Mar 2025 14:50:13 +0000 Subject: [PATCH 4/5] Review feedback --- .../repositories/s3/S3BlobContainer.java | 5 +--- .../java/fixture/aws/AwsCredentialsUtils.java | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java index 591ef20513987..6963e329ddc86 100644 --- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java +++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java @@ -469,10 +469,7 @@ void executeSingleUpload( S3BlobStore.configureRequestForMetrics(putRequest, blobStore, Operation.PUT_OBJECT, purpose); try (AmazonS3Reference clientReference = s3BlobStore.clientReference()) { - SocketAccess.doPrivilegedVoid(() -> { - // WIP - clientReference.client().putObject(putRequest); - }); + SocketAccess.doPrivilegedVoid(() -> clientReference.client().putObject(putRequest)); } catch (final AmazonClientException e) { throw new IOException("Unable to upload object [" + blobName + "] using a single upload", e); } diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java index 956ae601cdbe3..6247b918defea 100644 --- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java +++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java @@ -26,17 +26,19 @@ public enum AwsCredentialsUtils { /** * @return an authorization predicate that ensures the authorization header matches the given access key, region and service name. * @see AWS v4 Signatures + * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter */ - public static BiPredicate fixedAccessKey(String accessKey, String region, String service) { - return mutableAccessKey(() -> accessKey, region, service); + public static BiPredicate fixedAccessKey(String accessKey, String region, String serviceName) { + return mutableAccessKey(() -> accessKey, region, serviceName); } /** * @return an authorization predicate that ensures the authorization header matches the access key supplied by the given supplier, * and also matches the given region and service name. * @see AWS v4 Signatures + * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter */ - public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String service) { + public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String serviceName) { return (authorizationHeader, sessionTokenHeader) -> { if (authorizationHeader == null) { return false; @@ -50,21 +52,27 @@ public static BiPredicate mutableAccessKey(Supplier acce if (region.equals("*")) { // skip region validation; TODO eliminate this when region is fixed in all tests - return authorizationHeader.contains("/" + service + "/aws4_request, "); + return authorizationHeader.contains("/" + serviceName + "/aws4_request, "); } - final var remainder = authorizationHeader.substring(expectedPrefix.length() + 8 /* YYYYMMDD not validated */); - return remainder.startsWith("/" + region + "/" + service + "/aws4_request, "); + final var remainder = authorizationHeader.substring(expectedPrefix.length() + "YYYYMMDD".length() /* date not validated */); + return remainder.startsWith("/" + region + "/" + serviceName + "/aws4_request, "); }; } /** * @return an authorization predicate that ensures the access key, session token, region and service name all match the given values. * @see AWS v4 Signatures + * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter */ - public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken, String region, String service) { + public static BiPredicate fixedAccessKeyAndToken( + String accessKey, + String sessionToken, + String region, + String serviceName + ) { Objects.requireNonNull(sessionToken); - final var accessKeyPredicate = fixedAccessKey(accessKey, region, service); + final var accessKeyPredicate = fixedAccessKey(accessKey, region, serviceName); return (authorizationHeader, sessionTokenHeader) -> accessKeyPredicate.test(authorizationHeader, sessionTokenHeader) && sessionToken.equals(sessionTokenHeader); } From 108126e0d79d77a752ecfae4bc553eb54c164bc5 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 25 Mar 2025 14:53:07 +0000 Subject: [PATCH 5/5] Tweak comment --- .../src/main/java/fixture/aws/AwsCredentialsUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java index 6247b918defea..aab6504f2d8c3 100644 --- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java +++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java @@ -55,7 +55,7 @@ public static BiPredicate mutableAccessKey(Supplier acce return authorizationHeader.contains("/" + serviceName + "/aws4_request, "); } - final var remainder = authorizationHeader.substring(expectedPrefix.length() + "YYYYMMDD".length() /* date not validated */); + final var remainder = authorizationHeader.substring(expectedPrefix.length() + "YYYYMMDD".length() /* skip over date field */); return remainder.startsWith("/" + region + "/" + serviceName + "/aws4_request, "); }; }