@locker/eslint-plugin-unsafe-types
Version:
Detect usage of unsigned unsafe types.
194 lines (188 loc) • 10.6 kB
JavaScript
/** Original file https://github.com/eslint/eslint/blob/main/tests/lib/rules/no-eval.js
* @fileoverview Detect usage of unsigned eval calls.
* @author Lightning Web Security Team
*/
'use strict';
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const { RuleTester } = require('eslint');
const rule = require('../../../lib/rules/unsafe-eval');
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const ruleTester = new RuleTester({
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'script',
globals: {
window: 'readonly',
global: 'readonly',
globalThis: 'readonly',
setTimeout: 'readonly',
setInterval: 'readonly',
execScript: 'readonly',
},
},
});
ruleTester.run('unsafe-eval', rule, {
valid: [
{ code: 'Eval(foo)' },
{ code: "setTimeout('foo')" },
{ code: "setInterval('foo')" },
{ code: "window.setTimeout('foo')" },
{ code: "window.setInterval('foo')" },
{ code: "window.noeval('foo')" },
{ code: "function foo() { var eval = 'foo'; window[eval]('foo') }" },
{ code: "globalThis.noneval('foo')" },
{ code: "function foo() { var eval = 'foo'; globalThis[eval]('foo') }" },
{ code: "this.noeval('foo');" },
{ code: "function foo() { 'use strict'; this.eval('foo'); }" },
{ code: "var obj = {foo: function() { this.eval('foo'); }}" },
{ code: "var obj = {}; obj.foo = function() { this.eval('foo'); }" },
{ code: "function f() { 'use strict'; () => { this.eval('foo') } }" },
{ code: "(function f() { 'use strict'; () => { this.eval('foo') } })" },
{ code: 'class A { foo() { this.eval(); } }' },
{ code: 'class A { static foo() { this.eval(); } }' },
{ code: 'class A { field = this.eval(); }' },
{ code: 'class A { field = () => this.eval(); }' },
{ code: 'class A { static { this.eval(); } }' },
{
code: "array.findLast(function (x) { return this.eval.includes(x); }, { eval: ['foo', 'bar'] });",
},
{ code: 'callbacks.findLastIndex(function (cb) { return cb(this.eval); }, this);' },
{ code: "['1+1'].flatMap(function (str) { return this.eval(str); }, new Evaluator);" },
{ code: "eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "eval($A.$lockerService$.$trusted$.$createScript$('foo'))" },
{ code: "eval($A.lockerService.restricted.createScript('foo'))" },
{ code: "eval($A.$lockerService$.$restricted$.$createScript$('foo'))" },
{ code: 'eval($A.lockerService.trusted.createScript(foo))' },
{ code: "this.eval($A.lockerService.trusted.createScript('foo'));" },
{ code: "'use strict'; this.eval($A.lockerService.trusted.createScript('foo'));" },
{ code: "function foo(eval) { eval($A.lockerService.trusted.createScript('foo')) }" },
{ code: "function foo() { this.eval($A.lockerService.trusted.createScript('foo')); }" },
{ code: "() => { this.eval($A.lockerService.trusted.createScript('foo')) }" },
{ code: "window.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "global.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "globalThis.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "(0, eval)($A.lockerService.trusted.createScript('foo'))" },
{ code: "(0, window.eval)($A.lockerService.trusted.createScript('foo'))" },
{ code: "(0, window['eval'])($A.lockerService.trusted.createScript('foo'))" },
{ code: "() => { this.eval($A.lockerService.trusted.createScript('foo')); }" },
{
code: "() => { 'use strict'; this.eval($A.lockerService.trusted.createScript('foo')); }",
},
{
code: "'use strict'; () => { this.eval($A.lockerService.trusted.createScript('foo')); }",
},
{
code: "() => { 'use strict'; () => { this.eval($A.lockerService.trusted.createScript('foo')); } }",
},
{ code: "window.window.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "window.window['eval']($A.lockerService.trusted.createScript('foo'))" },
{ code: "global.global.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "global.global[`eval`]($A.lockerService.trusted.createScript('foo'))" },
{ code: "this.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "'use strict'; this.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "function foo() { this.eval($A.lockerService.trusted.createScript('foo')) }" },
{ code: "globalThis.globalThis.eval($A.lockerService.trusted.createScript('foo'))" },
{ code: "globalThis.globalThis['eval']($A.lockerService.trusted.createScript('foo'))" },
{ code: "(0, globalThis.eval)($A.lockerService.trusted.createScript('foo'))" },
{ code: "(0, globalThis['eval'])($A.lockerService.trusted.createScript('foo'))" },
{ code: "var EVAL = eval; EVAL($A.lockerService.trusted.createScript('foo'))" },
],
invalid: [
{
code: "eval(foo);eval($A.lockerService.trusted.createScript('foo'))",
errors: [{ messageId: 'unexpected' }],
},
{ code: 'eval(foo)', errors: [{ messageId: 'unexpected' }] },
{ code: "eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "function foo(eval) { eval('foo') }", errors: [{ messageId: 'unexpected' }] },
{ code: "function foo() { this.eval('foo'); }", errors: [{ messageId: 'unexpected' }] },
{ code: "() => { this.eval('foo') }", errors: [{ messageId: 'unexpected' }] },
{ code: "window.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "global.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(0, eval)('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(0, window.eval)('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(0, window['eval'])('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "var EVAL = eval; EVAL('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "var EVAL = this.eval; EVAL('foo')", errors: [{ messageId: 'unexpected' }] },
{
code: "var EVAL = this.eval; EVAL($A.lockerService.trusted.createScript('foo'))",
errors: [{ messageId: 'unexpected' }],
},
{
code: "'use strict'; var EVAL = this.eval; EVAL('foo')",
errors: [{ messageId: 'unexpected' }],
},
{
code: "'use strict'; var EVAL = this.eval; EVAL($A.lockerService.trusted.createScript('foo'))",
errors: [{ messageId: 'unexpected' }],
},
{ code: "() => { this.eval('foo'); }", errors: [{ messageId: 'unexpected' }] },
{
code: "() => { 'use strict'; this.eval('foo'); }",
errors: [{ messageId: 'unexpected' }],
},
{
code: "'use strict'; () => { this.eval('foo'); }",
errors: [{ messageId: 'unexpected' }],
},
{
code: "() => { 'use strict'; () => { this.eval('foo'); } }",
errors: [{ messageId: 'unexpected' }],
},
{ code: "(function(exe){ exe('foo') })(eval);", errors: [{ messageId: 'unexpected' }] },
{
code: "(function(exe){ exe($A.lockerService.trusted.createScript('foo')) })(eval);",
errors: [{ messageId: 'unexpected' }],
},
{ code: "window.window.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "window.window['eval']('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "global.global.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "global.global[`eval`]('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "this.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "'use strict'; this.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "function foo() { this.eval('foo') }", errors: [{ messageId: 'unexpected' }] },
{ code: "var EVAL = globalThis.eval; EVAL('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "globalThis.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "globalThis.globalThis.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "globalThis.globalThis['eval']('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(0, globalThis.eval)('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(0, globalThis['eval'])('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "window?.eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(window?.eval)('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "(window?.window).eval('foo')", errors: [{ messageId: 'unexpected' }] },
{ code: "class C { [this.eval('foo')] }", errors: [{ messageId: 'unexpected' }] },
{
code: "'use strict'; class C { [this.eval('foo')] }",
errors: [{ messageId: 'unexpected' }],
},
{ code: 'class A { static {} [this.eval()]; }', errors: [{ messageId: 'unexpected' }] },
{
code: "array.findLast(x => this.eval.includes(x), { eval: 'abc' });",
errors: [{ messageId: 'unexpected' }],
},
{
code: 'callbacks.findLastIndex(function (cb) { return cb(eval); }, this);',
errors: [{ messageId: 'unexpected' }],
},
{
code: "['1+1'].flatMap(function (str) { return this.eval(str); });",
errors: [{ messageId: 'unexpected' }],
},
{
code: "['1'].reduce(function (a, b) { return this.eval(a) ? a : b; }, '0');",
errors: [{ messageId: 'unexpected' }],
},
{
code: "eval($A.lockerService.trusted['createScript']('foo'))",
errors: [{ messageId: 'unexpected' }],
},
{
code: "eval($A.lockerService.trusted.createScript.call($A.lockerService.trusted, 'foo'))",
errors: [{ messageId: 'unexpected' }],
},
],
});