diff --git a/ChangeLog.md b/ChangeLog.md index e61434b27..667995ba2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,7 @@ General: +- Fixed shared key authentication signature generation when x-ms-date header is present. - Updated lockfile-resolved `axios` from 1.19.0 to 1.20.0 for hardened runtime option handling; no application code changes required. - Updated lockfile-resolved `lint-staged` from 17.3.0 to 17.4.1 to pick up `picomatch` 4.0.7 and `tinyexec` 1.3.0; moved `.lintstagedrc` flat-format coverage into `tests/packageScripts.test.ts`. - Bumped `morgan` from `^1.11.0` to `^1.12.0` (lockfile resolved to 1.12.0) to remediate CVE-2026-15603 (log forging via Unicode line separators in access log tokens); no Azurite source code changes were required. diff --git a/src/blob/authentication/BlobSharedKeyAuthenticator.ts b/src/blob/authentication/BlobSharedKeyAuthenticator.ts index f8fbbbae1..2dcb9169a 100644 --- a/src/blob/authentication/BlobSharedKeyAuthenticator.ts +++ b/src/blob/authentication/BlobSharedKeyAuthenticator.ts @@ -83,7 +83,7 @@ export default class BlobSharedKeyAuthenticator implements IAuthenticator { this.getHeaderValueToSign(req, HeaderConstants.CONTENT_LENGTH), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE), + req.getHeader(HeaderConstants.X_MS_DATE) !== undefined ? "" : this.getHeaderValueToSign(req, HeaderConstants.DATE), this.getHeaderValueToSign(req, HeaderConstants.IF_MODIFIED_SINCE), this.getHeaderValueToSign(req, HeaderConstants.IF_MATCH), this.getHeaderValueToSign(req, HeaderConstants.IF_NONE_MATCH), @@ -151,7 +151,7 @@ export default class BlobSharedKeyAuthenticator implements IAuthenticator { this.getHeaderValueToSign(req, HeaderConstants.CONTENT_LENGTH), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE), + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) ? "" : this.getHeaderValueToSign(req, HeaderConstants.DATE), this.getHeaderValueToSign(req, HeaderConstants.IF_MODIFIED_SINCE), this.getHeaderValueToSign(req, HeaderConstants.IF_MATCH), this.getHeaderValueToSign(req, HeaderConstants.IF_NONE_MATCH), diff --git a/src/queue/authentication/QueueSharedKeyAuthenticator.ts b/src/queue/authentication/QueueSharedKeyAuthenticator.ts index 6c779fd6f..f6b9942ce 100644 --- a/src/queue/authentication/QueueSharedKeyAuthenticator.ts +++ b/src/queue/authentication/QueueSharedKeyAuthenticator.ts @@ -328,7 +328,7 @@ export default class QueueSharedKeyAuthenticator implements IAuthenticator { this.getHeaderValueToSign(req, HeaderConstants.CONTENT_LENGTH), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE), + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) ? "" : this.getHeaderValueToSign(req, HeaderConstants.DATE), this.getHeaderValueToSign(req, HeaderConstants.IF_MODIFIED_SINCE), this.getHeaderValueToSign(req, HeaderConstants.IF_MATCH), this.getHeaderValueToSign(req, HeaderConstants.IF_NONE_MATCH), @@ -344,7 +344,7 @@ export default class QueueSharedKeyAuthenticator implements IAuthenticator { req.getMethod().toUpperCase(), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE) + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) ? "" : this.getHeaderValueToSign(req, HeaderConstants.DATE) ].join("\n") + "\n" + this.getCanonicalizedHeadersString(req) diff --git a/src/table/authentication/TableSharedKeyAuthenticator.ts b/src/table/authentication/TableSharedKeyAuthenticator.ts index bbded03fd..25fa76e52 100644 --- a/src/table/authentication/TableSharedKeyAuthenticator.ts +++ b/src/table/authentication/TableSharedKeyAuthenticator.ts @@ -53,8 +53,8 @@ export default class TableSharedKeyAuthenticator implements IAuthenticator { req.getMethod().toUpperCase(), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE) || - this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) || + this.getHeaderValueToSign(req, HeaderConstants.DATE) ].join("\n") + "\n" + this.getCanonicalizedResourceString( @@ -111,8 +111,8 @@ export default class TableSharedKeyAuthenticator implements IAuthenticator { req.getMethod().toUpperCase(), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_MD5), this.getHeaderValueToSign(req, HeaderConstants.CONTENT_TYPE), - this.getHeaderValueToSign(req, HeaderConstants.DATE) || - this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) || + this.getHeaderValueToSign(req, HeaderConstants.DATE) ].join("\n") + "\n" + this.getCanonicalizedResourceString( diff --git a/src/table/authentication/TableSharedKeyLiteAuthenticator.ts b/src/table/authentication/TableSharedKeyLiteAuthenticator.ts index 91914a3ce..194b1bf7d 100644 --- a/src/table/authentication/TableSharedKeyLiteAuthenticator.ts +++ b/src/table/authentication/TableSharedKeyLiteAuthenticator.ts @@ -53,8 +53,8 @@ export default class TableSharedKeyLiteAuthenticator implements IAuthenticator { const stringToSign: string = [ - this.getHeaderValueToSign(req, HeaderConstants.DATE) || - this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) || + this.getHeaderValueToSign(req, HeaderConstants.DATE) ].join("\n") + "\n" + this.getCanonicalizedResourceString( @@ -108,8 +108,8 @@ export default class TableSharedKeyLiteAuthenticator implements IAuthenticator { // JS/.net Track2 SDK will generate stringToSign from IP style URI with "-secondary" in authenticationPath, so will also compare signature with this kind stringToSignconst stringToSign: string = const stringToSign_secondary: string = [ - this.getHeaderValueToSign(req, HeaderConstants.DATE) || - this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) + this.getHeaderValueToSign(req, HeaderConstants.X_MS_DATE) || + this.getHeaderValueToSign(req, HeaderConstants.DATE) ].join("\n") + "\n" + this.getCanonicalizedResourceString( diff --git a/tests/table/utils/table.entity.tests.utils.for.rest.ts b/tests/table/utils/table.entity.tests.utils.for.rest.ts index 21fd03aea..b7c83c001 100644 --- a/tests/table/utils/table.entity.tests.utils.for.rest.ts +++ b/tests/table/utils/table.entity.tests.utils.for.rest.ts @@ -52,8 +52,8 @@ export function createStringToSignForSharedKeyLite( ): string { const stringToSign: string = [ - getHeaderValueToSign(HeaderConstants.DATE, headers) || - getHeaderValueToSign(HeaderConstants.X_MS_DATE, headers) + getHeaderValueToSign(HeaderConstants.X_MS_DATE, headers) || + getHeaderValueToSign(HeaderConstants.DATE, headers) ].join("\n") + "\n" + getCanonicalizedResourceString(