stylelint: table sub-dependency Ajv breaking Stylelint in environments with blocked eval
Describe the issue. Is it a bug or a feature request (new rule, new option, etc.)?
It seems that in table@3.7.10 a dependency on ajv was brought in from https://github.com/gajus/table/pull/16. Unfortunately it seems this library uses eval to compile the JSON it is asked to validate. table@3.7.9 looks like it should still be safe to run in environments where that is blocked like Atom.
There are a few ways to move forward here:
- Have Ajv update to no longer
eval(unlikely, this looks to be a major part of how it works) - Have
tablemove away fromunsafe-evaldependencies - Move away from
tablehere instylelint - Give up on keeping
stylelintable to run in environments whereevalis blocked, and havelinter-stylelint(and any other place that is usingstylelintin an environment like this) run this package through a wrapper library.
Which rule, if any, is this issue related to?
N/A
What CSS is needed to reproduce this issue?
N/A
What stylelint configuration is needed to reproduce this issue?
N/A
Which version of stylelint are you using?
6.0.0 through 7.2.0 (table dependency introduced in https://github.com/stylelint/stylelint/commit/06b0fcd8105319870e1e87c990f10c95587bea62)
How are you running stylelint: CLI, PostCSS plugin, Node API?
Node API
Does your issue relate to non-standard syntax (e.g. SCSS, nesting, etc.)?
N/A
What did you expect to happen?
No unsafe-eval code being ran.
What actually happened (e.g. what warnings or errors you are getting)?
The following error is being thrown:
Stack trace:
EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'".
at Ajv.localCompile (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/compile/index.js:130:26)
at Ajv.resolve (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/compile/resolve.js:53:19)
at Object.resolveRef (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/compile/index.js:195:21)
at Object.generate_ref [as code] (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/dotjs/ref.js:22:22)
at Object.generate_validate [as validate] (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/dotjs/validate.js:157:37)
at Object.generate_properties [as code] (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/dotjs/properties.js:198:26)
at generate_validate (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/dotjs/validate.js:230:37)
at localCompile (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/compile/index.js:91:22)
at Ajv.compile (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/compile/index.js:59:13)
at _compile (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:325:29)
at getSchema (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:189:51)
at validate (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:88:11)
at validateSchema (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:159:19)
at _addSchema (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:285:7)
at Ajv.compile (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/ajv.js:110:21)
at Ajv.addKeyword (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv/lib/keyword.js:46:40)
at defFunc (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv-keywords/keywords/typeof.js:37:7)
at defineKeywords (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/ajv-keywords/index.js:20:17)
at Object.<anonymous> (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/table/dist/validateConfig.js:29:27)
at Module._compile (/Applications/Atom.app/Contents/Resources/app.asar/src/native-compile-cache.js:103:30)
at Object.defineProperty.value [as .js] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:208:21)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (/Applications/Atom.app/Contents/Resources/app.asar/src/native-compile-cache.js:50:27)
at Object.<anonymous> (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/table/dist/makeConfig.js:15:23)
at Module._compile (/Applications/Atom.app/Contents/Resources/app.asar/src/native-compile-cache.js:103:30)
at Object.defineProperty.value [as .js] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:208:21)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (/Applications/Atom.app/Contents/Resources/app.asar/src/native-compile-cache.js:50:27)
at Object.<anonymous> (/Users/lorisbettazza/.atom/packages/linter-stylelint/node_modules/table/dist/table.js:15:19)
at Module._compile (/Applications/Atom.app/Contents/Resources/app.asar/src/native-compile-cache.js:103:30)
at Object.defineProperty.value [as .js] (/Applications/Atom.app/Contents/Resources/app.asar/src/compile-cache.js:208:21)
at Module.load (module.js:357:32)
_Note: Originally filed under https://github.com/AtomLinter/linter-stylelint/issues/269._
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 5
- Comments: 33 (21 by maintainers)
My mistake, sorry – forgot that
NODE_ENVdefaults todevelopment. To fix it, I have added a prepublish step that rebuilds the package usingNODE_ENV=production.v3.8.3 has been published.
Maybe there is a library simpler than
tablethat we can use in stylelint, since we hardly use any oftable’s real capabilities. I don’t think ajv has to be involved to accomplish the simple layout that we need.I am definitely going to implement pre-compiling schemas into functions - it was an old plan anyway and there are other reasons to do it (browser bundle size, also see epoberezkin/ajv#156). Table package will be able to use precompiled schemas so there will be no dynamic code evaluation there. I will make a PR within 2-4 weeks.
If you want it resolved quicker, using the loophole can be a temporary solution, which later can be reverted, it’s up to you. I see no harm in sticking with the previous version of table for this time.
Generally speaking, I think allowing dynamic code evaluation (via Function constructor only) is the right thing - there are quite a few use cases that are difficult/much slower otherwise. That’s not my call to estimate which security risks it introduces… Although I think that crippling JavaScript under security pretence is not the right thing. It could have been a bit more granular - for example, they could have crippled generated code instead. Maybe I just like using generated code…
Does Atom allow to require other scripts?
If you look into Node.js source code, you will learn that require is using vm to run all the code. VM = eval.
I don’t see it as an issue to depend on
evalcode.As a short term solution, just restrict table version to
table@3.7.9in your package.json.table v3.8.3 works, thanks! 🎉
omg, I think we somehow managed to publish instrumented version of table package… That is good that it was broken at least, or we could have missed it.