Skip to content

Commit

Permalink
Merge with main
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecote committed Aug 26, 2024
2 parents 48806ca + 64b79d7 commit 426a306
Show file tree
Hide file tree
Showing 347 changed files with 5,895 additions and 4,940 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ examples/guided_onboarding_example @elastic/appex-sharedux
src/plugins/guided_onboarding @elastic/appex-sharedux
packages/kbn-handlebars @elastic/kibana-security
packages/kbn-hapi-mocks @elastic/kibana-core
test/plugin_functional/plugins/hardening @elastic/kibana-security
packages/kbn-health-gateway-server @elastic/kibana-core
examples/hello_world @elastic/kibana-core
src/plugins/home @elastic/kibana-core
Expand Down Expand Up @@ -1351,7 +1352,9 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib
/packages/kbn-std/src/parse_next_url.ts @elastic/kibana-core @elastic/kibana-security
/test/interactive_setup_api_integration/ @elastic/kibana-security
/test/interactive_setup_functional/ @elastic/kibana-security
/test/plugin_functional/plugins/hardening @elastic/kibana-security
/test/plugin_functional/test_suites/core_plugins/rendering.ts @elastic/kibana-security
/test/plugin_functional/test_suites/hardening @elastic/kibana-security
/x-pack/test/accessibility/apps/group1/login_page.ts @elastic/kibana-security
/x-pack/test/accessibility/apps/group1/roles.ts @elastic/kibana-security
/x-pack/test/accessibility/apps/group1/spaces.ts @elastic/kibana-security
Expand Down
5 changes: 5 additions & 0 deletions config/serverless.security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,8 @@ xpack.ml.compatibleModuleType: 'security'

# Disable the embedded Dev Console
console.ui.embeddedEnabled: false

# mTLS cert paths for agentless-api calls
xpack.fleet.agentless.api.tls.certificate: "/mnt/elastic-internal/http-certs/tls.crt"
xpack.fleet.agentless.api.tls.key: "/mnt/elastic-internal/http-certs/tls.key"
xpack.fleet.agentless.api.tls.ca: "/mnt/elastic-internal/http-certs/ca.crt"
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,58 @@ This event will be indexed with the following structure:
}
```

#### Add custom metrics
Having `kibana:plugin_render_time` metric event is not always enough, depending on the use case you would likely need some complementary information to give some sense to the value reported by the metric (e.g. number of hosts, number of services, number of dataStreams, etc).
`kibana:plugin_render_time` metric API supports up to 9 numbered free fields that can be used to report numeric metrics that you intend to analyze. Note that they can be used for any type of numeric information you may want to report.

We could make use of these custom metrics using the following format:

```typescript
...
// Call onPageReady once the meaningful data has rendered and visible to the user
onPageReady({
key1: 'datasets',
value1: 5,
key2: 'documents',
value2: 1000,
});
...
```

where the `keys` will be the keys for the custom metrics we can later aggregate and analyze further.

An event using custom metrics will be indexed with the following structure:

```typescript
{
"_index": "backing-ebt-kibana-browser-performance-metrics-000001", // Performance metrics are stored in a dedicated simplified index (browser \ server).
"_source": {
"timestamp": "2024-08-13T11:29:58.275Z"
"event_type": "performance_metric", // All performance events share a common event type to simplify mapping
"eventName": 'kibana:plugin_render_time', // Event name as specified when reporting it
"duration": 736, // Event duration as specified when reporting it
"meta": {
"target": '/home',
},
"context": { // Context holds information identifying the deployment, version, application and page that generated the event
"version": "8.16.0-SNAPSHOT",
"cluster_name": "elasticsearch",
"pageName": "application:home:app",
"applicationId": "home",
"page": "app",
"entityId": "61c58ad0-3dd3-11e8-b2b9-5d5dc1715159",
"branch": "main",
...
},
"key1": "datasets",
"value1": 5,
"key2": "documents",
"value2": 1000,
...
},
}
```

### Development environment

The metric will be delivered to the [Telemetry Staging](https://telemetry-v2-staging.elastic.dev/) cluster, alongside with the event's context.
Expand Down
29 changes: 15 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@
"@kbn/guided-onboarding-plugin": "link:src/plugins/guided_onboarding",
"@kbn/handlebars": "link:packages/kbn-handlebars",
"@kbn/hapi-mocks": "link:packages/kbn-hapi-mocks",
"@kbn/hardening-plugin": "link:test/plugin_functional/plugins/hardening",
"@kbn/health-gateway-server": "link:packages/kbn-health-gateway-server",
"@kbn/hello-world-plugin": "link:examples/hello_world",
"@kbn/home-plugin": "link:src/plugins/home",
Expand Down Expand Up @@ -1294,10 +1295,10 @@
"@frsource/cypress-plugin-visual-regression-diff": "^3.3.10",
"@istanbuljs/nyc-config-typescript": "^1.0.2",
"@istanbuljs/schema": "^0.1.2",
"@jest/console": "^29.6.1",
"@jest/reporters": "^29.6.1",
"@jest/console": "^29.7.0",
"@jest/reporters": "^29.7.0",
"@jest/transform": "^29.6.1",
"@jest/types": "^29.6.1",
"@jest/types": "^29.6.3",
"@kayahr/text-encoding": "^1.3.0",
"@kbn/alerting-api-integration-helpers": "link:x-pack/test/alerting_api_integration/packages/helpers",
"@kbn/ambient-common-types": "link:packages/kbn-ambient-common-types",
Expand Down Expand Up @@ -1631,7 +1632,7 @@
"argsplit": "^1.0.5",
"autoprefixer": "^10.4.7",
"axe-core": "^4.10.0",
"babel-jest": "^29.6.1",
"babel-jest": "^29.7.0",
"babel-loader": "^8.2.5",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-istanbul": "^6.1.1",
Expand Down Expand Up @@ -1685,7 +1686,7 @@
"eslint-plugin-react-perf": "^3.3.1",
"eslint-traverse": "^1.0.0",
"exit-hook": "^2.2.0",
"expect": "^29.6.1",
"expect": "^29.7.0",
"expose-loader": "^0.7.5",
"express": "^4.19.2",
"faker": "^5.1.0",
Expand All @@ -1704,16 +1705,16 @@
"http2-proxy": "^5.0.53",
"http2-wrapper": "^2.2.1",
"ignore": "^5.3.0",
"jest": "^29.6.1",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.5.2",
"jest-cli": "^29.6.1",
"jest-config": "^29.6.1",
"jest-diff": "^29.6.1",
"jest-environment-jsdom": "^29.6.1",
"jest-matcher-utils": "^29.6.1",
"jest-mock": "^29.6.1",
"jest-runtime": "^29.6.1",
"jest-snapshot": "^29.6.1",
"jest-cli": "^29.7.0",
"jest-config": "^29.7.0",
"jest-diff": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-matcher-utils": "^29.7.0",
"jest-mock": "^29.7.0",
"jest-runtime": "^29.7.0",
"jest-snapshot": "^29.7.0",
"jest-specific-snapshot": "^8.0.0",
"jest-styled-components": "7.0.3",
"jsdom": "^20.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const roleEditor = 'editor';
const cloudUsersFilePath = resolve(REPO_ROOT, SERVERLESS_ROLES_ROOT_PATH, 'role_users.json');

const createLocalSAMLSessionMock = jest.spyOn(samlAuth, 'createLocalSAMLSession');
const createCloudSAMLSessionMock = jest.spyOn(samlAuth, 'createCloudSAMLSession');
const getSecurityProfileMock = jest.spyOn(samlAuth, 'getSecurityProfile');
const readCloudUsersFromFileMock = jest.spyOn(helper, 'readCloudUsersFromFile');
const isValidHostnameMock = jest.spyOn(helper, 'isValidHostname');
Expand All @@ -41,6 +40,11 @@ jest.mock('../kbn_client/kbn_client', () => {
const get = jest.fn();

describe('SamlSessionManager', () => {
let createCloudSAMLSessionMock: jest.SpyInstance;
beforeEach(() => {
createCloudSAMLSessionMock = jest.spyOn(samlAuth, 'createCloudSAMLSession');
});

describe('for local session', () => {
beforeEach(() => {
jest.resetAllMocks();
Expand Down Expand Up @@ -199,6 +203,7 @@ describe('SamlSessionManager', () => {
});

test('should throw error if TEST_CLOUD_HOST_NAME is not set', async () => {
createCloudSAMLSessionMock.mockRestore();
isValidHostnameMock.mockReturnValueOnce(false);
const samlSessionManager = new SamlSessionManager(samlSessionManagerOptions);
await expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,11 @@ kibana_vars=(
xpack.securitySolution.packagerTaskInterval
xpack.securitySolution.prebuiltRulesPackageVersion
xpack.spaces.maxSpaces
xpack.task_manager.capacity
xpack.task_manager.claim_strategy
xpack.task_manager.discovery.active_nodes_lookback
xpack.task_manager.discovery.interval
xpack.task_manager.kibanas_per_partition
xpack.task_manager.max_attempts
xpack.task_manager.max_workers
xpack.task_manager.monitored_aggregated_stats_refresh_rate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ describe('Elasticsearch blob storage', () => {
esBlobStorage = createEsBlobStorage({ chunkSize: '1024B' });
const { id } = await esBlobStorage.upload(Readable.from([fileString]));
expect(await getAllDocCount()).toMatchObject({ count: 37 });
esRefreshIndexSpy.mockReset();
esRefreshIndexSpy.mockClear();
const rs = await esBlobStorage.download({ id });
expect(esRefreshIndexSpy).toHaveBeenCalled(); // Make sure we refresh the index before downloading the chunks
const chunks: string[] = [];
Expand Down Expand Up @@ -141,7 +141,7 @@ describe('Elasticsearch blob storage', () => {
const { id } = await esBlobStorage.upload(Readable.from([fileString]));
const { id: id2 } = await esBlobStorage.upload(Readable.from([fileString2]));
expect(await getAllDocCount()).toMatchObject({ count: 10 });
esRefreshIndexSpy.mockReset();
esRefreshIndexSpy.mockClear();
await esBlobStorage.delete(id);
expect(esRefreshIndexSpy).toHaveBeenCalled(); // Make sure we refresh the index before deleting the chunks
expect(await getAllDocCount()).toMatchObject({ count: 2 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ describe('convertToPercentileColumns', () => {
if (expected === null) {
expect(convertToPercentileColumns(...input)).toBeNull();
} else if (Array.isArray(expected)) {
expect(convertToPercentileColumns(...input)).toEqual(expected.map(expect.objectContaining));
expect(convertToPercentileColumns(...input)).toEqual(
expected.map((el) => (el === null ? null : expect.objectContaining(el)))
);
} else {
expect(convertToPercentileColumns(...input)).toEqual(expect.objectContaining(expected));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ describe('convertToPercentileRankColumns', () => {
expect(convertToPercentileRankColumns(...input)).toBeNull();
} else if (Array.isArray(expected)) {
expect(convertToPercentileRankColumns(...input)).toEqual(
expected.map(expect.objectContaining)
expected.map((el) => (el === null ? null : expect.objectContaining(el)))
);
} else {
expect(convertToPercentileRankColumns(...input)).toEqual(expect.objectContaining(expected));
Expand Down
7 changes: 7 additions & 0 deletions src/setup_node_env/harden/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
var ritm = require('require-in-the-middle');
var lodashPatch = require('./lodash_template');
var patchChildProcess = require('./child_process');
var hardenPrototypes = require('./prototype');

// the performance cost of using require-in-the-middle is atm directly related to the number of
// registered hooks (as require is patched once for EACH hook)
Expand Down Expand Up @@ -39,3 +40,9 @@ new ritm.Hook(
return module;
}
);

// Use of the `KBN_UNSAFE_DISABLE_PROTOTYPE_HARDENING` environment variable is discouraged, and should only be set to facilitate testing
// specific scenarios. This should never be set in production.
if (!process.env.KBN_UNSAFE_DISABLE_PROTOTYPE_HARDENING) {
hardenPrototypes();
}
29 changes: 29 additions & 0 deletions src/setup_node_env/harden/prototype.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

function hardenPrototypes() {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal
// > The Object.seal() static method seals an object.
// > Sealing an object prevents extensions and makes existing properties non-configurable.
// > A sealed object has a fixed set of properties: new properties cannot be added, existing properties cannot be removed,
// > their enumerability and configurability cannot be changed, and its prototype cannot be re-assigned.
// > Values of existing properties can still be changed as long as they are writable.
// Object.freeze would take this one step further, and prevent the values of the properties from being changed as well.
// This is not currently feasible for Kibana, as this functionality is required for some of the libraries that we use, such as react-dom/server.
// While Object.seal() is not a silver bullet, it does provide a good balance between security and compatibility.
// The goal is to prevent a majority of prototype pollution vulnerabilities that can be exploited by an attacker.

Object.seal(Object.prototype);
Object.seal(Number.prototype);
Object.seal(String.prototype);
Object.seal(Function.prototype);

// corejs currently manipulates Array.prototype, so we cannot seal it.
}

module.exports = hardenPrototypes;
3 changes: 3 additions & 0 deletions test/harden/child_process.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Side Public License, v 1.
*/

// We must disable prototype hardening to test the pollution
process.env.KBN_UNSAFE_DISABLE_PROTOTYPE_HARDENING = 'true';

require('../../src/setup_node_env');

const cp = require('child_process');
Expand Down
3 changes: 3 additions & 0 deletions test/harden/lodash_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Side Public License, v 1.
*/

// We must disable prototype hardening to test the pollution
process.env.KBN_UNSAFE_DISABLE_PROTOTYPE_HARDENING = 'true';

require('../../src/setup_node_env');
const _ = require('lodash');
// eslint-disable-next-line no-restricted-modules
Expand Down
Loading

0 comments on commit 426a306

Please sign in to comment.