Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-security

Package Overview
Dependencies
Maintainers
6
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-security - npm Package Compare versions

Comparing version 1.7.0 to 1.7.1

test/utils/is-static-expression.js

7

CHANGELOG.md
# Changelog
### [1.7.1](https://www.github.com/eslint-community/eslint-plugin-security/compare/v1.7.0...v1.7.1) (2023-02-02)
### Bug Fixes
* false positives for static expressions in detect-non-literal-fs-filename, detect-child-process, detect-non-literal-regexp, and detect-non-literal-require ([#109](https://www.github.com/eslint-community/eslint-plugin-security/issues/109)) ([56102b5](https://www.github.com/eslint-community/eslint-plugin-security/commit/56102b50aed4bd632dd668770eb37de58788110b))
## [1.7.0](https://www.github.com/eslint-community/eslint-plugin-security/compare/v1.6.0...v1.7.0) (2023-01-26)

@@ -4,0 +11,0 @@

2

package.json
{
"name": "eslint-plugin-security",
"version": "1.7.0",
"version": "1.7.1",
"description": "Security rules for eslint",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -9,2 +9,3 @@ /**

const { getImportAccessPath } = require('../utils/import-utils');
const { isStaticExpression } = require('../utils/is-static-expression');
const childProcessPackageNames = ['child_process', 'node:child_process'];

@@ -45,3 +46,9 @@

// Reports non-literal `exec()` calls.
if (!node.arguments.length || node.arguments[0].type === 'Literal') {
if (
!node.arguments.length ||
isStaticExpression({
node: node.arguments[0],
scope: context.getScope(),
})
) {
return;

@@ -48,0 +55,0 @@ }

@@ -13,19 +13,5 @@ /**

const { getImportAccessPath } = require('../utils/import-utils');
const { isStaticExpression } = require('../utils/is-static-expression');
//------------------------------------------------------------------------------
// Utils
//------------------------------------------------------------------------------
function getIndices(node, argMeta) {
return (argMeta || []).filter((argIndex) => node.arguments[argIndex].type !== 'Literal');
}
function generateReport({ context, node, packageName, methodName, indices }) {
if (!indices || indices.length === 0) {
return;
}
context.report({ node, message: `Found ${methodName} from package "${packageName}" with non literal argument at index ${indices.join(',')}` });
}
//------------------------------------------------------------------------------
// Rule Definition

@@ -91,11 +77,19 @@ //------------------------------------------------------------------------------

const indices = getIndices(node, fsMetaData[fnName]);
generateReport({
context,
node,
packageName,
methodName: fnName,
indices,
});
const indices = [];
for (const index of fsMetaData[fnName] || []) {
if (index >= node.arguments.length) {
continue;
}
const argument = node.arguments[index];
if (isStaticExpression({ node: argument, scope: context.getScope() })) {
continue;
}
indices.push(index);
}
if (indices.length) {
context.report({
node,
message: `Found ${fnName} from package "${packageName}" with non literal argument at index ${indices.join(',')}`,
});
}
},

@@ -102,0 +96,0 @@ };

@@ -8,2 +8,4 @@ /**

const { isStaticExpression } = require('../utils/is-static-expression');
//------------------------------------------------------------------------------

@@ -28,3 +30,10 @@ // Rule Definition

const args = node.arguments;
if (args && args.length > 0 && args[0].type !== 'Literal') {
if (
args &&
args.length > 0 &&
!isStaticExpression({
node: args[0],
scope: context.getScope(),
})
) {
return context.report({ node: node, message: 'Found non-literal argument to RegExp Constructor' });

@@ -31,0 +40,0 @@ }

@@ -8,2 +8,4 @@ /**

const { isStaticExpression } = require('../utils/is-static-expression');
//------------------------------------------------------------------------------

@@ -29,4 +31,8 @@ // Rule Definition

if (
(args && args.length > 0 && args[0].type === 'TemplateLiteral' && args[0].expressions.length > 0) ||
(args[0].type !== 'TemplateLiteral' && args[0].type !== 'Literal')
args &&
args.length > 0 &&
!isStaticExpression({
node: args[0],
scope: context.getScope(),
})
) {

@@ -33,0 +39,0 @@ return context.report({ node: node, message: 'Found non-literal argument in require' });

@@ -53,2 +53,10 @@ 'use strict';

}`,
`
var child_process = require('child_process');
var FOO = 'ls';
child_process.exec(FOO);`,
`
import child_process from 'child_process';
const FOO = 'ls';
child_process.exec(FOO);`,
],

@@ -55,0 +63,0 @@ invalid: [

@@ -6,3 +6,3 @@ 'use strict';

parserOptions: {
ecmaVersion: 6,
ecmaVersion: 13,
sourceType: 'module',

@@ -28,2 +28,47 @@ },

},
{
code: `
import { promises as fsp } from 'fs';
import fs from 'fs';
import path from 'path';
const index = await fsp.readFile(path.resolve(__dirname, './index.html'), 'utf-8');
const key = fs.readFileSync(path.join(__dirname, './ssl.key'));
await fsp.writeFile(path.resolve(__dirname, './sitemap.xml'), sitemap);`,
globals: {
__dirname: 'readonly',
},
},
{
code: `
import fs from 'fs';
import path from 'path';
const dirname = path.dirname(__filename)
const key = fs.readFileSync(path.resolve(dirname, './index.html'));`,
globals: {
__filename: 'readonly',
},
},
{
code: `
import fs from 'fs';
const key = fs.readFileSync(\`\${process.cwd()}/path/to/foo.json\`);`,
globals: {
process: 'readonly',
},
},
`
import fs from 'fs';
import path from 'path';
import url from 'url';
const dirname = path.dirname(url.fileURLToPath(import.meta.url));
const html = fs.readFileSync(path.resolve(dirname, './index.html'), 'utf-8');`,
{
code: `
import fs from 'fs';
const pkg = fs.readFileSync(require.resolve('eslint/package.json'), 'utf-8');`,
globals: {
require: 'readonly',
},
},
],

@@ -146,3 +191,13 @@ invalid: [

},
{
code: `
import fs from 'fs';
import path from 'path';
const key = fs.readFileSync(path.resolve(__dirname, foo));`,
globals: {
__filename: 'readonly',
},
errors: [{ message: 'Found readFileSync from package "fs" with non literal argument at index 0' }],
},
],
});

@@ -10,3 +10,10 @@ 'use strict';

tester.run(ruleName, require(`../rules/${ruleName}`), {
valid: [{ code: "var a = new RegExp('ab+c', 'i')" }],
valid: [
{ code: "var a = new RegExp('ab+c', 'i')" },
{
code: `
var source = 'ab+c'
var a = new RegExp(source, 'i')`,
},
],
invalid: [

@@ -13,0 +20,0 @@ {

@@ -10,3 +10,17 @@ 'use strict';

tester.run(ruleName, require(`../rules/${ruleName}`), {
valid: [{ code: "var a = require('b')" }, { code: 'var a = require(`b`)' }],
valid: [
{ code: "var a = require('b')" },
{ code: 'var a = require(`b`)' },
{
code: `
const d = 'debounce'
var a = require(\`lodash/\${d}\`)`,
},
{
code: "const utils = require(__dirname + '/utils');",
globals: {
__dirname: 'readonly',
},
},
],
invalid: [

@@ -13,0 +27,0 @@ {

@@ -0,1 +1,3 @@

const { findVariable } = require('./find-variable');
module.exports.getImportAccessPath = getImportAccessPath;

@@ -185,13 +187,1 @@

}
/** @returns {import("eslint").Scope.Variable | null} */
function findVariable(scope, name) {
while (scope != null) {
const variable = scope.set.get(name);
if (variable != null) {
return variable;
}
scope = scope.upper;
}
return null;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc