Skip to content

Commit ecfbf2d

Browse files
wojteknclaude
andauthored
Fix ReDoS in mu-plugins loader path regex (#4254)
## Related issues - Related to code scanning alert [#204](https://github.com/Automattic/studio/security/code-scanning/204) (`js/redos`, CWE-1333, high severity) ## How AI was used in this PR Claude Code fetched the code scanning alert, identified the ambiguous regex branch causing exponential backtracking, applied the fix, and verified correctness and timing. All human-reviewed. ## Proposed Changes The regex that reads the mu-plugins directory path back out of the generated loader plugin (`$studio_mu_plugins_dir = '...'`) had ambiguous alternatives: its catch-all branch `[^']` also matched a lone backslash, overlapping with the `\\` and `\'` escape branches. A path containing many consecutive backslashes could therefore be matched multiple ways, triggering catastrophic (exponential) backtracking — a ReDoS. In practice this is reached when Studio parses an existing native-PHP loader file, so a malformed/crafted loader path could hang the process. The fix excludes backslash from the catch-all branch (`[^\\']`), making the three alternatives mutually exclusive while still matching exactly what PHP single-quote escaping produces. No behavior change for valid paths. ## Testing Instructions - `npm test -- packages/common/lib/tests/mu-plugins.test.ts` — all 12 tests pass. - Verified a path containing backslashes and quotes still round-trips correctly through escape/unescape. - Verified timing: a malicious input (~40 backslashes) previously took ~3940 ms to reject and now rejects in ~0.04 ms. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent c6d45d7 commit ecfbf2d

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

‎packages/common/lib/mu-plugins.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async function getExistingNativePhpMuPluginsDir(
9595
return null;
9696
}
9797

98-
const match = loaderContent.match( /\$studio_mu_plugins_dir = '((?:\\\\|\\'|[^'])*)';/ );
98+
const match = loaderContent.match( /\$studio_mu_plugins_dir = '((?:\\\\|\\'|[^\\'])*)';/ );
9999
if ( ! match ) {
100100
return null;
101101
}

0 commit comments

Comments
 (0)