Skip to content

Commit 5e0b9a0

Browse files
committed
fix: avoid ReDoS in packagist name validation
Signed-off-by: anilb <epipav@gmail.com>
1 parent 5352377 commit 5e0b9a0

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

services/apps/packages_worker/src/packagist/__tests__/listPackages.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ describe('parsePackagistPackageList', () => {
4747
expect(invalid).toBe(7)
4848
})
4949

50+
it('rejects a long invalid segment without catastrophic regex backtracking', () => {
51+
// CodeQL js/redos: a long run of one char class followed by a char that breaks
52+
// the match is the classic trigger for exponential backtracking.
53+
const pathological = 'vendor/' + '0'.repeat(50) + '!'
54+
const start = Date.now()
55+
const { entries, invalid } = parsePackagistPackageList({ packageNames: [pathological] })
56+
expect(Date.now() - start).toBeLessThan(200)
57+
expect(entries).toEqual([])
58+
expect(invalid).toBe(1)
59+
})
60+
5061
it('lowercases and deduplicates names without counting duplicates as invalid', () => {
5162
const { entries, invalid } = parsePackagistPackageList({
5263
packageNames: ['Monolog/Monolog', 'monolog/monolog'],

services/apps/packages_worker/src/packagist/listPackages.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { buildPackagistUserAgent, describeFetchFailure, packagistDispatcher } fr
44
import type { FetchError } from './types'
55

66
const PACKAGIST_LIST = 'https://packagist.org/packages/list.json'
7-
const COMPOSER_NAME_REGEX = /^[a-z0-9]([_.-]?[a-z0-9]+)*$/
7+
// Non-backtracking form: a mandatory separator per repetition (vs. an optional one)
8+
// removes the ambiguity that let the old `([_.-]?[a-z0-9]+)*` pattern backtrack
9+
// exponentially on a long run of the same character class (CodeQL js/redos).
10+
const COMPOSER_NAME_REGEX = /^[a-z0-9]+(?:[_.-][a-z0-9]+)*$/
811

912
export interface PackagistListEntry {
1013
vendor: string

0 commit comments

Comments
 (0)