From 8c2d24ee400bc4567335e97ee6004c3baa6ef66f Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Thu, 4 Nov 2021 18:05:31 +0300 Subject: [PATCH 1/4] fix: base64 generation and unicode characters (#197) --- lib/getHashDigest.js | 10 ++++-- lib/hash/BatchedHash.js | 64 ++++++++++++++++++++++++++++++++++++ lib/hash/wasm-hash.js | 2 +- test/getHashDigest.test.js | 4 +-- test/interpolateName.test.js | 10 +++--- 5 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 lib/hash/BatchedHash.js diff --git a/lib/getHashDigest.js b/lib/getHashDigest.js index 820ae1d..7098f06 100644 --- a/lib/getHashDigest.js +++ b/lib/getHashDigest.js @@ -40,6 +40,7 @@ function encodeBufferToBase(buffer, base) { } let createMd4 = undefined; +let BatchedHash = undefined; function getHashDigest(buffer, hashType, digestType, maxLength) { hashType = hashType || 'md4'; @@ -53,9 +54,13 @@ function getHashDigest(buffer, hashType, digestType, maxLength) { if (error.code === 'ERR_OSSL_EVP_UNSUPPORTED' && hashType === 'md4') { if (createMd4 === undefined) { createMd4 = require('./hash/md4'); + + if (BatchedHash === undefined) { + BatchedHash = require('./hash/BatchedHash'); + } } - hash = createMd4(); + hash = new BatchedHash(createMd4()); } if (!hash) { @@ -72,8 +77,7 @@ function getHashDigest(buffer, hashType, digestType, maxLength) { digestType === 'base49' || digestType === 'base52' || digestType === 'base58' || - digestType === 'base62' || - digestType === 'base64' + digestType === 'base62' ) { return encodeBufferToBase(hash.digest(), digestType.substr(4)).substr( 0, diff --git a/lib/hash/BatchedHash.js b/lib/hash/BatchedHash.js new file mode 100644 index 0000000..6ec6a44 --- /dev/null +++ b/lib/hash/BatchedHash.js @@ -0,0 +1,64 @@ +const MAX_SHORT_STRING = require('./wasm-hash').MAX_SHORT_STRING; + +class BatchedHash { + constructor(hash) { + this.string = undefined; + this.encoding = undefined; + this.hash = hash; + } + + /** + * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding} + * @param {string|Buffer} data data + * @param {string=} inputEncoding data encoding + * @returns {this} updated hash + */ + update(data, inputEncoding) { + if (this.string !== undefined) { + if ( + typeof data === 'string' && + inputEncoding === this.encoding && + this.string.length + data.length < MAX_SHORT_STRING + ) { + this.string += data; + + return this; + } + + this.hash.update(this.string, this.encoding); + this.string = undefined; + } + + if (typeof data === 'string') { + if ( + data.length < MAX_SHORT_STRING && + // base64 encoding is not valid since it may contain padding chars + (!inputEncoding || !inputEncoding.startsWith('ba')) + ) { + this.string = data; + this.encoding = inputEncoding; + } else { + this.hash.update(data, inputEncoding); + } + } else { + this.hash.update(data); + } + + return this; + } + + /** + * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding} + * @param {string=} encoding encoding of the return value + * @returns {string|Buffer} digest + */ + digest(encoding) { + if (this.string !== undefined) { + this.hash.update(this.string, this.encoding); + } + + return this.hash.digest(encoding); + } +} + +module.exports = BatchedHash; diff --git a/lib/hash/wasm-hash.js b/lib/hash/wasm-hash.js index c2c2bd6..d8f2817 100644 --- a/lib/hash/wasm-hash.js +++ b/lib/hash/wasm-hash.js @@ -82,7 +82,7 @@ class WasmHash { endPos += 2; } else { // bail-out for weird chars - endPos += mem.write(data.slice(endPos), endPos, encoding); + endPos += mem.write(data.slice(i), endPos, encoding); break; } } diff --git a/test/getHashDigest.test.js b/test/getHashDigest.test.js index 28f2fc3..9fa1355 100644 --- a/test/getHashDigest.test.js +++ b/test/getHashDigest.test.js @@ -12,7 +12,7 @@ describe('getHashDigest()', () => { '6f8db599de986fab7a21625b7916589c', ], ['test string', 'md5', 'hex', 4, '6f8d'], - ['test string', 'md5', 'base64', undefined, '2sm1pVmS8xuGJLCdWpJoRL'], + ['test string', 'md5', 'base64', undefined, 'b421md6Yb6t6IWJbeRZYnA=='], ['test string', 'md5', 'base52', undefined, 'dJnldHSAutqUacjgfBQGLQx'], ['test string', 'md5', 'base26', 6, 'bhtsgu'], [ @@ -20,7 +20,7 @@ describe('getHashDigest()', () => { 'sha512', 'base64', undefined, - '2IS-kbfIPnVflXb9CzgoNESGCkvkb0urMmucPD9z8q6HuYz8RShY1-tzSUpm5-Ivx_u4H1MEzPgAhyhaZ7RKog', + 'EObWR69EYkRC84jCwUp4f/ixfmFluD12fsBHdo2MvLcaGjIm58x4Frx5wEJ9lKnaaIxBo5kse/Xk18w+C+XbrA==', ], [ 'test string', diff --git a/test/interpolateName.test.js b/test/interpolateName.test.js index c56e298..4ed7c5b 100644 --- a/test/interpolateName.test.js +++ b/test/interpolateName.test.js @@ -62,13 +62,13 @@ describe('interpolateName()', () => { '/app/img/image.png', '[sha512:hash:base64:7].[ext]', 'test content', - '2BKDTjl.png', + 'DL9MrvO.png', ], [ '/app/img/image.png', '[sha512:contenthash:base64:7].[ext]', 'test content', - '2BKDTjl.png', + 'DL9MrvO.png', ], [ '/app/dir/file.png', @@ -116,13 +116,13 @@ describe('interpolateName()', () => { '/lib/components/modal/modal.css', '[name].[md5:hash:base64:20].[ext]', 'test content', - 'modal.1n8osQznuT8jOAwdzg_n.css', + 'modal.lHP90NiApDwht3eNNIch.css', ], [ '/lib/components/modal/modal.css', '[name].[md5:contenthash:base64:20].[ext]', 'test content', - 'modal.1n8osQznuT8jOAwdzg_n.css', + 'modal.lHP90NiApDwht3eNNIch.css', ], // Should not interpret without `hash` or `contenthash` [ @@ -265,7 +265,7 @@ describe('interpolateName()', () => { ], [ [{}, '[hash:base64]', { content: 'test string' }], - '2LIG3oc1uBNmwOoL7kXgoK', + 'Lgbt1PFiMmjFpRcw2KCyrw==', 'should interpolate [hash] token with options', ], [ From 90c7c4be17e3e0b2f6091a69c67db7a6df9fd044 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Thu, 4 Nov 2021 18:06:58 +0300 Subject: [PATCH 2/4] chore(release): 2.0.2 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14b41a4..60f15e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.0.2](https://github.com/webpack/loader-utils/compare/v2.0.1...v2.0.2) (2021-11-04) + + +### Bug Fixes + +* base64 generation and unicode characters ([#197](https://github.com/webpack/loader-utils/issues/197)) ([8c2d24e](https://github.com/webpack/loader-utils/commit/8c2d24ee400bc4567335e97ee6004c3baa6ef66f)) + ### [2.0.1](https://github.com/webpack/loader-utils/compare/v2.0.0...v2.0.1) (2021-10-29) diff --git a/package.json b/package.json index 7648bee..7c357c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loader-utils", - "version": "2.0.1", + "version": "2.0.2", "author": "Tobias Koppers @sokra", "description": "utils for webpack loaders", "dependencies": { From a93cf6f4702012030f6b5ee8340d5c95ec1c7d4c Mon Sep 17 00:00:00 2001 From: Mike Cebrian Date: Thu, 20 Oct 2022 15:54:33 -0400 Subject: [PATCH 3/4] fix(security): prototype polution exploit (#217) --- lib/parseQuery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/parseQuery.js b/lib/parseQuery.js index fdca007..4a201a2 100644 --- a/lib/parseQuery.js +++ b/lib/parseQuery.js @@ -26,7 +26,7 @@ function parseQuery(query) { } const queryArgs = query.split(/[,&]/g); - const result = {}; + const result = Object.create(null); queryArgs.forEach((arg) => { const idx = arg.indexOf('='); From 7162619fb982c394ed75098a0a0ed7e7f3177c70 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 20 Oct 2022 22:58:39 +0300 Subject: [PATCH 4/4] chore(release): 2.0.3 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f15e7..ae27c68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.0.3](https://github.com/webpack/loader-utils/compare/v2.0.1...v2.0.3) (2022-10-20) + + +### Bug Fixes + +* **security:** prototype pollution exploit ([#217](https://github.com/webpack/loader-utils/issues/217)) ([a93cf6f](https://github.com/webpack/loader-utils/commit/a93cf6f4702012030f6b5ee8340d5c95ec1c7d4c)) + ### [2.0.2](https://github.com/webpack/loader-utils/compare/v2.0.1...v2.0.2) (2021-11-04) diff --git a/package.json b/package.json index 7c357c9..7c597b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loader-utils", - "version": "2.0.2", + "version": "2.0.3", "author": "Tobias Koppers @sokra", "description": "utils for webpack loaders", "dependencies": { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy