fix(front): reject backslash paths in isValidReturnToPath (open-redirect hardening) (#21287)
## Summary
`isValidReturnToPath` validates the post-login `returnTo` path and
already rejects protocol-relative `//` paths — but not the backslash
variant. Browsers normalize `\` to `/`, so `/\evil.com` resolves like
`//evil.com` (a protocol-relative, external URL) while still passing the
existing `//` check:
```ts
isValidReturnToPath("/\\evil.com"); // returns true today; should be false
```
This hardens the open-redirect guard by rejecting any path containing a
backslash, so a `returnTo` can only ever be a same-site absolute path.
## Changes
- `isValidReturnToPath`: reject paths containing `\`.
- Added tests for backslash-tricked paths.
Framed as defense-in-depth — the validator should reject this class
regardless of how each consumer performs the redirect.
---------
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@@ -17,6 +17,12 @@ describe('isValidReturnToPath', () => {
|
||||
expect(isValidReturnToPath('//evil.com')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for backslash-tricked paths', () => {
|
||||
expect(isValidReturnToPath('/\\evil.com')).toBe(false);
|
||||
expect(isValidReturnToPath('/\\/evil.com')).toBe(false);
|
||||
expect(isValidReturnToPath('/objects\\..\\evil')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for onboarding paths', () => {
|
||||
expect(isValidReturnToPath('/create/workspace')).toBe(false);
|
||||
expect(isValidReturnToPath('/create/profile')).toBe(false);
|
||||
|
||||
@@ -16,7 +16,7 @@ export const isValidReturnToPath = (path: string): boolean => {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!path.startsWith('/') || path.startsWith('//')) {
|
||||
if (!path.startsWith('/') || path.startsWith('//') || path.includes('\\')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user