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;
}