From 9bc2f22589a4b1dfe6ee627d14709b82b8f0cc23 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 08:56:08 +0700 Subject: [PATCH] fix: strip trailing slash in SigV4 canonical URI AWS SigV4 canonical URI must not have trailing slash (except root '/'). Bun can receive paths with trailing slash from SDK, causing signature mismatch for all bucket operations (CreateBucket, HeadBucket, etc.) Co-Authored-By: Claude Opus 5 (1M context) --- src/utils/s3/auth.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/utils/s3/auth.ts b/src/utils/s3/auth.ts index 8abf547..95f659e 100644 --- a/src/utils/s3/auth.ts +++ b/src/utils/s3/auth.ts @@ -1,5 +1,4 @@ import { timingSafeEqual } from 'node:crypto'; -import logger from '../../shared/logger/index'; /** * Timing-safe string comparison that prevents timing attacks. @@ -167,9 +166,9 @@ const normalizeUri = (uri: string): string => { result.push(segment); } - // Reconstruct path + // Reconstruct path (no trailing slash except root) const normalized = result.length > 0 ? `/${result.join('/')}` : '/'; - return normalized; + return normalized === '/' ? '/' : normalized.replace(/\/+$/, ''); }; const awsEncode = (value: string): string => @@ -300,15 +299,6 @@ export const verifySignature = async ( const hashedCanonicalRequest = await sha256Hex(canonicalRequest); - // Debug canonical request for non-root GETs (bucket operations) - logger.info('SigV4 canonical request', { - method, - path: parsedUrl.pathname, - signedHeaders: parsed.signedHeaders, - hashedPayload: hashedPayload.slice(0, 20) + '...', - canReq: canonicalRequest.slice(0, 500), - }); - // M1: Fall back to Date header if x-amz-date is missing const amzDate = headers['x-amz-date'] || headers['date'] || '';