public FunctionAndMethodAnalyzer Create(ImmutableVariableStorage variableStorage, IIncludeResolver incResolver,
     AnalysisStacks stacks, CustomFunctionHandler customFuncHandler,
     IVulnerabilityStorage vulnerabilityStorage)
 {
     return new FunctionAndMethodAnalyzer(variableStorage, incResolver, stacks, customFuncHandler, vulnerabilityStorage)
            {
                UseSummaries = this.UseSummaries
            };
 }
Ejemplo n.º 2
0
        private ExpressionInfo Node_FuncCall(XmlNode node)
        {
            var functionCallExtractor = new FunctionCallExtractor();
            var functionCall = functionCallExtractor.ExtractFunctionCall(node);

            bool isAlreadyInStack = _analysisStacks.CallStack.Any(x => x.Name == functionCall.Name);
            _analysisStacks.CallStack.Push(functionCall);

            var argInfos = new List<ExpressionInfo>();

            //Actually extract the arguments
            for (uint index = 1; index <= functionCall.Arguments.Count; index++)
            {
                var item = functionCall.Arguments.FirstOrDefault(x => x.Key == index);
                var exprInfo = this.Analyze(item.Value);
                if (_varResolver.IsResolvableNode(item.Value))
                {
                    var variableResolveResult = _varResolver.ResolveVariable(item.Value);
                    exprInfo.ValueInfo = variableResolveResult.Variable.Info;
                }
                argInfos.Add(exprInfo);
            }

            if (functionCall.Name == "")
            {
                var expr_info = new ExpressionInfo();
                _analysisStacks.CallStack.Pop();
                return argInfos.Aggregate(expr_info, (current, info) => current.Merge(info));
            }

            var customFunctionHandler = new CustomFunctionHandler(this._analyzer, _subroutineAnalyzerFactory);
            customFunctionHandler.AnalysisExtensions.AddRange(this.AnalysisExtensions);
            var immutableVariableStorage = ImmutableVariableStorage.CreateFromMutable(_variableStorage);
            var functionMethodAnalyzer = this._subroutineAnalyzerFactory.Create(immutableVariableStorage, _inclusionResolver,
                _analysisStacks, customFunctionHandler, _vulnerabilityStorage);

            var resultTaintSet = new ExpressionInfo();
            if (!isAlreadyInStack)
            {
                resultTaintSet = functionMethodAnalyzer.AnalyzeFunctionCall(functionCall, argInfos);
            }

            FunctionsHandler fh = FunctionsHandler.Instance;
            var sqlSaniFunc = fh.FindSQLSanitizerByName(functionCall.Name);
            var sqlSinkFunc = fh.FindSQLSinkByName(functionCall.Name);
            var xssSaniFunc = fh.FindXSSSanitizerByName(functionCall.Name);
            var xssSinkFunc = fh.FindXSSSinkByName(functionCall.Name);

            if(sqlSaniFunc != null && sqlSaniFunc.DefaultStatus == SQLITaint.None)
            {
                resultTaintSet.ExpressionTaint.SqliTaint.Clear();
                resultTaintSet.ValueInfo.Taints.SqliTaint.Clear();
                resultTaintSet.ExpressionStoredTaint.Taint.SqliTaint.Clear();
            }
            if (xssSaniFunc != null && xssSaniFunc.DefaultStatus == XSSTaint.None)
            {
                resultTaintSet.ExpressionTaint.XssTaint.Clear();
                resultTaintSet.ValueInfo.Taints.XssTaint.Clear();
                resultTaintSet.ExpressionStoredTaint.Taint.XssTaint.Clear();
            }
            if (sqlSinkFunc != null)
            {
                var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = functionCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var parameter in param)
                {
                    var argInfo = argInfos.ElementAt((int) (parameter.Key - 1));
                    CheckForSQLVulnerabilities(argInfo, parameter.Value);
                }
            }
            if (xssSinkFunc != null)
            {
                var vulnerableXssParams = xssSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                var param = functionCall.Arguments.Where(x => vulnerableXssParams.Keys.Any(z => z.Item1 == x.Key));

                foreach (var parameter in param)
                {
                    var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                    CheckForXssVulnerabilities(argInfo, parameter.Value);
                }
            }
            resultTaintSet = StoredFuncHandler(resultTaintSet, node, argInfos);

            var argumentInfoWithIndex = argInfos.Select((a, i) => new { Info = a, Index = (uint)i + 1 })
                                                .ToDictionary(a => a.Index, a => a.Info);
            resultTaintSet = ApplyAnalysisExtensionsToFuncCall(node, resultTaintSet, argumentInfoWithIndex);

            _analysisStacks.CallStack.Pop();
            return resultTaintSet;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Calls AnalyzeFuncCall on all external components. This was created because we currently do not call Analyze on "Node:Arg",
 /// which is needed to let the components find the arguments themselves.
 /// TODO: Handle Node:Arg in the analysis explicitly, to allow this.
 /// </summary>
 private ExpressionInfo ApplyAnalysisExtensionsToFuncCall(XmlNode node, ExpressionInfo currentInfo, IDictionary<uint, ExpressionInfo> argInfos)
 {
     foreach (var analysisExtension in AnalysisExtensions)
     {
         analysisExtension.FunctionMethodAnalyzerFactory = storage =>
         {
             var customFunctionHandler = new CustomFunctionHandler(this._analyzer, _subroutineAnalyzerFactory);
             customFunctionHandler.AnalysisExtensions.AddRange(this.AnalysisExtensions);
             var varStorage = ImmutableVariableStorage.CreateFromMutable(storage);
             return _subroutineAnalyzerFactory.Create(varStorage, _inclusionResolver, _analysisStacks,
                                                      customFunctionHandler, _vulnerabilityStorage);
         };
         currentInfo = analysisExtension.AnalyzeFunctionCall(node, currentInfo, _variableStorage, _vulnerabilityStorage, argInfos, this._analysisStacks);
     }
     return currentInfo;
 }
Ejemplo n.º 4
0
        private ExpressionInfo Node_MethodCall(XmlNode node)
        {
            var functionCallExtractor = new FunctionCallExtractor();
            var methodCall = functionCallExtractor.ExtractMethodCall(node, this._variableStorage, this._analysisScope);

            bool isAlreadyInStack = _analysisStacks.CallStack.Any(x => x.Name == methodCall.Name);
            _analysisStacks.CallStack.Push(methodCall);

            var argInfos = new List<ExpressionInfo>();

            //Actually analyze the arguments
            for (uint index = 1; index <= methodCall.Arguments.Count; index++)
            {
                var item = methodCall.Arguments.FirstOrDefault(x => x.Key == index);
                var exprInfo = this.Analyze(item.Value);
                if (_varResolver.IsResolvableNode(item.Value))
                {
                    var @var = _varResolver.ResolveVariable(item.Value);
                    exprInfo.ValueInfo = @var.Variable.Info;
                }
                argInfos.Add(exprInfo);
            }

            if (methodCall.Name == "")
            {
                var exprInfo = new ExpressionInfo();
                _analysisStacks.CallStack.Pop();
                return argInfos.Aggregate(exprInfo, (current, info) => current.Merge(info));
            }

            var customFunctionHandler = new CustomFunctionHandler(this._analyzer, _subroutineAnalyzerFactory);
            customFunctionHandler.AnalysisExtensions.AddRange(this.AnalysisExtensions);
            var functionMethodAnalyzer = _subroutineAnalyzerFactory.Create(ImmutableVariableStorage.CreateFromMutable(_variableStorage),
                _inclusionResolver, _analysisStacks, customFunctionHandler, _vulnerabilityStorage);

            var methodCallTaintSet = new ExpressionInfo();
            if(!isAlreadyInStack)
            {
                methodCallTaintSet = functionMethodAnalyzer.AnalyzeMethodCall(methodCall, argInfos);
            }

            FunctionsHandler fh = FunctionsHandler.Instance;
            var resultTaintSet = new ExpressionInfo();
            foreach (var className in methodCall.ClassNames.Distinct())
            {
                var tempResultTaintSet = methodCallTaintSet.AssignmentClone();
                var sqlSaniFunc = fh.FindSQLSanitizerByName(methodCall.CreateFullMethodName(className));
                var sqlSinkFunc = fh.FindSQLSinkByName(methodCall.CreateFullMethodName(className));
                var xssSaniFunc = fh.FindXSSSanitizerByName(methodCall.CreateFullMethodName(className));
                var xssSinkFunc = fh.FindXSSSinkByName(methodCall.CreateFullMethodName(className));

                if (sqlSaniFunc != null && sqlSaniFunc.DefaultStatus == SQLITaint.None)
                {
                    resultTaintSet.ExpressionTaint.SqliTaint.Clear();
                }
                if (xssSaniFunc != null && xssSaniFunc.DefaultStatus == XSSTaint.None)
                {
                    resultTaintSet.ExpressionTaint.XssTaint.Clear();
                }
                if (sqlSinkFunc != null || xssSinkFunc != null)
                {
                    if (sqlSinkFunc != null)
                    {
                        var vulnerableSqlParams = sqlSinkFunc.Parameters.Where(x => x.Value.IsSensitive)
                                                                        .ToDictionary(pair => pair.Key);
                        var parameters = methodCall.Arguments.Where(x => vulnerableSqlParams.Keys.Any(z => z.Item1 == x.Key));

                        foreach (var parameter in parameters)
                        {
                            //var argInfo = Analyze(parameter.Value);
                            var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                            CheckForSQLVulnerabilities(argInfo, parameter.Value);
                        }
                        if (sqlSinkFunc.ReturnType == "object" || sqlSinkFunc.ReturnType == "mix")
                        {
                            resultTaintSet.ValueInfo.ClassNames.AddRange(sqlSinkFunc.Classnames);
                        }
                    }
                    if (xssSinkFunc != null)
                    {
                        var vulnerableXssParams = xssSinkFunc.Parameters.Where(x => x.Value.IsSensitive).ToDictionary(pair => pair.Key);
                        var param = methodCall.Arguments.Where(x => vulnerableXssParams.Keys.Any(z => z.Item1 == x.Key));

                        foreach (var parameter in param)
                        {
                            var argInfo = argInfos.ElementAt((int)(parameter.Key - 1));
                            CheckForXssVulnerabilities(argInfo, parameter.Value);
                        }
                    }
                    // Assuming sinks does not return taint.
                    resultTaintSet.ExpressionTaint.ClearTaint();
                    resultTaintSet.ExpressionStoredTaint.Taint.ClearTaint();
                }
                tempResultTaintSet = StoredMethodHandler(tempResultTaintSet, node);
                resultTaintSet = resultTaintSet.Merge(tempResultTaintSet);

                var methodNameWithClass = methodCall.CreateFullMethodName(className);
                bool isStoredProvider = FunctionsHandler.Instance.FindStoredProviderMethods(methodNameWithClass).Any();
                if (isStoredProvider)
                {
                    resultTaintSet.ExpressionStoredTaint = resultTaintSet.ExpressionStoredTaint.Merge(methodCall.Var.Info.PossibleStoredTaint);
                    //TODO: The following is not true in all cases.
                    // What cases?
                    var cloned = resultTaintSet.ExpressionStoredTaint.Taint.DeepClone();
                    resultTaintSet.ValueInfo.NestedVariablePossibleStoredDefaultTaintFactory = () => cloned;
                }
            }

            _analysisStacks.CallStack.Pop();
            return resultTaintSet;
        }