Skip to content

Commit 75d7282

Browse files
committed
fix(storage): use unsigned payload for pre-signed urls
1 parent 7d61814 commit 75d7282

File tree

4 files changed

+39
-15
lines changed

4 files changed

+39
-15
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ packages/**/esm/
1111
packages/**/cjs/
1212
**/.DS_Store
1313
.vscode
14+
.kiro
1415
.idea
1516
*.log
1617
.npm/

packages/core/src/clients/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ export {
1313
PresignUrlOptions,
1414
SignRequestOptions,
1515
} from './middleware/signing/signer/signatureV4';
16-
export { EMPTY_HASH as EMPTY_SHA256_HASH } from './middleware/signing/signer/signatureV4/constants';
16+
export {
17+
EMPTY_HASH as EMPTY_SHA256_HASH,
18+
UNSIGNED_PAYLOAD,
19+
} from './middleware/signing/signer/signatureV4/constants';
1720
export { extendedEncodeURIComponent } from './middleware/signing/utils/extendedEncodeURIComponent';
1821
export {
1922
signingMiddlewareFactory,

packages/storage/__tests__/providers/s3/utils/client/S3/getPresignedGetObjectUrl.test.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import { presignUrl } from '@aws-amplify/core/internals/aws-client-utils';
4+
import {
5+
UNSIGNED_PAYLOAD,
6+
presignUrl,
7+
} from '@aws-amplify/core/internals/aws-client-utils';
58

69
import { getPresignedGetObjectUrl } from '../../../../../../src/providers/s3/utils/client/s3data';
710

@@ -42,9 +45,6 @@ describe('serializeGetObjectRequest', () => {
4245
);
4346
expect(actualUrl.pathname).toEqual('/key');
4447
expect(actualUrl.searchParams.get('X-Amz-Expires')).toEqual('900');
45-
expect(actualUrl.searchParams.get('x-amz-content-sha256')).toEqual(
46-
expect.any(String),
47-
);
4848
expect(actualUrl.searchParams.get('x-amz-user-agent')).toEqual('UA');
4949
});
5050

@@ -99,9 +99,6 @@ describe('serializeGetObjectRequest', () => {
9999
);
100100

101101
expect(actual.searchParams.get('X-Amz-Expires')).toBe('900');
102-
expect(actual.searchParams.get('x-amz-content-sha256')).toEqual(
103-
expect.any(String),
104-
);
105102
expect(actual.searchParams.get('response-content-disposition')).toBe(
106103
'attachment; filename="filename.jpg"',
107104
);
@@ -110,4 +107,32 @@ describe('serializeGetObjectRequest', () => {
110107
);
111108
expect(actual.searchParams.get('x-amz-user-agent')).toBe('UA');
112109
});
110+
111+
it('should use UNSIGNED-PAYLOAD for presigned URLs', async () => {
112+
mockPresignUrl.mockClear();
113+
114+
const result = await getPresignedGetObjectUrl(
115+
{
116+
...defaultConfigWithStaticCredentials,
117+
signingRegion: defaultConfigWithStaticCredentials.region,
118+
signingService: 's3',
119+
expiration: 900,
120+
},
121+
{
122+
Bucket: 'bucket',
123+
Key: 'key',
124+
},
125+
);
126+
127+
// Verify UNSIGNED-PAYLOAD is used in the signature calculation
128+
expect(mockPresignUrl).toHaveBeenCalledWith(
129+
expect.objectContaining({
130+
body: UNSIGNED_PAYLOAD,
131+
}),
132+
expect.anything(),
133+
);
134+
135+
// Verify x-amz-content-sha256 is NOT in the presigned URL query parameters
136+
expect(result.searchParams.get('x-amz-content-sha256')).toBeNull();
137+
});
113138
});

packages/storage/src/providers/s3/utils/client/s3data/getObject.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import {
5-
EMPTY_SHA256_HASH,
65
Endpoint,
76
HttpRequest,
87
HttpResponse,
98
PresignUrlOptions,
9+
UNSIGNED_PAYLOAD,
1010
UserAgentOptions,
1111
parseMetadata,
1212
presignUrl,
@@ -18,7 +18,6 @@ import {
1818
} from '@aws-amplify/core/internals/utils';
1919

2020
import {
21-
CONTENT_SHA256_HEADER,
2221
assignStringVariables,
2322
buildStorageServiceError,
2423
deserializeBoolean,
@@ -172,10 +171,6 @@ export const getPresignedGetObjectUrl = async (
172171
const endpoint = defaultConfig.endpointResolver(config, input);
173172
const { url, headers, method } = await getObjectSerializer(input, endpoint);
174173

175-
// TODO: set content sha256 query parameter with value of UNSIGNED-PAYLOAD instead of empty hash.
176-
// It requires changes in presignUrl. Without this change, the generated url still works,
177-
// but not the same as other tools like AWS SDK and CLI.
178-
url.searchParams.append(CONTENT_SHA256_HEADER, EMPTY_SHA256_HASH);
179174
if (config.userAgentValue) {
180175
url.searchParams.append(
181176
config.userAgentHeader ?? USER_AGENT_HEADER,
@@ -199,7 +194,7 @@ export const getPresignedGetObjectUrl = async (
199194
}
200195

201196
return presignUrl(
202-
{ method, url, body: undefined },
197+
{ method, url, body: UNSIGNED_PAYLOAD },
203198
{
204199
signingService: defaultConfig.service,
205200
signingRegion: config.region,

0 commit comments

Comments
 (0)