From 7aa09a2ee782c7ab5e58e22dcbbc4ec76e92ea95 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Sun, 30 Aug 2026 23:16:57 -0400 Subject: [PATCH] fix(mobile): bound gzip package chunk decoding --- .../mobile-web/mobile-web-package-chunk-decoder.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mobile/src/mobile-web/mobile-web-package-chunk-decoder.ts b/mobile/src/mobile-web/mobile-web-package-chunk-decoder.ts index 3720bea622f..74eb9e7e557 100644 --- a/mobile/src/mobile-web/mobile-web-package-chunk-decoder.ts +++ b/mobile/src/mobile-web/mobile-web-package-chunk-decoder.ts @@ -52,6 +52,9 @@ export function decodeGzipMobileWebPackageChunk( ) { return null } + if (expectedLength > MOBILE_WEB_PACKAGE_CHUNK_BYTES) { + return null + } const compressed = decodeCanonicalBase64(chunk.data.dataBase64) if ( !compressed || @@ -61,10 +64,10 @@ export function decodeGzipMobileWebPackageChunk( return null } try { - const bytes = gunzipSync(compressed) - return bytes.byteLength === expectedLength && bytes.byteLength <= MOBILE_WEB_PACKAGE_CHUNK_BYTES - ? bytes - : null + // Reserve one sentinel byte so expansion beyond the advertised size is rejected without an + // attacker-controlled allocation. + const bytes = gunzipSync(compressed, { out: new Uint8Array(expectedLength + 1) }) + return bytes.byteLength === expectedLength ? bytes : null } catch { return null }