picomatch known bugs

npm

6 known bugs in picomatch, with affected versions, fixes and workarounds. Sourced from upstream issue trackers.

6
bugs
Known bugs
SeverityAffectedFixed inTitleStatusSource
high4.0.04.0.4
Picomatch has a ReDoS vulnerability via extglob quantifiers
### Impact `picomatch` is vulnerable to Regular Expression Denial of Service (ReDoS) when processing crafted extglob patterns. Certain patterns using extglob quantifiers such as `+()` and `*()`, especially when combined with overlapping alternatives or nested extglobs, are compiled into regular expressions that can exhibit catastrophic backtracking on non-matching input. Examples of problematic patterns include `+(a|aa)`, `+(*|?)`, `+(+(a))`, `*(+(a))`, and `+(+(+(a)))`. In local reproduction, these patterns caused multi-second event-loop blocking with relatively short inputs. For example, `+(a|aa)` compiled to `^(?:(?=.)(?:a|aa)+)$` and took about 2 seconds to reject a 41-character non-matching input, while nested patterns such as `+(+(a))` and `*(+(a))` took around 29 seconds to reject a 33-character input on a modern M1 MacBook. Applications are impacted when they allow untrusted users to supply glob patterns that are passed to `picomatch` for compilation or matching. In those cases, an attacker can cause excessive CPU consumption and block the Node.js event loop, resulting in a denial of service. Applications that only use trusted, developer-controlled glob patterns are much less likely to be exposed in a security-relevant way. ### Patches This issue is fixed in picomatch 4.0.4, 3.0.2 and 2.3.2. Users should upgrade to one of these versions or later, depending on their supported release line. ### Workarounds If upgrading is not immediately possible, avoid passing untrusted glob patterns to `picomatch`. Possible mitigations include: - disable extglob support for untrusted patterns by using `noextglob: true` - reject or sanitize patterns containing nested extglobs or extglob quantifiers such as `+()` and `*()` - enforce strict allowlists for accepted pattern syntax - run matching in an isolated worker or separate process with time and resource limits - apply application-level request throttling and input validation for any endpoint that accepts glob patterns ### Resources - Picomatch repository: https://github.com/micromatch/picomatch - `lib/parse.js` and `lib/constants.js` are involved in generating the vulnerable regex forms - Comparable ReDoS precedent: CVE-2024-4067 (`micromatch`) - Comparable generated-regex precedent: CVE-2024-45296 (`path-to-regexp`)
fixedosv:GHSA-c2c7-rcm5-vvqj
mediumany\u2014
Relative patterns and paths with dot in the base name
The `isMatch` method always returns `true` for files starting with a period if a relative path is used. The `dot` option has no effect here. ```js const picomatch = require('picomatch'); const isMatch = picomatch('../*.js'); const result = isMatch('../.test.js'); console.log(result); // true ``` Comparing behavior with micromatch: ```js const picomatch = require('picomatch'); const micromatch = require('micromatch'); const pico = picomatch('../*.js'); const micro = micromatch.isMatch('../.test.js', '../*.js'); console.log(pico('../.test.js')); // true console.log(micro); // false Will be `true` with { dot: true } ```
fixedgithub:2
mediumany\u2014
Incorrect matching with curly braces and globstar
#### Source * mrmlnc/fast-glob#159 #### Actual behavior The following filepathes is not matched by `minimatch`, `micromatch` and `picomatch` for the `{file.txt,directory/**/*}` pattern. ``` directory/.test.txt directory/test.txt ``` But if you remove the `/*` part of the pattern, everything works correctly. #### Expected behavior Will be matched or documented :) #### Code sample Works fine: ```js picomatch.makeRe('{file.txt,directory/**}', { dot: true }); ``` * https://runkit.com/mrmlnc/5c6db74af4685d0012b8a037 Works bad: ```js picomatch.makeRe('{file.txt,directory/**/*}', { dot: true }); ``` * https://runkit.com/mrmlnc/5c6db7a2629c26001267cf8d
fixedgithub:8
mediumany\u2014
Brace expansion matches single item
According to the braces library, braces expansion should not match a single item like `{foo}`. However, picomatch does interpret this expression. braces: ```js braces('{foo}') //=> ['{foo}'] ``` picomatch: ```js picomatch.parse('{foo}').output //=> '(foo)' ``` Compare that to when there are multiple items: ```js braces('{foo,bar}') //=> ['(foo|bar)'] picomatch.parse('{foo,bar}').output //=> '(foo|bar)' ``` It seems to me like the behavior should match in both cases.
fixedgithub:49
mediumany\u2014
Glob **/!(*-dbg).@(js) is wrongly translated into RegExp and thus DOES match -dbg.js files
The Glob: ``` **/!(*-dbg).@(js) ``` Which should match any `.js` files that do not end with `-dbg` is wrongly translated to: ``` ^(?:(?:^|[\\/]|(?:(?:(?!(?:^|[\\/])\.{1,2}(?:[\\/]|$)).)*?)[\\/])(?:(?!(?:[^\\/]*?-dbg).@(js))[^\\/]*?)\.(js))$ ``` Please note how for the negative backreference, the glob pattern `.@(js)` is literally taking into the regex and is not translated into a regexp / excapted itself? Expected RegExp would have been: ``` ^(?:(?:^|[\\/]|(?:(?:(?!(?:^|[\\/])\.{1,2}(?:[\\/]|$)).)*?)[\\/])(?:(?!(?:[^\\/]*?-dbg)\.(js))[^\\/]*?)\.(js))$ ```
fixedgithub:93
medium4.0.04.0.4
Picomatch: Method Injection in POSIX Character Classes causes incorrect Glob Matching
### Impact picomatch is vulnerable to a **method injection vulnerability (CWE-1321)** affecting the `POSIX_REGEX_SOURCE` object. Because the object inherits from `Object.prototype`, specially crafted POSIX bracket expressions (e.g., `[[:constructor:]]`) can reference inherited method names. These methods are implicitly converted to strings and injected into the generated regular expression. This leads to **incorrect glob matching behavior (integrity impact)**, where patterns may match unintended filenames. The issue does **not enable remote code execution**, but it can cause security-relevant logic errors in applications that rely on glob matching for filtering, validation, or access control. All users of affected `picomatch` versions that process untrusted or user-controlled glob patterns are potentially impacted. ### Patches This issue is fixed in picomatch 4.0.4, 3.0.2 and 2.3.2. Users should upgrade to one of these versions or later, depending on their supported release line. ### Workarounds If upgrading is not immediately possible, avoid passing untrusted glob patterns to picomatch. Possible mitigations include: - Sanitizing or rejecting untrusted glob patterns, especially those containing POSIX character classes like `[[:...:]]`. - Avoiding the use of POSIX bracket expressions if user input is involved. - Manually patching the library by modifying `POSIX_REGEX_SOURCE` to use a null prototype: ```js const POSIX_REGEX_SOURCE = { __proto__: null, alnum: 'a-zA-Z0-9', alpha: 'a-zA-Z', // ... rest unchanged }; ### Resources - fix for similar issue: https://github.com/micromatch/picomatch/pull/144 - picomatch repository https://github.com/micromatch/picomatch
fixedosv:GHSA-3v7f-55p6-f55p
API access

Get this data programmatically \u2014 free, no authentication.

curl https://depscope.dev/api/bugs/npm/picomatch
picomatch bugs — known issues per version | DepScope | DepScope