From 97731871e674bf93bcbf29e9d3258da8685f3076 Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Thu, 17 Jul 2025 02:18:36 +0800 Subject: [PATCH 1/7] Update hosted-git-resolver.js --- src/resolvers/exotics/hosted-git-resolver.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/resolvers/exotics/hosted-git-resolver.js b/src/resolvers/exotics/hosted-git-resolver.js index 83d4ab20b0..aa6ab043da 100644 --- a/src/resolvers/exotics/hosted-git-resolver.js +++ b/src/resolvers/exotics/hosted-git-resolver.js @@ -30,8 +30,9 @@ export function explodeHostedGitFragment(fragment: string, reporter: Reporter): } const parts = fragment - .replace(/(.*?)#.*/, '$1') // Strip hash - .replace(/.*:(.*)/, '$1') // Strip prefixed protocols + .split('#', 1)[0] + .split(':') + .pop() .replace(/.git$/, '') // Strip the .git suffix .split('/'); From af396d504054051b5ccf529369746f600e8ca4fa Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Thu, 17 Jul 2025 02:19:28 +0800 Subject: [PATCH 2/7] Update hosted-git-resolver.js --- __tests__/resolvers/exotics/hosted-git-resolver.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/__tests__/resolvers/exotics/hosted-git-resolver.js b/__tests__/resolvers/exotics/hosted-git-resolver.js index 403e14374a..260b26ebf2 100644 --- a/__tests__/resolvers/exotics/hosted-git-resolver.js +++ b/__tests__/resolvers/exotics/hosted-git-resolver.js @@ -28,3 +28,13 @@ const reporter = new reporters.NoopReporter({}); expect(explodeHostedGitFragment(fragment, reporter).hash).toEqual(hash); }); }); +describe('explodeHostedGitFragment DOS vulnerability test', () => { + const MAX_MS = 200; + test('long fragment without # should finish quickly and throw', () => { + const longFragment = '' + '\u0000'.repeat(100000) + '\u0000'; + const start = Date.now(); + expect(() => explodeHostedGitFragment(longFragment, reporter)).toThrow(); + const duration = Date.now() - start; + expect(duration).toBeLessThan(MAX_MS); + }); +}); From f34b205513a544bcc0e94efdd475dc4e196bbab0 Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Wed, 13 Aug 2025 10:03:14 +0800 Subject: [PATCH 3/7] Update hosted-git-resolver.js --- src/resolvers/exotics/hosted-git-resolver.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/resolvers/exotics/hosted-git-resolver.js b/src/resolvers/exotics/hosted-git-resolver.js index aa6ab043da..83d4ab20b0 100644 --- a/src/resolvers/exotics/hosted-git-resolver.js +++ b/src/resolvers/exotics/hosted-git-resolver.js @@ -30,9 +30,8 @@ export function explodeHostedGitFragment(fragment: string, reporter: Reporter): } const parts = fragment - .split('#', 1)[0] - .split(':') - .pop() + .replace(/(.*?)#.*/, '$1') // Strip hash + .replace(/.*:(.*)/, '$1') // Strip prefixed protocols .replace(/.git$/, '') // Strip the .git suffix .split('/'); From 81979c88fb77ee3055ef2981389f3bae3edd2eec Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Wed, 13 Aug 2025 10:04:41 +0800 Subject: [PATCH 4/7] Update hosted-git-resolver.js --- __tests__/resolvers/exotics/hosted-git-resolver.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/__tests__/resolvers/exotics/hosted-git-resolver.js b/__tests__/resolvers/exotics/hosted-git-resolver.js index 260b26ebf2..403e14374a 100644 --- a/__tests__/resolvers/exotics/hosted-git-resolver.js +++ b/__tests__/resolvers/exotics/hosted-git-resolver.js @@ -28,13 +28,3 @@ const reporter = new reporters.NoopReporter({}); expect(explodeHostedGitFragment(fragment, reporter).hash).toEqual(hash); }); }); -describe('explodeHostedGitFragment DOS vulnerability test', () => { - const MAX_MS = 200; - test('long fragment without # should finish quickly and throw', () => { - const longFragment = '' + '\u0000'.repeat(100000) + '\u0000'; - const start = Date.now(); - expect(() => explodeHostedGitFragment(longFragment, reporter)).toThrow(); - const duration = Date.now() - start; - expect(duration).toBeLessThan(MAX_MS); - }); -}); From 7e94704ae04da9c5d6a195e125323e49cb32743c Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Wed, 13 Aug 2025 11:28:14 +0800 Subject: [PATCH 5/7] Update registry-resolver.js --- .../resolvers/exotics/registry-resolver.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/__tests__/resolvers/exotics/registry-resolver.js b/__tests__/resolvers/exotics/registry-resolver.js index ab8d802594..06754ecd83 100644 --- a/__tests__/resolvers/exotics/registry-resolver.js +++ b/__tests__/resolvers/exotics/registry-resolver.js @@ -28,3 +28,24 @@ test('resolves scoped yarn: package', () => { expect(resolver.name).toEqual('@org/foo'); }); + +test('Regex Dos', () => { + const nativeFs = require('fs'); + const os = require('os'); + + const bundle = '' + '-----BEGIN '.repeat(50000) + '\r'; + const tmp = path.join(os.tmpdir(), `cafile-${Date.now()}.pem`); + nativeFs.writeFileSync(tmp, bundle, 'utf8'); + + const rm = new RequestManager((new Reporter(): any)); + + const start = Date.now(); + rm.setOptions({userAgent: 'ua/1.0', strictSSL: false, cafile: tmp}); + const duration = Date.now() - start; + + expect(duration).toBeLessThan(3000); + + try { + nativeFs.unlinkSync(tmp); + } catch (_) {} +}); From e8ed0ecb4c2ce44540542801534f2cd3cb744356 Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Wed, 13 Aug 2025 11:28:39 +0800 Subject: [PATCH 6/7] Update registry-resolver.js --- .../resolvers/exotics/registry-resolver.js | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/__tests__/resolvers/exotics/registry-resolver.js b/__tests__/resolvers/exotics/registry-resolver.js index 06754ecd83..03fa8af907 100644 --- a/__tests__/resolvers/exotics/registry-resolver.js +++ b/__tests__/resolvers/exotics/registry-resolver.js @@ -29,23 +29,21 @@ test('resolves scoped yarn: package', () => { expect(resolver.name).toEqual('@org/foo'); }); -test('Regex Dos', () => { - const nativeFs = require('fs'); - const os = require('os'); - - const bundle = '' + '-----BEGIN '.repeat(50000) + '\r'; - const tmp = path.join(os.tmpdir(), `cafile-${Date.now()}.pem`); - nativeFs.writeFileSync(tmp, bundle, 'utf8'); - - const rm = new RequestManager((new Reporter(): any)); - - const start = Date.now(); - rm.setOptions({userAgent: 'ua/1.0', strictSSL: false, cafile: tmp}); - const duration = Date.now() - start; - - expect(duration).toBeLessThan(3000); - - try { - nativeFs.unlinkSync(tmp); - } catch (_) {} +describe('RegistryResolver DOS regression test', () => { + const MAX_MS = 200; + + test('long fragment without # should finish quickly and throw', () => { + const fragment = '\u0000' + '\u0000:'.repeat(100000) + '\n1\n'; + const reqWithReporter: any = { + reporter: {lang: (_key, frag) => `invalidFragment: ${String(frag).slice(0, 16)}...`}, + }; + + const start = Date.now(); + expect(() => { + new RegistryResolver((reqWithReporter: any), fragment); + }).toThrow(MessageError); + const duration = Date.now() - start; + + expect(duration).toBeLessThan(MAX_MS); + }); }); From 5150f8613c99219a7e4c51d7f2e0c1febed532de Mon Sep 17 00:00:00 2001 From: mmmsssttt404 <931121963@qq.com> Date: Wed, 13 Aug 2025 11:30:22 +0800 Subject: [PATCH 7/7] Update registry-resolver.js --- src/resolvers/exotics/registry-resolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolvers/exotics/registry-resolver.js b/src/resolvers/exotics/registry-resolver.js index f75f673e86..9b06a94288 100644 --- a/src/resolvers/exotics/registry-resolver.js +++ b/src/resolvers/exotics/registry-resolver.js @@ -9,7 +9,7 @@ export default class RegistryResolver extends ExoticResolver { constructor(request: PackageRequest, fragment: string) { super(request, fragment); - const match = fragment.match(/^(\S+):(@?.*?)(@(.*?)|)$/); + const match = fragment.match(/^(\S+):(@?(?:(?![@:]).)*?)(@((?:(?![@:]).)*?)|)$/); if (match) { this.range = match[4] || 'latest'; this.name = match[2];