Example #1
0
    def _parse_me(self, node, scope):
        '''
        TODO: add method call
        
        Traverse this AST subtree until either a Variable or FunctionCall node
        is found...
        '''
        for node in NodeRep.parse(node):
            
            if type(node) is phpast.BinaryOp:
                # only parse direct nodes
                for item in NodeRep.parse(node, 0, 0, 1): 
                    self._parse_me(item, scope)
                break
            
            if type(node) is phpast.Variable:
                # object properties are stored as $this->property
                varname = node.name
                if type(node._parent_node) is phpast.ObjectProperty:
                    varname = node._parent_node.node.name + '->' + node._parent_node.name 
                 
                vardef = VariableDef(varname + '__$temp_anon_var$_', node.lineno, scope)
                vardef.var_nodes = [node]
                # anon var is not stored in scope
                vardef._anon_var = True
                # get and set parent
                scopevar = scope.get_var(varname)
                vardef.add_parent(scopevar)
                # add Param to VarDef
                # TODO: not really necessary?
                vardef._parent_obj = self
                # add var to current scope
                scope.add_var(vardef)
                self.vars.append(vardef)
                break
            
            elif type(node) is phpast.FunctionCall:
                
                # TEST call functioncal visitor
                from core.visitors.base_visitor import BaseVisitor
                from core.visitors.function_call_visitor import FunctionCallVisitor
                
                visitor = FunctionCallVisitor(BaseVisitor);
                fc, stoponthis = visitor.visit(node, scope.get_state())
                
                vardef = VariableDef(node.name + '_funvar', node.lineno, scope)
                
#                 from core.nodes.function_call import FuncCall
#                 from core.nodes.function_call import FuncCall
#                 fc = FuncCall(node.name, node.lineno, node, scope, self)
                
                #TODO: Can we do this in a more extensible way? Why different ways for handling FILE_DISC / XSS?
                # Add vulntrace
                vulntype = fc.is_vulnerable_for()
                if vulntype and 'FILE_DISCLOSURE' in vulntype and \
                self._parent_obj.name in SENSITIVE_FUNCTIONS['XSS']: 
                    # Add vulntrace to parent call with pending trace
                    fc.add_vulntrace(vulntype)
                    self._parent_obj._pending_trace = fc.get_vulntraces()[-1]
                    vardef._safe_for.append('XSS')
                    vardef.set_clean()
                 
#                 elif vulntype:
#                     fc.add_vulntrace(vulntype)
#                     # Keep track of thin funccal
#                     self.get_root_obj()._functions.append(fc)
#                     vardef.set_clean()
                
                # return values (custom function)?
                called_obj = fc.get_called_obj();
                if called_obj:
                    # Set function scope as active code
                    called_obj._scope._dead_code = False
                    for var in called_obj._return_vars:
                        vardef.add_parent(var)
#                  
                else:
                    for param in fc.params:
                        for var in param.vars:
                            vardef.add_parent(var)
                   
                # Securing function?
                vulnty = get_vulnty_for_sec(fc.name)
                if vulnty:
                    vardef._safe_for.append(vulnty)
                
                self.vars.append(vardef)
                break