From ea3774a8163dd5b646e2549066746c745422ccdd Mon Sep 17 00:00:00 2001 From: Rich Gowman Date: Fri, 18 Oct 2019 15:22:59 -0400 Subject: [PATCH 1/2] Reject rounds=0 for SHA1 hashes Port of https://github.com/firebase/firebase-tools/pull/1701 --- src/auth/user-import-builder.ts | 16 ++++++++++++ test/integration/auth.spec.ts | 2 +- test/unit/auth/user-import-builder.spec.ts | 30 +++++++++++++++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index f538bb6489..d35c90ecd7 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -344,6 +344,22 @@ export class UserImportBuilder { case 'SHA1': case 'SHA256': case 'SHA512': + // MD5 is [0,8192] but SHA1, SHA256, and SHA512 are [1,8192] + rounds = getNumberField(options.hash, 'rounds'); + const minRounds = options.hash.algorithm === 'MD5' ? 0 : 1; + if (isNaN(rounds) || rounds < minRounds || rounds > 8192) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_HASH_ROUNDS, + `A valid "hash.rounds" number between ${minRounds} and 8192 must be provided for ` + + `hash algorithm ${options.hash.algorithm}.`, + ); + } + populatedOptions = { + hashAlgorithm: options.hash.algorithm, + rounds, + }; + break; + case 'PBKDF_SHA1': case 'PBKDF2_SHA256': rounds = getNumberField(options.hash, 'rounds'); diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 58c45023a9..0f0157c131 100755 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1331,7 +1331,7 @@ describe('admin.auth', () => { importOptions: { hash: { algorithm: 'SHA256', - rounds: 0, + rounds: 1, }, } as any, computePasswordHash: (userImportTest: UserImportTest): Buffer => { diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 54861f3652..cdd3b2d470 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -207,12 +207,34 @@ describe('UserImportBuilder', () => { md5ShaPbkdfAlgorithms.forEach((algorithm) => { describe(`${algorithm}`, () => { - const invalidRounds = [-1, 120001, 'invalid', undefined, null]; + let minRounds: number; + let maxRounds: number; + switch (algorithm) { + case 'MD5': + minRounds = 0; + maxRounds = 8192; + break; + case 'SHA1': + case 'SHA256': + case 'SHA512': + minRounds = 1; + maxRounds = 8192; + break; + case 'PBKDF_SHA1': + case 'PBKDF2_SHA256': + minRounds = 0; + maxRounds = 120000; + break; + default: + throw new Error('Unexpected algorith: ' + algorithm); + } + const invalidRounds = [minRounds - 1, maxRounds + 1, 'invalid', undefined, null]; + invalidRounds.forEach((rounds) => { it(`should throw when ${JSON.stringify(rounds)} rounds provided`, () => { const expectedError = new FirebaseAuthError( AuthClientErrorCode.INVALID_HASH_ROUNDS, - `A valid "hash.rounds" number between 0 and 120000 must be provided for ` + + `A valid "hash.rounds" number between ${minRounds} and ${maxRounds} must be provided for ` + `hash algorithm ${algorithm}.`, ); const invalidOptions = { @@ -231,12 +253,12 @@ describe('UserImportBuilder', () => { const validOptions = { hash: { algorithm, - rounds: 120000, + rounds: maxRounds, }, }; const expectedRequest = { hashAlgorithm: algorithm, - rounds: 120000, + rounds: maxRounds, users: expectedUsersRequest, }; const userImportBuilder = From 92aa6b8a41cbea7940171d529957429420fe2aac Mon Sep 17 00:00:00 2001 From: Rich Gowman Date: Wed, 23 Oct 2019 08:40:42 -0400 Subject: [PATCH 2/2] typo --- test/unit/auth/user-import-builder.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index cdd3b2d470..58b100d059 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -226,7 +226,7 @@ describe('UserImportBuilder', () => { maxRounds = 120000; break; default: - throw new Error('Unexpected algorith: ' + algorithm); + throw new Error('Unexpected algorithm: ' + algorithm); } const invalidRounds = [minRounds - 1, maxRounds + 1, 'invalid', undefined, null];