elements icon indicating copy to clipboard operation
elements copied to clipboard

Elements requires `eval` to function correctly

Open captn3m0 opened this issue 3 years ago • 3 comments

Context

Elements breaks on websites with a CSP disallowing eval. See https://endoflife.date/docs/api for eg. Initially reported here: https://github.com/endoflife-date/endoflife.date/issues/905

Current Behavior

In a restricted environment with a CSP policy denying the use of eval, JS doesn't function correctly breaking core functionality.

Expected Behavior

Elements should not rely on eval

Debug

I traced down the eval call to ajv which requires Eval support to function. ajv shows up in production because of httpsnippet.

yarn why ajv
yarn why v1.22.18
[1/4] Why do we have the module "ajv"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "[email protected]"
info Has been hoisted to "ajv"
info Reasons this module exists
   - "workspace-aggregator-3c23fdb0-4330-4f51-a315-d9e7a139f7fc" depends on it
   - Hoisted from "_project_#eslint#ajv"
   - Hoisted from "_project_#schema-utils#ajv"
   - Hoisted from "_project_#webpack-dev-server#schema-utils#ajv"
   - Hoisted from "_project_#@stoplight#elements-demo#eslint#ajv"
   - Hoisted from "_project_#@storybook#react#webpack#ajv"
   - Hoisted from "_project_#eslint#@eslint#eslintrc#ajv"
   - Hoisted from "_project_#@storybook#react#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#webpack#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#@storybook#core-common#webpack#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#fork-ts-checker-webpack-plugin#schema-utils#ajv"
   - Hoisted from "_project_#@stoplight#elements-core#httpsnippet#har-validator#ajv"
   - Hoisted from "_project_#@storybook#react#@pmmmwh#react-refresh-webpack-plugin#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#babel-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-postcss#css-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#css-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-postcss#postcss-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#style-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#webpack-dev-middleware#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#@storybook#core-common#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#webpack#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#@storybook#core-common#fork-ts-checker-webpack-plugin#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#css-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#style-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#postcss-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#builder-webpack4#terser-webpack-plugin#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#builder-webpack5#@storybook#core-common#webpack#terser-webpack-plugin#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#@storybook#manager-webpack4#webpack#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#@storybook#manager-webpack4#webpack#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#@storybook#manager-webpack4#css-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#@storybook#manager-webpack4#style-loader#schema-utils#ajv"
   - Hoisted from "_project_#@storybook#addon-docs#@storybook#core#@storybook#core-server#@storybook#manager-webpack4#terser-webpack-plugin#schema-utils#ajv"
info Disk size without dependencies: "1.12MB"
info Disk size with unique dependencies: "1.89MB"
info Disk size with transitive dependencies: "1.93MB"
info Number of shared dependencies: 5
=> Found "table#[email protected]"
info This module exists because "_project_#eslint#table" depends on it.
info Disk size without dependencies: "2.43MB"
info Disk size with unique dependencies: "3.13MB"
info Disk size with transitive dependencies: "3.18MB"
info Number of shared dependencies: 5
Done in 1.12s.

Steps to Reproduce

  1. Open https://endoflife.date/docs/api
  2. Click on "Your GET Endpoint" 3 Notice breakage. image

Environment

Directly using the web-components.min.js file from the unpkg. https://github.com/endoflife-date/endoflife.date/blob/master/_layouts/schema.html

  • Version used: Latest
  • Environment name and version (e.g. Chrome 39, node.js 5.4): Any
  • Operating System and version (desktop or mobile): Any
  • Link to your environment/workspace/project: https://github.com/endoflife-date/endoflife.date/blob/master/_layouts/schema.html

captn3m0 avatar May 04 '22 14:05 captn3m0

@captn3m0

Ajv is an external dependency that we don't have control over because we use Httpsnippet to generate code samples. A workaround is mentioned here: https://github.com/ajv-validator/ajv/blob/c3e203c2696e42ec107fe6a5a659fca54b2e4993/docs/security.md#content-security-policy

If this doesn't work for you let us know!

mnaumanali94 avatar May 12 '22 17:05 mnaumanali94

The workaround doesn't work, since httpsnippet does not offer a way to use the compiled schemas, and neither does elements.

captn3m0 avatar May 30 '22 08:05 captn3m0

Created an issue against httpsnippet to pre-compile the HAR schema: https://github.com/Kong/httpsnippet/issues/270

captn3m0 avatar May 30 '22 08:05 captn3m0

Cross-site scripting attacksunsafe-eval is NOT recommended in a secure CSP[1], as it has the potential to open the document to cross-site scripting (XSS) attacks.

The workaround isn’t feasible for lots of websites for security reasons as it introduces a huge attack surface.

captn3m0 avatar Oct 11 '22 07:10 captn3m0