def test_vars(self): code = ''' <? $foo = $_GET['bar']; $spam = $_POST['blah']; $eggs = 'blah' . 'blah'; if ($eggs){ $xx = 'waka-waka'; $yy = $foo; } ?> ''' analyzer = PhpSCA(code) # Get all vars vars = analyzer.get_vars(usr_controlled=False) self.assertEquals(5, len(vars)) # Get user controlled vars usr_cont_vars = analyzer.get_vars(usr_controlled=True) self.assertEquals(3, len(usr_cont_vars)) # Test $foo foovar = usr_cont_vars[0] self.assertEquals('$foo', foovar.name) self.assertTrue(foovar.controlled_by_user) self.assertFalse(foovar.is_root) self.assertTrue(foovar.parents) # Test $spam spamvar = usr_cont_vars[1] self.assertEquals('$spam', spamvar.name) # Test $spam yyvar = usr_cont_vars[2] self.assertEquals('$yy', yyvar.name)
def test_override_var(self): code = ''' <?php $var1 = $_GET['param']; $var1 = 'blah'; $var2 = escapeshellarg($_GET['param2']); $var3 = 'blah'; if ($x){ $var3 = $_POST['param2']; } else{ $var3 = 'blah'.'blah'; } ?> ''' analyzer = PhpSCA(code) vars = analyzer.get_vars(usr_controlled=False) # 'var1' is safe var1 = vars[0] self.assertFalse(var1.controlled_by_user) # 'var2' is controlled by the user but is safe for OS-Commanding var2 = vars[1] self.assertTrue(var2.controlled_by_user) self.assertFalse(var2.is_tainted_for('OS_COMMANDING')) # 'var3' must still be controllable by user var3 = vars[2] self.assertTrue(var3.controlled_by_user)
def test_variable_no_taint_taint_no_taint_diff(self): code = ''' <? $foo = htmlspecialchars($_GET[1]) . $_GET[2] . htmlspecialchars($_GET[3]); ?> ''' analyzer = PhpSCA(code) vars = analyzer.get_vars() foo_var = vars[0] self.assertTrue(foo_var.controlled_by_user) self.assertTrue(foo_var.is_tainted_for('XSS'), code)
def test_variable_taint_taint(self): code = ''' <? $foo = $_GET[2] .$_GET[1]; ?> ''' analyzer = PhpSCA(code) vars = analyzer.get_vars() foo_var = vars[0] self.assertTrue(foo_var.controlled_by_user) self.assertTrue(foo_var.is_tainted_for('XSS'))
def test_var_comp_operators(self): code = ''' <?php $var0 = 'bleh'; $var1 = $_GET['param']; $var2 = 'blah'; ?> ''' analyzer = PhpSCA(code) vars = analyzer.get_vars(usr_controlled=False) code2 = ''' <?php $var0 = 'bleh'; $var1 = 'blah'; if ($x){ $var2 = $_POST['param2']; } else{ $var2 = 'blah'.'blah'; } ?> ''' analyzer = PhpSCA(code2) vars2 = analyzer.get_vars(usr_controlled=False) c1_var0 = vars[0] c2_var0 = vars2[0] c1_var0._scope = c2_var0._scope self.assertTrue(c2_var0 == c1_var0) c1_var1 = vars[1] c2_var1 = vars2[1] c2_var1._scope = c1_var1._scope self.assertTrue(c2_var1 > c1_var1) c1_var2 = vars[2] c2_var2 = vars2[2] self.assertTrue(c2_var2 > c1_var2)
def test_vars_dependencies(self): code = ''' <? $x1 = 'waca-waka'; $x2 = '#!~?#*' + $x1; $x3 = func($x2); $y = $_COOKIES['1']; $y2 = 'ls ' . $y; $z = $x2 + $x3; ?> ''' analyzer = PhpSCA(code) vars = analyzer.get_vars(usr_controlled=False) vars.sort(cmp=lambda x, y: cmp(x.lineno, y.lineno)) x1deps, x2deps, x3deps, ydeps, y2deps, zdeps = \ [[vd.name for vd in v.deps()] for v in vars] self.assertEquals([], x1deps) self.assertEquals(['$x1'], x2deps) self.assertEquals(['$x2', '$x1'], x3deps) self.assertEquals(['$_COOKIES'], ydeps) self.assertEquals(['$y', '$_COOKIES'], y2deps) self.assertEquals(['$x2', '$x3', '$x1'], zdeps)