From 99112c000f4dccee5738184407258b66b7cab2b5 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Mon, 22 Jan 2024 11:32:38 -0600 Subject: [PATCH] [data views] implement fallback sha1 hash for fields request (#175181) ## Summary tldr; The implements a fallback sha1 method when using the browser in an insecure context. The data views fields requests cache need uniqueness across users. This has been implemented by hashing the user object into a HTTP header using sha1. Typically we can use the browser's built in crypto objects for this HOWEVER its not available in insecure contexts - https://www.chromium.org/blink/webcrypto/#accessing-it - this PR supplies a sha1 function for insecure contexts. How to test - when running kibana locally, it will run in a secure context via 127.0.0.1 or localhost. It will run in an insecure context at 0.0.0.0. Simply load some sample data and load a data view. follow up to https://github.com/elastic/kibana/pull/168910 Screenshot of error resolved by this pr - ![Visualize Visualize Reporting Screenshots Print PDF button becomes available whe-c57ca69f29465527c4079569a4548eb10fe0568302776500148260b299fbd5c4](https://github.com/elastic/kibana/assets/216176/d7bcec41-631f-426f-b209-87b2d6403f23) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../public/data_views/data_views_api_client.ts | 15 ++++++++++----- .../public/data_views/sha256.test.ts | 18 ++++++++++++++++++ .../data_views/public/data_views/sha256.ts | 11 +++++++++++ src/plugins/data_views/tsconfig.json | 1 + 4 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 src/plugins/data_views/public/data_views/sha256.test.ts create mode 100644 src/plugins/data_views/public/data_views/sha256.ts diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts index 65b418642b34f..48d5db17c0915 100644 --- a/src/plugins/data_views/public/data_views/data_views_api_client.ts +++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts @@ -16,11 +16,16 @@ const API_BASE_URL: string = `/api/index_patterns/`; const version = '1'; async function sha1(str: string) { - const enc = new TextEncoder(); - const hash = await crypto.subtle.digest('SHA-1', enc.encode(str)); - return Array.from(new Uint8Array(hash)) - .map((v) => v.toString(16).padStart(2, '0')) - .join(''); + if (crypto.subtle) { + const enc = new TextEncoder(); + const hash = await crypto.subtle.digest('SHA-256', enc.encode(str)); + return Array.from(new Uint8Array(hash)) + .map((v) => v.toString(16).padStart(2, '0')) + .join(''); + } else { + const { sha256 } = await import('./sha256'); + return sha256(str); + } } /** diff --git a/src/plugins/data_views/public/data_views/sha256.test.ts b/src/plugins/data_views/public/data_views/sha256.test.ts new file mode 100644 index 0000000000000..325f83c88433b --- /dev/null +++ b/src/plugins/data_views/public/data_views/sha256.test.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +import { sha256 } from './sha256'; +import { createHash } from 'crypto'; + +describe('@kbn/crypto-browser', () => { + test('sha256 equals built in sha256', async function () { + const content = 'hello world'; + + expect(await sha256(content)).toEqual(createHash('sha256').update(content).digest('hex')); + }); +}); diff --git a/src/plugins/data_views/public/data_views/sha256.ts b/src/plugins/data_views/public/data_views/sha256.ts new file mode 100644 index 0000000000000..dea53f74eeb56 --- /dev/null +++ b/src/plugins/data_views/public/data_views/sha256.ts @@ -0,0 +1,11 @@ +/* + * 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. + */ + +import { Sha256 } from '@kbn/crypto-browser'; + +export const sha256 = async (str: string) => new Sha256().update(str).digest('hex'); diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json index 1d414cb98ee95..13fc03be53996 100644 --- a/src/plugins/data_views/tsconfig.json +++ b/src/plugins/data_views/tsconfig.json @@ -34,6 +34,7 @@ "@kbn/core-saved-objects-server", "@kbn/logging", "@kbn/security-plugin-types-public", + "@kbn/crypto-browser", ], "exclude": [ "target/**/*",