Skip to content

Commit 06abb6e

Browse files
DianaDerevyankinakibanamachine
authored andcommitted
Enable prototype pollution protection in TSVB (#85952)
* Enable prototype pollution protection in TSVB Closes #78908 * Update Dock API Changes * Replace logging failed in validateObject validation with 400 error * Move validateObject to kbn-std package and add a description * Update Doc API Changes * Rename validateObject function to ensureNoUnsafeProperties * Rename other validateObject occurrences Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 78f6d9a commit 06abb6e

File tree

7 files changed

+17
-27
lines changed

7 files changed

+17
-27
lines changed

src/core/server/http/prototype_pollution/validate_object.test.ts renamed to packages/kbn-std/src/ensure_no_unsafe_properties.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
* under the License.
1818
*/
1919

20-
import { validateObject } from './validate_object';
20+
import { ensureNoUnsafeProperties } from './ensure_no_unsafe_properties';
2121

2222
test(`fails on circular references`, () => {
2323
const foo: Record<string, any> = {};
2424
foo.myself = foo;
2525

2626
expect(() =>
27-
validateObject({
27+
ensureNoUnsafeProperties({
2828
payload: foo,
2929
})
3030
).toThrowErrorMatchingInlineSnapshot(`"circular reference detected"`);
@@ -57,7 +57,7 @@ test(`fails on circular references`, () => {
5757
[property]: value,
5858
};
5959
test(`can submit ${JSON.stringify(obj)}`, () => {
60-
expect(() => validateObject(obj)).not.toThrowError();
60+
expect(() => ensureNoUnsafeProperties(obj)).not.toThrowError();
6161
});
6262
});
6363
});
@@ -74,6 +74,6 @@ test(`fails on circular references`, () => {
7474
JSON.parse(`{ "foo": { "bar": { "constructor": { "prototype" : null } } } }`),
7575
].forEach((value) => {
7676
test(`can't submit ${JSON.stringify(value)}`, () => {
77-
expect(() => validateObject(value)).toThrowErrorMatchingSnapshot();
77+
expect(() => ensureNoUnsafeProperties(value)).toThrowErrorMatchingSnapshot();
7878
});
7979
});

src/core/server/http/prototype_pollution/validate_object.ts renamed to packages/kbn-std/src/ensure_no_unsafe_properties.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const hasOwnProperty = (obj: any, property: string) =>
3131
const isObject = (obj: any) => typeof obj === 'object' && obj !== null;
3232

3333
// we're using a stack instead of recursion so we aren't limited by the call stack
34-
export function validateObject(obj: any) {
34+
export function ensureNoUnsafeProperties(obj: any) {
3535
if (!isObject(obj)) {
3636
return;
3737
}

packages/kbn-std/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ export { withTimeout } from './promise';
2727
export { isRelativeUrl, modifyUrl, getUrlOrigin, URLMeaningfulParts } from './url';
2828
export { unset } from './unset';
2929
export { getFlattenedObject } from './get_flattened_object';
30+
export { ensureNoUnsafeProperties } from './ensure_no_unsafe_properties';
3031
export * from './rxjs_7';

src/core/server/http/http_tools.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import Hoek from '@hapi/hoek';
2929
import type { ServerOptions as TLSOptions } from 'https';
3030
import type { ValidationError } from 'joi';
3131
import uuid from 'uuid';
32+
import { ensureNoUnsafeProperties } from '@kbn/std';
3233
import { HttpConfig } from './http_config';
33-
import { validateObject } from './prototype_pollution';
3434

3535
const corsAllowedHeaders = ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf'];
3636
/**
@@ -69,7 +69,7 @@ export function getServerOptions(config: HttpConfig, { configureTLS = true } = {
6969
// This is a default payload validation which applies to all LP routes which do not specify their own
7070
// `validate.payload` handler, in order to reduce the likelyhood of prototype pollution vulnerabilities.
7171
// (All NP routes are already required to specify their own validation in order to access the payload)
72-
payload: (value) => Promise.resolve(validateObject(value)),
72+
payload: (value) => Promise.resolve(ensureNoUnsafeProperties(value)),
7373
},
7474
},
7575
state: {

src/core/server/http/prototype_pollution/index.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/plugins/vis_type_timeseries/server/routes/vis.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import { IRouter, KibanaRequest } from 'kibana/server';
2121
import { schema } from '@kbn/config-schema';
22+
import { ensureNoUnsafeProperties } from '@kbn/std';
2223
import { getVisData, GetVisDataOptions } from '../lib/get_vis_data';
2324
import { visPayloadSchema } from '../../common/vis_schema';
2425
import { ROUTES } from '../../common/constants';
@@ -40,6 +41,14 @@ export const visDataRoutes = (
4041
},
4142
},
4243
async (requestContext, request, response) => {
44+
try {
45+
ensureNoUnsafeProperties(request.body);
46+
} catch (error) {
47+
return response.badRequest({
48+
body: error.message,
49+
});
50+
}
51+
4352
try {
4453
visPayloadSchema.validate(request.body);
4554
} catch (error) {

0 commit comments

Comments
 (0)