diff --git a/docs/README.md b/docs/README.md index f1d68a3cd1..7c4823d972 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1494,6 +1494,8 @@ operation. Count) Header Parameter value. The PBKDF2 iteration count defines the algorithm's computational expense. **Default:** '10000' + - `inflateRawSyncLimit`: `number` Limits compressed JWE plaintext output size. + **Default:** '250000' - `complete`: `` When true returns an object with the parsed headers, verified AAD, the content encryption key, the key that was used to unwrap or derive the content encryption key, and cleartext instead of only the cleartext. diff --git a/lib/jwe/decrypt.js b/lib/jwe/decrypt.js index 9da8aead45..358d084b95 100644 --- a/lib/jwe/decrypt.js +++ b/lib/jwe/decrypt.js @@ -52,7 +52,7 @@ const validateAlgorithms = (algorithms, option) => { /* * @public */ -const jweDecrypt = (skipValidateHeaders, serialization, jwe, key, { crit = [], complete = false, keyManagementAlgorithms, contentEncryptionAlgorithms, maxPBES2Count = 10000 } = {}) => { +const jweDecrypt = (skipValidateHeaders, serialization, jwe, key, { crit = [], complete = false, keyManagementAlgorithms, contentEncryptionAlgorithms, maxPBES2Count = 10000, inflateRawSyncLimit = 250000 } = {}) => { key = getKey(key, true) keyManagementAlgorithms = validateAlgorithms(keyManagementAlgorithms, 'keyManagementAlgorithms') @@ -189,7 +189,7 @@ const jweDecrypt = (skipValidateHeaders, serialization, jwe, key, { crit = [], c let cleartext = decrypt(enc, cek, base64url.decodeToBuffer(ciphertext), { iv, tag, aad: adata }) if (opts.zip) { - cleartext = inflateRawSync(cleartext) + cleartext = inflateRawSync(cleartext, { maxOutputLength: inflateRawSyncLimit }) } if (complete) { diff --git a/test/jwe/sanity.test.js b/test/jwe/sanity.test.js index fd8a083742..e83d8c787c 100644 --- a/test/jwe/sanity.test.js +++ b/test/jwe/sanity.test.js @@ -1,4 +1,5 @@ const test = require('ava') +const crypto = require('crypto') const base64url = require('../../lib/help/base64url') const { JWKS, JWK: { generateSync }, JWE, errors } = require('../..') @@ -616,3 +617,25 @@ if (!('electron' in process.versions)) { }, { instanceOf: errors.JWEInvalid, message: 'JOSE Header "p2c" (PBES2 Count) out is of acceptable bounds' }) }) } + +test('Compressed JWE output length limit', t => { + const k = generateSync('oct', 256) + { + const jwe = JWE.encrypt(crypto.randomBytes(250000), k, { alg: 'dir', enc: 'A128CBC-HS256', zip: 'DEF' }) + t.notThrows(() => { + JWE.decrypt(jwe, k) + }) + } + { + const jwe = JWE.encrypt(crypto.randomBytes(250000 + 1), k, { alg: 'dir', enc: 'A128CBC-HS256', zip: 'DEF' }) + t.throws(() => { + JWE.decrypt(jwe, k) + }) + } + { + const jwe = JWE.encrypt(crypto.randomBytes(1001), k, { alg: 'dir', enc: 'A128CBC-HS256', zip: 'DEF' }) + t.throws(() => { + JWE.decrypt(jwe, k, { inflateRawSyncLimit: 1000 }) + }) + } +}) diff --git a/types/index.d.ts b/types/index.d.ts index 30e146a019..ec33082208 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -402,6 +402,7 @@ export namespace JWE { contentEncryptionAlgorithms?: string[]; keyManagementAlgorithms?: string[]; maxPBES2Count?: number; + inflateRawSyncLimit?: number; } interface completeDecrypt {