From f78b9153b5f62a566963709a4e1d738f52635090 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 19 May 2021 10:06:52 -0400 Subject: [PATCH] Ban use of lodash.template (#100277) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .eslintrc.js | 64 ++++++++++++++----- src/setup_node_env/harden/lodash_template.js | 5 ++ test/harden/lodash_template.js | 2 + .../logs/log_filter/log_filter_state.ts | 2 +- .../pages/link_to/redirect_to_node_logs.tsx | 4 +- .../pages/logs/settings/form_elements.tsx | 2 +- .../components/node_details/tabs/logs.tsx | 2 +- .../shared/field_value_suggestions/index.tsx | 2 +- .../public/hooks/use_values_list.ts | 2 +- .../osquery/public/agents/agents_table.tsx | 2 +- .../public/common/store/sourcerer/helpers.ts | 3 +- .../rules/step_define_rule/index.tsx | 4 +- .../public/timelines/containers/api.ts | 4 +- .../overview/query_bar/use_query_bar.ts | 2 +- 14 files changed, 67 insertions(+), 33 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 20875a2c2913df..a4ce657d523d95 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -711,6 +711,33 @@ module.exports = { name: 'lodash/fp/assocPath', message: 'Please use @elastic/safer-lodash-set instead', }, + { + name: 'lodash', + importNames: ['template'], + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, + { + name: 'lodash.template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, + { + name: 'lodash/template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, + { + name: 'lodash/fp', + importNames: ['template'], + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, + { + name: 'lodash/fp/template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, { name: 'react-use', message: 'Please use react-use/lib/{method} instead.', @@ -730,6 +757,11 @@ module.exports = { name: 'lodash.setwith', message: 'Please use @elastic/safer-lodash-set instead', }, + { + name: 'lodash.template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, { name: 'lodash/set', message: 'Please use @elastic/safer-lodash-set instead', @@ -738,6 +770,11 @@ module.exports = { name: 'lodash/setWith', message: 'Please use @elastic/safer-lodash-set instead', }, + { + name: 'lodash/template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, ], }, ], @@ -753,6 +790,18 @@ module.exports = { property: 'set', message: 'Please use @elastic/safer-lodash-set instead', }, + { + object: 'lodash', + property: 'template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, + { + object: '_', + property: 'template', + message: + 'lodash.template is unsafe, and not compatible with our content security policy.', + }, { object: 'lodash', property: 'setWith', @@ -1576,20 +1625,5 @@ module.exports = { '@typescript-eslint/prefer-ts-expect-error': 'error', }, }, - { - files: [ - '**/public/**/*.{js,mjs,ts,tsx}', - '**/common/**/*.{js,mjs,ts,tsx}', - 'packages/**/*.{js,mjs,ts,tsx}', - ], - rules: { - 'no-restricted-imports': [ - 'error', - { - patterns: ['lodash/*', '!lodash/fp', 'rxjs/internal-compatibility'], - }, - ], - }, - }, ], }; diff --git a/src/setup_node_env/harden/lodash_template.js b/src/setup_node_env/harden/lodash_template.js index a0f181eab08fc9..3379cbfdeeb948 100644 --- a/src/setup_node_env/harden/lodash_template.js +++ b/src/setup_node_env/harden/lodash_template.js @@ -10,6 +10,8 @@ var hook = require('require-in-the-middle'); var isIterateeCall = require('lodash/_isIterateeCall'); hook(['lodash'], function (lodash) { + // we use lodash.template here to harden third-party usage of this otherwise banned function. + // eslint-disable-next-line no-restricted-properties lodash.template = createProxy(lodash.template); return lodash; }); @@ -52,6 +54,9 @@ function createFpProxy(template) { // > Iteratee arguments are capped to avoid gotchas with variadic iteratees. // this means that we can't specify the options in the second argument to fp.template because it's ignored. // Instead, we're going to use the non-FP _.template with only the first argument which has already been patched + + // we use lodash.template here to harden third-party usage of this otherwise banned function. + // eslint-disable-next-line no-restricted-properties return _.template(args[0]); }, }); diff --git a/test/harden/lodash_template.js b/test/harden/lodash_template.js index ad70f88ad22c5f..b04f8ad66275ab 100644 --- a/test/harden/lodash_template.js +++ b/test/harden/lodash_template.js @@ -8,6 +8,7 @@ require('../../src/setup_node_env'); const _ = require('lodash'); +// eslint-disable-next-line no-restricted-modules const template = require('lodash/template'); const fp = require('lodash/fp'); const fpTemplate = require('lodash/fp/template'); @@ -24,6 +25,7 @@ test('test setup ok', (t) => { t.end(); }); +// eslint-disable-next-line no-restricted-properties [_.template, template].forEach((fn) => { test(`_.template('<%= foo %>')`, (t) => { const output = fn('<%= foo %>')({ foo: 'bar' }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts index 6a78d7c6f94bc3..d4cb7ca90541f2 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts @@ -7,7 +7,7 @@ import createContainer from 'constate'; import { useCallback, useState } from 'react'; -import { useDebounce } from 'react-use'; +import useDebounce from 'react-use/lib/useDebounce'; import { esQuery, IIndexPattern, Query } from '../../../../../../../src/plugins/data/public'; type ParsedQuery = ReturnType; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 82e3813bde886d..bc8c5699229d81 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -6,9 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -// Prefer importing entire lodash library, e.g. import { get } from "lodash" -// eslint-disable-next-line no-restricted-imports -import flowRight from 'lodash/flowRight'; +import { flowRight } from 'lodash'; import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; import useMount from 'react-use/lib/useMount'; diff --git a/x-pack/plugins/infra/public/pages/logs/settings/form_elements.tsx b/x-pack/plugins/infra/public/pages/logs/settings/form_elements.tsx index 751d9762b937a3..90504a691cb95c 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/form_elements.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/form_elements.tsx @@ -7,7 +7,7 @@ import equal from 'fast-deep-equal'; import { useCallback, useMemo, useState } from 'react'; -import { useAsync } from 'react-use'; +import useAsync from 'react-use/lib/useAsync'; import { ObjectEntries } from '../../../../common/utility_types'; import { ChildFormValidationError, GenericValidationError } from './validation_errors'; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx index 4fa9fdf8cdd4a3..b792078c394e99 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/logs.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo, useState } from 'react'; -import { useThrottle } from 'react-use'; +import useThrottle from 'react-use/lib/useThrottle'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiFieldSearch } from '@elastic/eui'; diff --git a/x-pack/plugins/observability/public/components/shared/field_value_suggestions/index.tsx b/x-pack/plugins/observability/public/components/shared/field_value_suggestions/index.tsx index 359710e4b9c59b..ebe1111337919b 100644 --- a/x-pack/plugins/observability/public/components/shared/field_value_suggestions/index.tsx +++ b/x-pack/plugins/observability/public/components/shared/field_value_suggestions/index.tsx @@ -7,7 +7,7 @@ import React, { useState } from 'react'; -import { useDebounce } from 'react-use'; +import useDebounce from 'react-use/lib/useDebounce'; import { useValuesList } from '../../../hooks/use_values_list'; import { FieldValueSelection } from './field_value_selection'; import { FieldValueSuggestionsProps } from './types'; diff --git a/x-pack/plugins/observability/public/hooks/use_values_list.ts b/x-pack/plugins/observability/public/hooks/use_values_list.ts index 8d6e0abb896b3a..ff133d07489b06 100644 --- a/x-pack/plugins/observability/public/hooks/use_values_list.ts +++ b/x-pack/plugins/observability/public/hooks/use_values_list.ts @@ -7,7 +7,7 @@ import { capitalize, union } from 'lodash'; import { useEffect, useState } from 'react'; -import { useDebounce } from 'react-use'; +import useDebounce from 'react-use/lib/useDebounce'; import { IndexPattern } from '../../../../../src/plugins/data/common'; import { ESFilter } from '../../../../../typings/elasticsearch'; import { createEsParams, useEsSearch } from './use_es_search'; diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index 7f57f70e459dad..7e8f49c051614d 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -9,7 +9,7 @@ import { find } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { EuiComboBox, EuiHealth, EuiHighlight, EuiSpacer } from '@elastic/eui'; -import { useDebounce } from 'react-use'; +import useDebounce from 'react-use/lib/useDebounce'; import { useAllAgents } from './use_all_agents'; import { useAgentGroups } from './use_agent_groups'; import { useOsqueryPolicies } from './use_osquery_policies'; diff --git a/x-pack/plugins/security_solution/public/common/store/sourcerer/helpers.ts b/x-pack/plugins/security_solution/public/common/store/sourcerer/helpers.ts index 7d817ad30f1a0c..fd3a6f1fab3c11 100644 --- a/x-pack/plugins/security_solution/public/common/store/sourcerer/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/store/sourcerer/helpers.ts @@ -5,8 +5,7 @@ * 2.0. */ -// eslint-disable-next-line no-restricted-imports -import isEmpty from 'lodash/isEmpty'; +import { isEmpty } from 'lodash'; import { SourcererModel, SourcererScopeName } from './model'; import { TimelineEventsType } from '../../../../common/types/timeline'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index 29342bd32298eb..162f86c543308e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -8,9 +8,7 @@ import { EuiButtonEmpty, EuiFormRow, EuiSpacer } from '@elastic/eui'; import React, { FC, memo, useCallback, useState, useEffect } from 'react'; import styled from 'styled-components'; -// Prefer importing entire lodash library, e.g. import { get } from "lodash" -// eslint-disable-next-line no-restricted-imports -import isEqual from 'lodash/isEqual'; +import { isEqual } from 'lodash'; import { IndexPattern } from 'src/plugins/data/public'; import { DEFAULT_INDEX_KEY } from '../../../../../common/constants'; diff --git a/x-pack/plugins/security_solution/public/timelines/containers/api.ts b/x-pack/plugins/security_solution/public/timelines/containers/api.ts index d1c798a27b6c4f..e591685a31829d 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/api.ts +++ b/x-pack/plugins/security_solution/public/timelines/containers/api.ts @@ -8,9 +8,7 @@ import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; -// Prefer importing entire lodash library, e.g. import { get } from "lodash" -// eslint-disable-next-line no-restricted-imports -import isEmpty from 'lodash/isEmpty'; +import { isEmpty } from 'lodash'; import { throwErrors } from '../../../../cases/common'; import { diff --git a/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts b/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts index 164231bfdd89bd..2f2d8bf092ddfa 100644 --- a/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts +++ b/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts @@ -6,7 +6,7 @@ */ import React, { useCallback, useState } from 'react'; -import { useDebounce } from 'react-use'; +import useDebounce from 'react-use/lib/useDebounce'; import { useDispatch } from 'react-redux'; import { Query } from 'src/plugins/data/common'; import { useGetUrlParams, useUpdateKueryString, useUrlParams } from '../../../hooks';