mirror of
https://github.com/parse-community/parse-server
synced 2026-08-09 13:03:18 +00:00
fix: Sanitize control characters in page parameter response headers (#10237)
This commit is contained in:
@@ -1040,6 +1040,32 @@ describe('Pages Router', () => {
|
||||
}).catch(e => e);
|
||||
expect(response.status).not.toBe(500);
|
||||
});
|
||||
|
||||
it('does not return 500 when page parameter contains CRLF characters', async () => {
|
||||
await reconfigureServer(config);
|
||||
const crlf = 'abc\r\nX-Injected: 1';
|
||||
const url = `${config.publicServerURL}/apps/choose_password?appId=test&token=${encodeURIComponent(crlf)}&username=testuser`;
|
||||
const response = await request({
|
||||
url: url,
|
||||
followRedirects: false,
|
||||
}).catch(e => e);
|
||||
expect(response.status).not.toBe(500);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
it('does not return 500 when page parameter contains CRLF characters in redirect response', async () => {
|
||||
await reconfigureServer(config);
|
||||
const crlf = 'abc\r\nX-Injected: 1';
|
||||
const url = `${config.publicServerURL}/apps/test/resend_verification_email`;
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
url: url,
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: `username=${encodeURIComponent(crlf)}`,
|
||||
followRedirects: false,
|
||||
}).catch(e => e);
|
||||
expect(response.status).not.toBe(500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom route', () => {
|
||||
|
||||
+25
-14
@@ -455,13 +455,7 @@ export class PagesRouter extends PromiseRouter {
|
||||
|
||||
// Add placeholders in header to allow parsing for programmatic use
|
||||
// of response, instead of having to parse the HTML content.
|
||||
const encode = this.pagesConfig.encodePageParamHeaders;
|
||||
const headers = Object.entries(params).reduce((m, p) => {
|
||||
if (p[1] !== undefined) {
|
||||
m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = encode ? encodeURIComponent(p[1]) : p[1];
|
||||
}
|
||||
return m;
|
||||
}, {});
|
||||
const headers = this.composePageParamHeaders(params);
|
||||
|
||||
return { text: data, headers: headers };
|
||||
}
|
||||
@@ -555,6 +549,29 @@ export class PagesRouter extends PromiseRouter {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes page parameter headers from the given parameters. Control
|
||||
* characters are always stripped from header values to prevent
|
||||
* ERR_INVALID_CHAR errors. Values are URI-encoded if the
|
||||
* `encodePageParamHeaders` option is enabled.
|
||||
* @param {Object} params The parameters to include in the headers.
|
||||
* @returns {Object} The headers object.
|
||||
*/
|
||||
composePageParamHeaders(params) {
|
||||
const encode = this.pagesConfig.encodePageParamHeaders;
|
||||
return Object.entries(params).reduce((m, p) => {
|
||||
if (p[1] !== undefined) {
|
||||
let value = encode ? encodeURIComponent(p[1]) : p[1];
|
||||
if (typeof value === 'string') {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
value = value.replace(/[\x00-\x1f\x7f]/g, '');
|
||||
}
|
||||
m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = value;
|
||||
}
|
||||
return m;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a response with http redirect.
|
||||
* @param {Object} req The express request.
|
||||
@@ -578,13 +595,7 @@ export class PagesRouter extends PromiseRouter {
|
||||
|
||||
// Add parameters to header to allow parsing for programmatic use
|
||||
// of response, instead of having to parse the HTML content.
|
||||
const encode = this.pagesConfig.encodePageParamHeaders;
|
||||
const headers = Object.entries(params).reduce((m, p) => {
|
||||
if (p[1] !== undefined) {
|
||||
m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = encode ? encodeURIComponent(p[1]) : p[1];
|
||||
}
|
||||
return m;
|
||||
}, {});
|
||||
const headers = this.composePageParamHeaders(params);
|
||||
|
||||
return {
|
||||
status: 303,
|
||||
|
||||
Reference in New Issue
Block a user