From f722c4aa59a359fa6ce7eb3a636b1b0baf2a93f9 Mon Sep 17 00:00:00 2001 From: Julien Vanier Date: Wed, 11 Mar 2026 14:02:01 -0400 Subject: [PATCH] Limit to 100 env vars per layer --- lib/moduleEncoding.js | 12 +++++++++--- specs/lib/moduleEncoding.spec.js | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/moduleEncoding.js b/lib/moduleEncoding.js index c26c566..34e6437 100644 --- a/lib/moduleEncoding.js +++ b/lib/moduleEncoding.js @@ -28,6 +28,7 @@ const ENV_ASSET_NAME = 'env'; const ENV_JSON_FILE = 'env.json'; const MAX_ENV_SIZE = 16 * 1024; +const MAX_ENV_VARS = 100; function moduleFunctionToString(func) { switch (func) { @@ -1683,12 +1684,16 @@ async function createProtectedModule(module, certificate) { * @param {String|Number} snapshot.updatedAt Snapshot creation time. Can be a string in a format * supported by `Date.parse()` or a numeric timestamp. * @param {Number} [maxSize=MAX_ENV_SIZE] Maximum allowed size of the resulting module. + * @param {Number} [maxVars=MAX_ENV_VARS] Maximum allowed number of variables in the resulting module. * @returns {Promise} Asset data. */ -async function encodeEnvVarsAsset(vars, snapshot = undefined, maxSize = MAX_ENV_SIZE) { +async function encodeEnvVarsAsset(vars, snapshot = undefined, maxSize = MAX_ENV_SIZE, maxVars = MAX_ENV_VARS) { if (!vars || typeof vars !== 'object') { throw new Error('Expected variable values to be an object'); } + if (Object.keys(vars).length > maxVars) { + throw new Error(`Number of variables exceeds the maximum of ${maxVars}`); + } if (JSON.stringify(vars).length > maxSize) { throw new Error('Asset exceeds the maximum size'); } @@ -1745,9 +1750,10 @@ async function encodeEnvVarsAsset(vars, snapshot = undefined, maxSize = MAX_ENV_ * @param {String|Number} snapshot.updatedAt Snapshot creation time. Can be a string in a format * supported by `Date.parse()` or a numeric timestamp. * @param {Number} [maxSize=MAX_ENV_SIZE] Maximum allowed size of the resulting module. + * @param {Number} [maxVars=MAX_ENV_VARS] Maximum allowed number of variables in the resulting module. * @returns {Promise} Module binary. */ -async function createEnvVarsAssetModule(vars, snapshot = undefined, maxSize = MAX_ENV_SIZE) { +async function createEnvVarsAssetModule(vars, snapshot = undefined, maxSize = MAX_ENV_SIZE, maxVars = MAX_ENV_VARS) { let assetData; if (Buffer.isBuffer(vars)) { if (snapshot) { @@ -1755,7 +1761,7 @@ async function createEnvVarsAssetModule(vars, snapshot = undefined, maxSize = MA } assetData = vars; } else { - assetData = await encodeEnvVarsAsset(vars, snapshot, maxSize); + assetData = await encodeEnvVarsAsset(vars, snapshot, maxSize, maxVars); } const assetModule = await createAssetModule(assetData, ENV_ASSET_NAME, { diff --git a/specs/lib/moduleEncoding.spec.js b/specs/lib/moduleEncoding.spec.js index 5f921e6..a9b8072 100644 --- a/specs/lib/moduleEncoding.spec.js +++ b/specs/lib/moduleEncoding.spec.js @@ -1039,6 +1039,16 @@ describe('moduleEncoding', () => { const msg = 'Asset exceeds the maximum size'; await expect(createEnvVarsAssetModule({ 'ABC': '1'.repeat(20000) })).to.be.eventually.rejectedWith(Error, msg); }); + + + it('asset exceeds the maximum number of variables', async () => { + const msg = 'Number of variables exceeds the maximum of 100'; + const vars = {}; + for (let i = 0; i < 101; i++) { + vars['VAR' + i] = 'value'; + } + await expect(createEnvVarsAssetModule(vars)).to.be.eventually.rejectedWith(Error, msg); + }); }); }); });