mirror of
https://github.com/parse-community/parse-server
synced 2026-08-09 13:03:18 +00:00
fix: Reject invalid locale format in PagesRouter (#10282)
This commit is contained in:
@@ -1396,15 +1396,31 @@ describe('Pages Router', () => {
|
|||||||
expect(response.text).toContain('<img');
|
expect(response.text).toContain('<img');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape XSS in locale parameter', async () => {
|
it('should reject XSS payload in locale parameter', async () => {
|
||||||
const xssLocale = '"><svg/onload=alert(1)>';
|
const xssLocale = '"><svg/onload=alert(1)>';
|
||||||
const response = await request({
|
const response = await request({
|
||||||
url: `http://localhost:8378/1/apps/choose_password?locale=${encodeURIComponent(xssLocale)}&appId=test`,
|
url: `http://localhost:8378/1/apps/choose_password?locale=${encodeURIComponent(xssLocale)}&appId=test`,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
// Invalid locale is rejected by format validation, so the XSS
|
||||||
|
// payload never reaches the page content
|
||||||
expect(response.text).not.toContain('<svg/onload=alert(1)>');
|
expect(response.text).not.toContain('<svg/onload=alert(1)>');
|
||||||
expect(response.text).toContain('"><svg');
|
expect(response.text).not.toContain('"><svg');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject non-ASCII characters in locale parameter', async () => {
|
||||||
|
// Non-ASCII characters like ğ (U+011F) would cause ERR_INVALID_CHAR
|
||||||
|
// when set as HTTP header value if not rejected by locale validation
|
||||||
|
const nonAsciiLocale = 'ğ';
|
||||||
|
const response = await request({
|
||||||
|
url: `http://localhost:8378/1/apps/choose_password?locale=${encodeURIComponent(nonAsciiLocale)}&appId=test`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
// Non-ASCII locale is rejected by format validation;
|
||||||
|
// no ERR_INVALID_CHAR error occurs
|
||||||
|
expect(response.headers['x-parse-page-param-locale']).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle legitimate usernames with quotes correctly', async () => {
|
it('should handle legitimate usernames with quotes correctly', async () => {
|
||||||
|
|||||||
@@ -555,6 +555,16 @@ export class PagesRouter extends PromiseRouter {
|
|||||||
(req.body || {})[pageParams.locale] ||
|
(req.body || {})[pageParams.locale] ||
|
||||||
(req.params || {})[pageParams.locale] ||
|
(req.params || {})[pageParams.locale] ||
|
||||||
(req.headers || {})[pageParamHeaderPrefix + pageParams.locale];
|
(req.headers || {})[pageParamHeaderPrefix + pageParams.locale];
|
||||||
|
|
||||||
|
// Validate locale format to prevent path traversal and invalid
|
||||||
|
// HTTP header characters; only allow standard locale patterns
|
||||||
|
// like "en", "en-US", "de-AT", "zh-Hans-CN"
|
||||||
|
if (locale !== undefined && typeof locale !== 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (typeof locale === 'string' && !/^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(locale)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
return locale;
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user