def visit(self, node, state): currentscope = self.locate_scope(node, state) name = getattr(node, 'name', node.__class__.__name__.lower()) # Don't process custom functions until function call if name not in state.functions_declarations: # new function call newobj = FuncCall(name, node.lineno, node, currentscope, self) state.functions.append(newobj) # Evaluate if vulnerable, if true add trace vulntype = newobj.is_vulnerable_for() if vulntype: newobj.add_vulntrace(vulntype) # add vuln trace of pending trace (from param) if getattr(newobj,'_pending_trace', None): newobj.add_vulntrace(trace = newobj._pending_trace) newobj._pending_trace = None # add function to root scope. currentscope.get_root_scope().add_function(newobj) # Travel other files if include or require if type(node) in (phpast.Include, phpast.Require): self.parse_include_require(node, state, currentscope) return newobj, True
def visit(self, node, state): currscope = self.locate_scope(node, state) method_name = getattr(node, 'name', node.__class__.__name__.lower()) # Get object if node.node.name == '$this': object = currscope.get_root_scope()._parent_scope.obj else: object = state.objects[node.node.name]._obj_def method = object.get_method(method_name) # clean formal params to avoid false positives method.clean_formal_params() # keep track of the methods being traveled state.methods_deep.append(method) # Start ast travel method Node if method._parsed is False: method._parsed = True method._ast_node.accept(self._main_visitor_method) # Create funccall (parses the params) newobj = FuncCall(method_name, node.lineno, node, currscope) # Add method object to call for easy reference newobj._method = method # Keep track of what methods are called within this method currscope.get_root_scope().add_method_call(newobj) # Set method scope as active code method_scope = object.get_method(method_name)._scope method_scope._dead_code = False # Evaluate all raised methodcalls when all methods have been traveled if state.methods_deep[0] is method: # 1.We need to link all params and formal params together # all traveled methods for method0 in state.methods_deep: # All method calls in method for method_call1 in method0._scope.get_method_calls(): # Link for par_index, param in enumerate(method_call1.params): formal_param = method_call1._method.get_formal_param(par_index) formal_param._controlled_by_user = None formal_param.is_root = False formal_param.parents = param.vars # 2.Determine vulnerabilities for method0 in state.methods_deep: for method_call1 in method0._scope.get_method_calls(): method_scope = method_call1._method._scope for funccall in method_scope.get_functions(): vulntype = funccall.is_vulnerable_for() if vulntype: funccall.add_vulntrace(vulntype) # clean formal params to avoid false positives method_call1._method.clean_formal_params() # 3.Determine vulnerabilities for current method for funccall in method._scope.get_functions(): vulntype = funccall.is_vulnerable_for() if vulntype: funccall.add_vulntrace(vulntype) # reset method call stack state.methods_deep = [] return newobj, True