Skip to content

Commit e468700

Browse files
committed
CLDSRV-898: stop treating x-amz-checksum-algorithm/type as checksum digests
1 parent ff5b400 commit e468700

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

lib/api/apiUtils/integrity/validateChecksums.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,12 @@ const algorithms = Object.freeze({
172172
* null on success; otherwise a ChecksumError with details.
173173
*/
174174
async function validateXAmzChecksums(headers, body) {
175-
const checksumHeaders = Object.keys(headers).filter(header => header.startsWith('x-amz-checksum-'));
175+
const checksumHeaders = Object.keys(headers).filter(
176+
header =>
177+
header.startsWith('x-amz-checksum-') &&
178+
header !== 'x-amz-checksum-type' &&
179+
header !== 'x-amz-checksum-algorithm',
180+
);
176181
const xAmzChecksumCnt = checksumHeaders.length;
177182
if (xAmzChecksumCnt > 1) {
178183
return { error: ChecksumError.MultipleChecksumTypes, details: { algorithms: checksumHeaders } };
@@ -256,7 +261,12 @@ function getChecksumDataFromHeaders(headers) {
256261
return null;
257262
};
258263

259-
const checksumHeaders = Object.keys(headers).filter(header => header.startsWith('x-amz-checksum-'));
264+
const checksumHeaders = Object.keys(headers).filter(
265+
header =>
266+
header.startsWith('x-amz-checksum-') &&
267+
header !== 'x-amz-checksum-type' &&
268+
header !== 'x-amz-checksum-algorithm',
269+
);
260270
const xAmzChecksumCnt = checksumHeaders.length;
261271
if (xAmzChecksumCnt > 1) {
262272
return { error: ChecksumError.MultipleChecksumTypes, details: { algorithms: checksumHeaders } };

tests/unit/api/apiUtils/integrity/validateChecksums.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,40 @@ describe('validateChecksumsNoChunking CRC32, CRC32C, SHA1, SHA256, CRC64NVME', (
234234
assert.deepStrictEqual(result.details.algorithms, ['x-amz-checksum-sha1', 'x-amz-checksum-sha256']);
235235
});
236236

237+
it('should ignore x-amz-checksum-algorithm alongside a valid x-amz-checksum-<algo> value', async () => {
238+
const body = 'sha256 data';
239+
const headers = {
240+
'content-type': 'application/json',
241+
'x-amz-checksum-algorithm': 'SHA256',
242+
'x-amz-checksum-sha256': 'jS/UevcoKxbM33kmPFujS72ior/9/i374VmGvbTAwAc=',
243+
};
244+
const result = await validateChecksumsNoChunking(headers, body);
245+
assert.ifError(result);
246+
});
247+
248+
it('should ignore x-amz-checksum-type alongside a valid x-amz-checksum-<algo> value', async () => {
249+
const body = 'sha256 data';
250+
const headers = {
251+
'content-type': 'application/json',
252+
'x-amz-checksum-type': 'FULL_OBJECT',
253+
'x-amz-checksum-sha256': 'jS/UevcoKxbM33kmPFujS72ior/9/i374VmGvbTAwAc=',
254+
};
255+
const result = await validateChecksumsNoChunking(headers, body);
256+
assert.ifError(result);
257+
});
258+
259+
it('should ignore both x-amz-checksum-algorithm and x-amz-checksum-type when combined with a value', async () => {
260+
const body = 'sha256 data';
261+
const headers = {
262+
'content-type': 'application/json',
263+
'x-amz-checksum-algorithm': 'SHA256',
264+
'x-amz-checksum-type': 'FULL_OBJECT',
265+
'x-amz-checksum-sha256': 'jS/UevcoKxbM33kmPFujS72ior/9/i374VmGvbTAwAc=',
266+
};
267+
const result = await validateChecksumsNoChunking(headers, body);
268+
assert.ifError(result);
269+
});
270+
237271
for (const algo of algos) {
238272
it('should return error AlgoNotSupported if x-amz-sdk-checksum-algorithm algo not supported', async () => {
239273
const headers = {
@@ -591,6 +625,31 @@ describe('getChecksumDataFromHeaders', () => {
591625
assert.strictEqual(result.error, ChecksumError.MultipleChecksumTypes);
592626
});
593627

628+
it('should ignore x-amz-checksum-algorithm alongside a valid x-amz-checksum-<algo> value', () => {
629+
const result = getChecksumDataFromHeaders({
630+
'x-amz-checksum-algorithm': 'SHA256',
631+
'x-amz-checksum-sha256': validDigests.sha256,
632+
});
633+
assert.deepStrictEqual(result, { algorithm: 'sha256', isTrailer: false, expected: validDigests.sha256 });
634+
});
635+
636+
it('should ignore x-amz-checksum-type alongside a valid x-amz-checksum-<algo> value', () => {
637+
const result = getChecksumDataFromHeaders({
638+
'x-amz-checksum-type': 'FULL_OBJECT',
639+
'x-amz-checksum-sha256': validDigests.sha256,
640+
});
641+
assert.deepStrictEqual(result, { algorithm: 'sha256', isTrailer: false, expected: validDigests.sha256 });
642+
});
643+
644+
it('should ignore both x-amz-checksum-algorithm and x-amz-checksum-type when combined with a value', () => {
645+
const result = getChecksumDataFromHeaders({
646+
'x-amz-checksum-algorithm': 'SHA256',
647+
'x-amz-checksum-type': 'FULL_OBJECT',
648+
'x-amz-checksum-sha256': validDigests.sha256,
649+
});
650+
assert.deepStrictEqual(result, { algorithm: 'sha256', isTrailer: false, expected: validDigests.sha256 });
651+
});
652+
594653
it('should return MissingCorresponding when x-amz-sdk-checksum-algorithm has no x-amz-checksum- or trailer', () => {
595654
const result = getChecksumDataFromHeaders({ 'x-amz-sdk-checksum-algorithm': 'crc32' });
596655
assert.strictEqual(result.error, ChecksumError.MissingCorresponding);

0 commit comments

Comments
 (0)