99// Rule Definition
1010//------------------------------------------------------------------------------
1111
12- /*
13- * Stores variable names pointing to child_process to check (child_process).exec()
14- */
15- const names = [ ] ;
16-
1712module . exports = {
1813 meta : {
1914 type : 'error' ,
@@ -25,22 +20,44 @@ module.exports = {
2520 } ,
2621 } ,
2722 create : function ( context ) {
23+ /*
24+ * Stores variable identifiers pointing to child_process to check (child_process).exec()
25+ */
26+ const childProcessIdentifiers = new Set ( ) ;
27+
28+ /**
29+ * Extract identifiers assigned the expression `require("child_process")`.
30+ * @param {Pattern } node
31+ */
32+ function extractChildProcessIdentifiers ( node ) {
33+ if ( node . type !== 'Identifier' ) {
34+ return ;
35+ }
36+ const variable = context . getScope ( ) . set . get ( node . name ) ;
37+ if ( ! variable ) {
38+ return ;
39+ }
40+ for ( const reference of variable . references ) {
41+ childProcessIdentifiers . add ( reference . identifier ) ;
42+ }
43+ }
44+
2845 return {
2946 CallExpression : function ( node ) {
3047 if ( node . callee . name === 'require' ) {
3148 const args = node . arguments [ 0 ] ;
3249 if ( args && args . type === 'Literal' && args . value === 'child_process' ) {
3350 if ( node . parent . type === 'VariableDeclarator' ) {
34- names . push ( node . parent . id . name ) ;
51+ extractChildProcessIdentifiers ( node . parent . id ) ;
3552 } else if ( node . parent . type === 'AssignmentExpression' && node . parent . operator === '=' ) {
36- names . push ( node . parent . left . name ) ;
53+ extractChildProcessIdentifiers ( node . parent . left ) ;
3754 }
3855 return context . report ( { node : node , message : 'Found require("child_process")' } ) ;
3956 }
4057 }
4158 } ,
4259 MemberExpression : function ( node ) {
43- if ( node . property . name === 'exec' && names . indexOf ( node . object . name ) > - 1 ) {
60+ if ( node . property . name === 'exec' && childProcessIdentifiers . has ( node . object ) ) {
4461 if ( node . parent && node . parent . arguments && node . parent . arguments . length && node . parent . arguments [ 0 ] . type !== 'Literal' ) {
4562 return context . report ( { node : node , message : 'Found child_process.exec() with non Literal first argument' } ) ;
4663 }
0 commit comments