elements
elements copied to clipboard
Elements requires `eval` to function correctly
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
- Open https://endoflife.date/docs/api
- Click on "Your GET Endpoint"
3 Notice breakage.

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
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!
The workaround doesn't work, since httpsnippet does not offer a way to use the compiled schemas, and neither does elements.
Created an issue against httpsnippet to pre-compile the HAR schema: https://github.com/Kong/httpsnippet/issues/270
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.