private TaintSets Node_FuncCall(XmlNode node) { if (!isConditional) { return(null); } // We use the True scope as both True and False are the same at this point in time var functionCallExtractor = new FunctionCallExtractor(); var functionCall = functionCallExtractor.ExtractFunctionCall(node); var condSaniFunc = _funcHandler.FindCondSanitizerByName(functionCall.Name); if (condSaniFunc != null) { var parameter = functionCall.Arguments; var varResolverFalse = new VariableResolver(_variables[EdgeType.False]); if (parameter.Any(x => varResolverFalse.IsResolvableNode(x.Value)) && condSaniFunc.DefaultStatus == MixedStatus.XSSSQL_SAFE) { if (isNegated) { var var = varResolverFalse.ResolveVariable(parameter.First(x => varResolverFalse.IsResolvableNode(x.Value)).Value); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } else { var varResolverTrue = new VariableResolver(_variables[EdgeType.True]); var var = varResolverTrue.ResolveVariable(parameter.First(x => varResolverTrue.IsResolvableNode(x.Value)).Value); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } } } return(new TaintSets().ClearTaint()); }
public void ResolveMultipleArrayElements(string phpCode) { XmlNode ast = PHPParseUtils.ParsePHPCode(phpCode, Config.PHPSettings.PHPParserPath).FirstChild.NextSibling; var xmlNodes = ast.FirstChild.Cast <XmlNode>().ToList(); var varNodes = xmlNodes.Where(node => node.LocalName == AstConstants.Nodes.Expr_ArrayDimFetch); var varResolver = new VariableResolver(new VariableStorage(), AnalysisScope.File); var firstVar = varNodes.First(); var result = varResolver.ResolveVariable(firstVar); result = varResolver.ResolveVariable(firstVar); Assert.IsFalse(result.IsNew, "Var"); result = varResolver.ResolveVariable(varNodes.ElementAt(1)); Assert.IsTrue(result.IsNew, "First lookup of second var"); }
public void ResolveArrayElement(string phpCode, string varName) { XmlNode ast = PHPParseUtils.ParsePHPCode(phpCode, Config.PHPSettings.PHPParserPath).FirstChild.NextSibling; var xmlNodes = ast.FirstChild.Cast <XmlNode>().ToList(); var varNodes = xmlNodes.Where(node => node.LocalName == AstConstants.Nodes.Expr_ArrayDimFetch); var varResolver = new VariableResolver(new VariableStorage(), AnalysisScope.File); foreach (var varNode in varNodes) { var result = varResolver.ResolveVariable(varNode); Assert.AreEqual(varName, result.Variable.Name, "Names should match"); Assert.IsTrue(result.IsNew, "Variable should be new"); result = varResolver.ResolveVariable(varNode); Assert.AreEqual(varName, result.Variable.Name, "Names should still match"); Assert.IsFalse(result.IsNew, "Variable is no longer new"); } }
public void ResolveStaticPropertyFetch(string phpCode, string expectedVarName, string nodeType) { XmlNode ast = PHPParseUtils.ParsePHPCode(phpCode, Config.PHPSettings.PHPParserPath).FirstChild.NextSibling; var xmlNodes = ast.FirstChild.Cast <XmlNode>() .Where(node => node.LocalName == nodeType); var propFetch = xmlNodes.First(); var varResolver = new VariableResolver(new VariableStorage(), AnalysisScope.File); var result = varResolver.ResolveVariable(propFetch); Assert.AreEqual(expectedVarName, result.Variable.Name, "Name should match"); Assert.IsTrue(result.IsNew, "New var"); result = varResolver.ResolveVariable(propFetch); Assert.AreEqual(expectedVarName, result.Variable.Name, "Names should still match"); Assert.IsFalse(result.IsNew, "Variable is no longer new"); }
public void ResolveArrayElementMixIndexType() { string phpCode = @"<?php $a['1']; $a[1];"; XmlNode ast = PHPParseUtils.ParsePHPCode(phpCode, Config.PHPSettings.PHPParserPath).FirstChild.NextSibling; var xmlNodes = ast.FirstChild.Cast <XmlNode>().ToList(); var varNodes = xmlNodes.Where(node => node.LocalName == AstConstants.Nodes.Expr_ArrayDimFetch); var varResolver = new VariableResolver(new VariableStorage(), AnalysisScope.File); var arrayfetch = varNodes.First(); var result = varResolver.ResolveVariable(arrayfetch); Assert.AreEqual("1", result.Variable.Name, "Names should match"); Assert.IsTrue(result.IsNew, "Variable should be new"); result = varResolver.ResolveVariable(varNodes.ElementAt(1)); Assert.AreEqual("1", result.Variable.Name, "Names should still match"); Assert.IsFalse(result.IsNew, "Variable is no longer new"); }
private TaintSets EqualsComparison(XmlNode node) { if (!isConditional) { return(null); } var leftNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Left) .GetSubNodesByPrefix(AstConstants.Node).Single(); var rightNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Right) .GetSubNodesByPrefix(AstConstants.Node).Single(); var scalarNodes = new[] { AstConstants.Nodes.Scalar_DNumber, AstConstants.Nodes.Scalar_LNumber, AstConstants.Nodes.Scalar_MagicConst_Class, AstConstants.Nodes.Scalar_MagicConst_Dir, AstConstants.Nodes.Scalar_MagicConst_File, AstConstants.Nodes.Scalar_MagicConst_Function, AstConstants.Nodes.Scalar_MagicConst_Line, AstConstants.Nodes.Scalar_MagicConst_Method, AstConstants.Nodes.Scalar_MagicConst_Namespace, AstConstants.Nodes.Scalar_MagicConst_Trait, AstConstants.Nodes.Scalar_String, }; if (_varResolver.IsResolvableNode(leftNode) && scalarNodes.Contains(rightNode.LocalName)) { var varResolver = new VariableResolver(_variables[isNegated ? EdgeType.False : EdgeType.True]); var var = varResolver.ResolveVariable(leftNode); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } else if (scalarNodes.Contains(leftNode.LocalName) && _varResolver.IsResolvableNode(rightNode)) { var varResolver = new VariableResolver(_variables[isNegated ? EdgeType.False : EdgeType.True]); var var = varResolver.ResolveVariable(rightNode); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } return(new TaintSets().ClearTaint()); }
private TaintSets Node_FuncCall(XmlNode node) { if (!isConditional) { return null; } // We use the True scope as both True and False are the same at this point in time var functionCallExtractor = new FunctionCallExtractor(); var functionCall = functionCallExtractor.ExtractFunctionCall(node); FunctionsHandler fh = FunctionsHandler.Instance; var condSaniFunc = fh.FindCondSanitizerByName(functionCall.Name); if (condSaniFunc != null) { var parameter = functionCall.Arguments; var varResolverFalse = new VariableResolver(_variables[EdgeType.False]); if (parameter.Any(x => varResolverFalse.IsResolvableNode(x.Value)) && condSaniFunc.DefaultStatus == MixedStatus.XSSSQL_SAFE) { if (isNegated) { var var = varResolverFalse.ResolveVariable(parameter.First(x => varResolverFalse.IsResolvableNode(x.Value)).Value); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } else { var varResolverTrue = new VariableResolver(_variables[EdgeType.True]); var var = varResolverTrue.ResolveVariable(parameter.First(x => varResolverTrue.IsResolvableNode(x.Value)).Value); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } } } return new TaintSets().ClearTaint(); }
private TaintSets EqualsComparison(XmlNode node) { if (!isConditional) { return null; } var leftNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Left) .GetSubNodesByPrefix(AstConstants.Node).Single(); var rightNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Right) .GetSubNodesByPrefix(AstConstants.Node).Single(); var scalarNodes = new[] { AstConstants.Nodes.Scalar_DNumber, AstConstants.Nodes.Scalar_LNumber, AstConstants.Nodes.Scalar_MagicConst_Class, AstConstants.Nodes.Scalar_MagicConst_Dir, AstConstants.Nodes.Scalar_MagicConst_File, AstConstants.Nodes.Scalar_MagicConst_Function, AstConstants.Nodes.Scalar_MagicConst_Line, AstConstants.Nodes.Scalar_MagicConst_Method, AstConstants.Nodes.Scalar_MagicConst_Namespace, AstConstants.Nodes.Scalar_MagicConst_Trait, AstConstants.Nodes.Scalar_String, }; if (_varResolver.IsResolvableNode(leftNode) && scalarNodes.Contains(rightNode.LocalName)) { var varResolver = new VariableResolver(_variables[isNegated ? EdgeType.False : EdgeType.True]); var var = varResolver.ResolveVariable(leftNode); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } else if (scalarNodes.Contains(leftNode.LocalName) && _varResolver.IsResolvableNode(rightNode)) { var varResolver = new VariableResolver(_variables[isNegated ? EdgeType.False : EdgeType.True]); var var = varResolver.ResolveVariable(rightNode); var.Variable.Info.Taints = new TaintSets().ClearTaint(); } return new TaintSets().ClearTaint(); }
public MethodCall ExtractMethodCall(XmlNode node, IVariableStorage varStorage, AnalysisScope scope = AnalysisScope.File) { int startLine = AstNode.GetStartLine(node); int endLine = AstNode.GetEndLine(node); string methodName = ""; //Get the varNode which includes either (new ClassName())->MethodName or $var->MethodName var varNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Var); var classNames = new List <string>(); if (varNode.FirstChild.LocalName == AstConstants.Nodes.Expr_New) { //PHP: (new ClassName(args))->MethodName(args); //Extract the ClassName directly, in this case there can be only one ClassName! var className = varNode.FirstChild .GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Class) .GetSubNode(AstConstants.Node + ":" + AstConstants.Nodes.Name) .GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Parts).FirstChild.FirstChild.InnerText; classNames.Add(className); methodName = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).InnerText; return(new MethodCall(methodName, classNames, node, startLine, endLine) { Arguments = ExtractArgumentNodes(node) }); } else { //PHP: $var->MethodName(args); //Resolve the variable, and get all the possible class names! VariableResolver vr = new VariableResolver(varStorage, scope); VariableResolveResult variableResult = null; if (vr.IsResolvableNode(varNode.FirstChild)) { variableResult = vr.ResolveVariable(varNode.FirstChild); classNames.AddRange(variableResult.Variable.Info.ClassNames.Where(className => !classNames.Contains(className))); } var nameSubnode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Name); XmlNode nameNode = null; bool success = nameSubnode.TryGetSubNode(AstConstants.Node + ":" + AstConstants.Nodes.Name, out nameNode); if (success) { methodName = nameNode.InnerText; } else { if (nameSubnode.FirstChild.LocalName == AstConstants.Scalars.String) { methodName = nameSubnode.FirstChild.InnerText; } } return(variableResult == null ? new MethodCall(methodName, classNames, node, startLine, endLine) { Arguments = ExtractArgumentNodes(node) } : new MethodCall(methodName, classNames, node, startLine, endLine, variableResult.Variable) { Arguments = ExtractArgumentNodes(node) }); } }