Skip to content

Commit e047da9

Browse files
authored
fix: Reject invalid locale format in PagesRouter (#10282)
1 parent 99fcbb3 commit e047da9

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

spec/PagesRouter.spec.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,15 +1396,31 @@ describe('Pages Router', () => {
13961396
expect(response.text).toContain('<img');
13971397
});
13981398

1399-
it('should escape XSS in locale parameter', async () => {
1399+
it('should reject XSS payload in locale parameter', async () => {
14001400
const xssLocale = '"><svg/onload=alert(1)>';
14011401
const response = await request({
14021402
url: `http://localhost:8378/1/apps/choose_password?locale=${encodeURIComponent(xssLocale)}&appId=test`,
14031403
});
14041404

14051405
expect(response.status).toBe(200);
1406+
// Invalid locale is rejected by format validation, so the XSS
1407+
// payload never reaches the page content
14061408
expect(response.text).not.toContain('<svg/onload=alert(1)>');
1407-
expect(response.text).toContain('&quot;&gt;&lt;svg');
1409+
expect(response.text).not.toContain('&quot;&gt;&lt;svg');
1410+
});
1411+
1412+
it('should reject non-ASCII characters in locale parameter', async () => {
1413+
// Non-ASCII characters like ğ (U+011F) would cause ERR_INVALID_CHAR
1414+
// when set as HTTP header value if not rejected by locale validation
1415+
const nonAsciiLocale = 'ğ';
1416+
const response = await request({
1417+
url: `http://localhost:8378/1/apps/choose_password?locale=${encodeURIComponent(nonAsciiLocale)}&appId=test`,
1418+
});
1419+
1420+
expect(response.status).toBe(200);
1421+
// Non-ASCII locale is rejected by format validation;
1422+
// no ERR_INVALID_CHAR error occurs
1423+
expect(response.headers['x-parse-page-param-locale']).toBeUndefined();
14081424
});
14091425

14101426
it('should handle legitimate usernames with quotes correctly', async () => {

src/Routers/PagesRouter.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,16 @@ export class PagesRouter extends PromiseRouter {
555555
(req.body || {})[pageParams.locale] ||
556556
(req.params || {})[pageParams.locale] ||
557557
(req.headers || {})[pageParamHeaderPrefix + pageParams.locale];
558+
559+
// Validate locale format to prevent path traversal and invalid
560+
// HTTP header characters; only allow standard locale patterns
561+
// like "en", "en-US", "de-AT", "zh-Hans-CN"
562+
if (locale !== undefined && typeof locale !== 'string') {
563+
return undefined;
564+
}
565+
if (typeof locale === 'string' && !/^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(locale)) {
566+
return undefined;
567+
}
558568
return locale;
559569
}
560570

0 commit comments

Comments
 (0)