@@ -48,7 +48,7 @@ function(scope, node, ce) { // http.get
48
48
var func = ce . arguments [ 1 ] ;
49
49
50
50
func . scope . sources . push ( func . params [ 1 ] ) ;
51
- func . scope . log ( 'SOURCE' , node , '' , func . params [ 1 ] ) ;
51
+ func . scope . log ( 'SOURCE' , node , false , func . params [ 1 ] ) ;
52
52
traverse ( func . body , func . scope ) ;
53
53
return true ;
54
54
} , function ( scope , node , ce ) { // (new require('hapi').server()).route()
@@ -68,7 +68,7 @@ function(scope, node, ce) { // http.get
68
68
69
69
if ( func && func . scope ) {
70
70
func . scope . sources . push ( func . params [ 0 ] ) ;
71
- func . scope . log ( 'SOURCE' , node , '' , func . params [ 0 ] ) ;
71
+ func . scope . log ( 'SOURCE' , node , false , func . params [ 0 ] ) ;
72
72
traverse ( func . body , func . scope ) ;
73
73
74
74
}
@@ -88,7 +88,7 @@ function(scope, node, ce) { // http.get
88
88
89
89
if ( func && func . scope ) {
90
90
func . scope . sources . push ( func . params [ 0 ] ) ;
91
- func . scope . log ( 'SOURCE' , node , '' , func . params [ 0 ] ) ;
91
+ func . scope . log ( 'SOURCE' , node , false , func . params [ 0 ] ) ;
92
92
traverse ( func . body , func . scope ) ;
93
93
94
94
}
@@ -105,7 +105,7 @@ function(scope, node, ce) { // http.get
105
105
var func = ce . arguments [ 2 ] ; // the callback
106
106
if ( func ) {
107
107
func . scope . sources . push ( func . params [ 1 ] ) ; // data
108
- func . scope . log ( 'SOURCE' , node , '' , func . params [ 1 ] ) ;
108
+ func . scope . log ( 'SOURCE' , node , false , func . params [ 1 ] ) ;
109
109
traverse ( func . body , func . scope ) ;
110
110
}
111
111
return true ;
@@ -142,7 +142,13 @@ function(scope, node, ce) { // http.get
142
142
if ( ast ) {
143
143
if ( flags . verbose )
144
144
console . log ( ' ---- ' . yellow , pkg ) ;
145
- var newScope = new Scope ( { sinks : sinks , sources : sources , file :pkg , log :scope . log , leaveScope :scope . leaveScope } ) ;
145
+ var newScope = new Scope ( {
146
+ sinks : sinks ,
147
+ sources : sources ,
148
+ file : pkg ,
149
+ log : scope . log ,
150
+ leaveScope : scope . leaveScope
151
+ } ) ;
146
152
traverse ( ast , newScope ) ;
147
153
// scope.log('EXPORTS', ast, newScope.vars.module.exports);
148
154
@@ -169,8 +175,8 @@ Scope = module.exports.Scope = function(scope) {
169
175
this . file = scope . file ;
170
176
if ( ! baseFile ) baseFile = scope . file ;
171
177
this . log = scope . log || log ;
172
- this . createNewScope = scope . createNewScope ;
173
178
this . leaveScope = scope . leaveScope ;
179
+ this . createNewScope = scope . createNewScope ;
174
180
this . reports = [ ] ;
175
181
} ;
176
182
@@ -251,38 +257,38 @@ Scope.prototype.resolveStatement = function(node) {
251
257
}
252
258
253
259
var ceName = scope . resolve ( ce . name ) ;
254
-
260
+
255
261
var t = 'CES' ;
256
262
257
263
if ( ce . arguments )
258
264
ce . arguments . some ( function ( arg ) {
259
- if ( ! arg )
265
+ if ( ! arg || ( arg . scope && arg . params && arg . body ) )
260
266
return false ;
261
267
var resolved = scope . resolve ( arg ) ;
262
268
var source = resolved ;
263
-
269
+
264
270
if ( scope . isSource ( arg . name || arg ) || scope . isSource ( resolved . name || resolved ) ||
265
- ( arg . left ? _ . some ( climbBE ( arg ) , function ( a ) {
271
+ ( traverseJSON ( arg , function ( a ) {
266
272
if ( ! a ) return false ;
267
273
var r = scope . resolve ( a ) ;
268
274
if ( scope . isSource ( a . name || a ) || scope . isSource ( r . name || r ) ) {
269
275
source = r ;
270
276
return true ;
271
277
}
272
278
return false ;
273
- } ) : false ) ) {
279
+ } ) ) ) {
274
280
275
281
// If the function is a sink and there is a source, return as sink;
276
282
// If not a sink but still has source, return as a Source CES (possible taint)
277
283
t = ( scope . isSink ( ce . name ) || scope . isSink ( ceName ) ) ?'SINK' :'SCES' ;
278
- scope . log ( t , node , ce . name , source ) ;
284
+ scope . log ( t , node , ce . name , source . name || source ) ;
279
285
return true ;
280
286
}
281
287
return false ;
282
288
} ) ;
283
289
284
- if ( ( flags . verbose || t [ 0 ] == 'S' ) && typeof ceName == 'string' )
285
- this . log ( t , node , ce . raw , typeof ceName == 'string' ?ceName :{ } ) ;
290
+ if ( flags . verbose && typeof ceName == 'string' )
291
+ this . log ( t , node , ce . name , typeof ceName == 'string' ?ceName :{ } ) ;
286
292
287
293
return ce ;
288
294
case 'AssignmentExpression' :
@@ -384,6 +390,7 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
384
390
if ( flags . verbose )
385
391
this . log ( 'ARRAY' , right , array ) ;
386
392
return array ;
393
+ case 'LogicalExpression' :
387
394
case 'BinaryExpression' : // A + B - C * D
388
395
var bin = {
389
396
left : this . resolveExpression ( right . left , isSourceCB ) ,
@@ -405,29 +412,27 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
405
412
if ( ceName && typeof ceName == 'string' ) {
406
413
if ( ce . arguments ) {
407
414
ce . arguments . some ( function ( arg ) {
408
- if ( ! arg )
409
- return false ;
415
+ if ( ! arg || ( arg . scope && arg . params && arg . body ) )
416
+ return false ;
410
417
var resolved = scope . resolve ( arg ) ;
411
418
var source = resolved ;
412
419
413
420
if ( scope . isSource ( arg . name || arg ) || scope . isSource ( resolved . name || resolved ) ||
414
- arg . left ? _ . some ( climbBE ( arg ) , function ( a ) {
421
+ ( traverseJSON ( arg , function ( a ) {
415
422
if ( ! a ) return false ;
416
423
var r = scope . resolve ( a ) ;
417
424
if ( scope . isSource ( a . name || a ) || scope . isSource ( r . name || r ) ) {
418
425
source = r ;
419
426
return true ;
420
427
}
421
428
return false ;
422
- } ) : false ) {
429
+ } ) ) ) {
423
430
424
- if ( scope . isSource ( ce . name ) || scope . isSink ( ceName ) ) {
425
- scope . log ( 'SINK' , right , ce . name , source ) ;
426
- return true ;
427
- } else {
428
- t = 'SCE' ;
429
- return false ;
430
- }
431
+
432
+ // If the function is a sink and there is a source, return as sink;
433
+ // If not a sink but still has source, return as a Source CES (possible taint)
434
+ t = ( scope . isSink ( ce . name ) || scope . isSink ( ceName ) ) ?'SINK' :'SCES' ;
435
+ scope . log ( t , right , ce . name , source ) ;
431
436
}
432
437
return false ;
433
438
} ) ;
@@ -452,7 +457,9 @@ Scope.prototype.resolveExpression = function(right, isSourceCB) {
452
457
case 'FunctionExpression' : // functions
453
458
var fe = scope . resolveFunctionExpression ( right ) ;
454
459
return fe ;
455
-
460
+ default :
461
+ // console.log(right.type, pos(right));
462
+ return { } ;
456
463
}
457
464
} ;
458
465
@@ -597,7 +604,8 @@ Scope.prototype.traverse = function(ast, returnCB) {
597
604
// (scope.leaveScope || function () {
598
605
// console.log('leaving scope'.yellow);
599
606
// })();
600
- scope . leaveScope ( ) ;
607
+ if ( scope . leaveScope )
608
+ scope . leaveScope ( ) ;
601
609
} ;
602
610
603
611
Scope . prototype . resolvePath = function ( file , cb ) {
@@ -611,7 +619,8 @@ Scope.prototype.resolvePath = function(file, cb) {
611
619
try {
612
620
pkg = resolve . sync ( file , { basedir : String ( this . file ) . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) } ) ;
613
621
} catch ( e ) {
614
- console . error ( String ( e ) ) ;
622
+ if ( flags . verbose )
623
+ console . error ( String ( e ) ) ;
615
624
return false ;
616
625
}
617
626
@@ -662,7 +671,6 @@ traverse = module.exports.traverse = function(ast, scope) {
662
671
scope . log ( 'SOURCES' , ast , scope . sources ) ;
663
672
}
664
673
665
-
666
674
ast . body . forEach ( function ( node ) {
667
675
if ( node . type == 'ExpressionStatement' )
668
676
node = node . expression ;
@@ -674,7 +682,8 @@ traverse = module.exports.traverse = function(ast, scope) {
674
682
// console.log('leaving scope'.yellow);
675
683
// })();
676
684
// }
677
- scope . leaveScope ( ) ;
685
+ if ( scope . leaveScope )
686
+ scope . leaveScope ( ) ;
678
687
} ;
679
688
680
689
astFromFile = module . exports . astFromFile = function ( file , output ) {
@@ -710,4 +719,30 @@ climbBE = module.exports.climbBE = function (be, func) {
710
719
// Convience function to return the line of a node assuming a node has one.
711
720
module . exports . pos = pos = function ( node ) {
712
721
return node . loc ? String ( node . loc . start . line ) : "-1" ;
713
- } ;
722
+ } ;
723
+
724
+ // function traverseJSON(o,func) {
725
+ // for (var i in o) {
726
+ // func(o[i]);
727
+ // if (o[i] !== null && typeof(o[i])=="object") {
728
+ // //going on step down in the object tree!!
729
+ // traverseJSON(o[i],func);
730
+ // }
731
+ // }
732
+ // }
733
+
734
+ function traverseJSON ( o , func ) {
735
+ return typeof o == 'object' ? _ . some ( o , function ( i ) {
736
+ if ( ! i )
737
+ return false ;
738
+ if ( typeof i == 'object' ) {
739
+ if ( ! i || ( i . scope && i . params && i . body ) )
740
+ return false ;
741
+ return traverseJSON ( i , func ) ;
742
+ } else {
743
+ return func ( i ) ;
744
+ }
745
+
746
+ return false ;
747
+ } ) : false ;
748
+ }
0 commit comments