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)
Exemple #2
0
    def test_classes_2(self):
        code = '''
        <?php
        class A {
        
            function foo($var) {
                $this->prop = $var;
                $this->baz();
            }
            
            function bar() {
                include($this->prop);
            }
            
            function baz() {
                $this->bar();
                echo $_GET[1];
            }
        }
        
        $obj1 = new A();
        $obj1->foo($_GET[1]); # XSS, FILE
        $obj1->bar('clean'); # FILE
        
        $obj2 = new A();
        $obj2->bar(); # Clean
        $obj2->baz(); # XSS
        ?>
        '''

        analyzer = PhpSCA(code)
        vulns = analyzer.get_vulns()
                            
        self.assertEquals(2, len(vulns['XSS']))
        self.assertEquals(2, len(vulns['FILE_INCLUDE']))
 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)
Exemple #4
0
def main():
    try:
        long_options = ['help', 'input-files=']
        opts, _ = getopt.getopt(sys.argv[1:], "hi:", long_options)
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        return -3
    
    input_file_list = None
    
    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            return 0
        if o in ('-i', '--input-files='):
            input_file_list = a.split(',')
    
    if input_file_list is None:
        usage()
        return -3
                
    for input_file in input_file_list:
        analyzer = PhpSCA(infile=input_file)
        
        for vulnerability_type in analyzer.get_vulns():
            print vulnerability_type
            for vulnerability in analyzer.get_vulns()[vulnerability_type]:
                print '    ', vulnerability
        
        if len(analyzer.get_alerts()) > 0:
            print ''
            print 'Alerts:'
            for alert in analyzer.get_alerts():
                print alert
Exemple #5
0
 def test_classes_3(self):
     code = '''
     <?php
     
     class A {
     
         function foo($var) {
             $this->prop = $var;
         }
         
         function bar() {
             $var = 'bla' . somefunc($this->prop);
             echo $var;
         }
         
     }
     
     $obj1 = new A();
     $obj1->foo($_GET[1]);
     $obj1->bar();
     ?>
     '''
     # Poperty to var test
     analyzer = PhpSCA(code)
     vulns = analyzer.get_vulns() 
     self.assertEquals(1, len(vulns['XSS']))   
 def test_vuln_functions_2(self):
     code = '''
     <?
       $foo = $_GET['bar'];
       system('ls ' . $foo);
       echo file_get_contents($foo);
     ?>
     '''
     analyzer = PhpSCA(code)
     syscall, echocall = analyzer.get_func_calls()
     self.assertTrue('OS_COMMANDING' in syscall.vulntypes)
     self.assertTrue('FILE_DISCLOSURE' in echocall.vulntypes)
 def test_include_require_2(self):
     
     analyzer = PhpSCA(infile = os.path.join(self.TEST_DIR, '2', 'a.php'))
     
     echo = analyzer.get_func_calls()[1]
     self.assertTrue('XSS' in echo.vulntypes)
     self.assertEquals('core' + os.sep + 'tests' + os.sep + 'test_include_require' + os.sep + '2' + os.sep + 'b.php', echo.get_file_name())
     
     vulns = analyzer.get_vulns()
     self.assertEquals('core' + os.sep + 'tests' + os.sep + 'test_include_require' + os.sep + '2' + os.sep + 'a.php', vulns['XSS'][0][-1].get_file_name())
     self.assertEquals(2, vulns['XSS'][0][-1].lineno)
     
 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_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_vuln_func_get_sources_1(self):
     code = '''
     <?
         $eggs = $_GET['bar'];
         $foo = func($eggs);
         $a = 'ls ' . $foo; 
         exec($a);
     ?>
     '''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'bar' in execfunc.vulnsources)
 def test_vuln_functions_3(self):
     code = '''
     <?php
       $var1 = escapeshellarg($_GET['param']);
       system($var1);
       system(escapeshellarg($_GET['param']));
       system(myfunc(escapeshellarg($_GET['param'])));
     ?>
     '''
     analyzer = PhpSCA(code)
     escapecall, syscall1, syscall2, syscall3 = analyzer.get_func_calls()
     # Both must be SAFE!
     self.assertEquals(0, len(syscall1.vulntypes))
     self.assertEquals(0, len(syscall2.vulntypes))
     self.assertEquals(0, len(syscall3.vulntypes))
Exemple #12
0
 def test_classes_1(self):
     code = '''
     <?php
     class A {
         private $prop1 = 'ok';
         
         function foo($var1) {
             echo $_GET[1];
             $this->prop1 = $var1;
         }
         
         function bar($prop2 = 'default') {
             echo $this->prop1;
             $this->prop2 = $prop2;
         }
         
         function baz() {
             if (1) {
                 system($this->prop2);
             }
         }
     }
     
     $obj1 = new A();
     $obj1->foo($_GET[1]); #XSS
     $obj1->bar(); #XSS
     $obj1->baz();
     
     $awsome = $_POST[1];
     $obj2 = new A();
     $obj2->foo('test'); #XSS
     $obj2->bar($awsome);
     $obj2->baz(); #OS COMMANDING
     
     $obj1->bar(); #XSS again
     ?>'''
     analyzer = PhpSCA(code)
     vulns = analyzer.get_vulns()
     
     self.assertEquals(4, len(vulns['XSS']))
     self.assertEquals(1, len(vulns['OS_COMMANDING']))
     
     self.assertEquals(18, vulns['OS_COMMANDING'][0][0].lineno)
     self.assertEquals('$awsome', vulns['OS_COMMANDING'][0][-1].name)
     self.assertEquals(28, vulns['OS_COMMANDING'][0][-1].lineno)
     
     objects = analyzer.get_objects();
     self.assertTrue('$obj1' and '$obj2' in objects)
Exemple #13
0
    def test_function_scope_2(self):
        code = '''
        <?
          $var = 1;
          echo $var;
          
          function foo($var, $var2) {
            echo $var;
          }
          foo($_GET[1], 4);          
        ?>
        '''
        analyzer = PhpSCA(code)
        echo_outside_func, echo_in_func = analyzer.get_func_calls()

        self.assertFalse('XSS' in echo_outside_func.vulntypes)
        self.assertTrue('XSS' in echo_in_func.vulntypes)
Exemple #14
0
 def analyze_(self, test_case):
     for input_file_obj in test_case.files:
         input_file_name = os.path.join(self.SAMATE_TEST_DIR, input_file_obj.file)
         analyzer = PhpSCA(infile=input_file_name)
         
         identified_vulns = []
         
         for vuln_type in analyzer.get_vulns():
             for vuln_func_call in analyzer.get_vulns()[vuln_type]:
                 identified_vulns.append((vuln_type, vuln_func_call[0]._lineno))
         
         expected_vulns = []
         for flaw in input_file_obj.flaws:
             sca_name = SAMATE_TO_SCA[flaw.vuln_name]
             expected_vulns.append((sca_name, int(flaw.vuln_line_no)))
         
         #print set(expected_vulns), set(identified_vulns)
         assert set(expected_vulns) == set(identified_vulns)
 def test_vuln_functions_1(self):
     code = '''
     <?php
       $var = $_GET['bleh'];
       if ($x){
           $var = 2;
           // not vuln!
           system($var);
       }
       // vuln for OS COMMANDING!
       system($var);
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, sys2 = analyzer.get_func_calls()
     # First system call
     self.assertEquals(0, len(sys1.vulntypes))
     # Second system call
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
 def test_vuln_functions_4(self):
     code = '''
     <?
     $foo = $_GET['foo'];
     if ( $spam == $eggs ){
          $foo = 'ls';
          system($foo);
     }
     else{
          echo $foo;
          system($foo);
     }
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, echo, sys2 = analyzer.get_func_calls()
     self.assertEquals([], sys1.vulntypes)
     self.assertIn('XSS', echo.vulntypes)
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
 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)
 def test_vuln_func_get_sources_2(self):
     code = '''<? echo file_get_contents($_REQUEST['file']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'file' in execfunc.vulnsources)
 def test_vuln_func_get_sources_3(self):
     code = '''<? system($_GET['foo']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'foo' in execfunc.vulnsources)