Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/react-devtools-shared/src/__tests__/utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,24 @@ describe('utils', () => {
165558,
]);
});

it('should handle malicious input without ReDoS vulnerability', () => {
// This test ensures the Firefox stack regex doesn't exhibit catastrophic
// backtracking (ReDoS) when processing malicious input patterns.
// See: https://github.com/facebook/react/issues/35490
const nullChar = String.fromCharCode(0);
const maliciousInput =
' ' + ('"' + nullChar).repeat(2000) + '\r!\r!' + '\n';

const startTime = Date.now();
// This should complete quickly (< 100ms) instead of hanging for seconds
const result = extractLocationFromComponentStack(maliciousInput);
const elapsedTime = Date.now() - startTime;

// The result should be null (no valid stack frame) and complete quickly
expect(result).toEqual(null);
expect(elapsedTime).toBeLessThan(100);
});
});

describe('symbolicateSource', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ function parseStackTraceFromChromeStack(
return parsedFrames;
}

const firefoxFrameRegExp = /^((?:.*".+")?[^@]*)@(.+):(\d+):(\d+)$/;
// Fix ReDoS vulnerability: Changed `.*".+"` to `"[^"]+"` to prevent catastrophic backtracking.
// The original pattern `(?:.*".+")?` with nested quantifiers could cause exponential time
// complexity on malicious inputs. Using `"[^"]+"` (negated character class) is O(n) and
// maintains the same matching behavior for valid Firefox stack frames.
const firefoxFrameRegExp = /^((?:"[^"]+")?[^@]*)@(.+):(\d+):(\d+)$/;
function parseStackTraceFromFirefoxStack(
stack: string,
skipFrames: number,
Expand Down