private void VisitMethods(SyntaxNodeAnalysisContext ctx) { var node = ctx.Node as MethodDeclarationSyntax; try { if (node != null) { var state = new ExecutionState(ctx); foreach (var ext in extensions) { ext.VisitBeginMethodDeclaration(node, state); } VisitMethodDeclaration(node, state); foreach (var ext in extensions) { ext.VisitEndMethodDeclaration(node, state); } } } catch (Exception e) { //Intercept the exception for logging. Otherwise, the analyzer will failed silently. string methodName = node.Identifier.Text; SGLogging.Log(string.Format("Unhandle exception while visiting method {0} : {1}", methodName, e.Message)); throw e; } }
public void VisitMethods(SyntaxNodeAnalysisContext ctx) { var node = ctx.Node as MethodBlockSyntax; try { if (node != null) { var state = new ExecutionState(ctx); foreach (var ext in extensions) { ext.VisitBeginMethodDeclaration(node, state); } //TODO: Implement VB code evaluation VisitMethodDeclaration(node, state); foreach (var ext in extensions) { ext.VisitEndMethodDeclaration(node, state); } } } catch (Exception e) { //Intercept the exception for logging. Otherwise, the analyzer will failed silently. string methodName = node.ToString(); string errorMsg = string.Format("Unhandle exception while visiting method: {0}", e.Message); SGLogging.Log(errorMsg); throw new Exception(errorMsg, e); } }
private static void visitNodeRecursively(SyntaxNode node, int indent, SyntaxNodeAnalysisContext ctx) { string code = node.GetText().Lines[0].Text.ToString().Trim() + (node.GetText().Lines.Count > 1 ? "[...]" : ""); if (node.ChildNodes().Count() > 0) { code = ""; } if (node is InvocationExpressionSyntax) { var symbol = ctx.SemanticModel.GetSymbolInfo(node).Symbol; if (symbol != null) { string typeName = symbol.ContainingType?.Name; //Class name string name = symbol.Name; //Method if (typeName != null && name != null) { code = typeName + "." + name; } } } SGLogging.Log(new string(' ', indent * 4) + code + " <" + node.GetType().Name + ">", false); foreach (var n in node.ChildNodes()) { visitNodeRecursively(n, indent + 1, ctx); } }
/// <summary> /// Statement are all segment separate by semi-colon. /// </summary> /// <param name="node"></param> /// <param name="state"></param> private VariableState VisitNode(SyntaxNode node, ExecutionState state) { //SGLogging.Log(node.GetType().ToString()); //Variable allocation if (node is LocalDeclarationStatementSyntax) { var declaration = (LocalDeclarationStatementSyntax)node; return(VisitLocalDeclaration(declaration, state)); } else if (node is VariableDeclaratorSyntax) { var declaration = (VariableDeclaratorSyntax)node; return(VisitVariableDeclaration(declaration, state)); } else if (node is AssignmentStatementSyntax) { var assignment = (AssignmentStatementSyntax)node; return(VisitAssignmentStatement(assignment, state)); } //Expression else if (node is ExpressionStatementSyntax) { var expression = (ExpressionStatementSyntax)node; return(VisitExpressionStatement(expression, state)); } else if (node is ExpressionSyntax) { var expression = (ExpressionSyntax)node; return(VisitExpression(expression, state)); } else if (node is MethodBlockSyntax) { var methodDeclaration = (MethodBlockSyntax)node; return(VisitMethodDeclaration(methodDeclaration, state)); } else { foreach (var n in node.ChildNodes()) { VisitNode(n, state); } // var isBlockStatement = node is BlockSyntax || node is IfStatementSyntax || node is ForEachStatementSyntax || node is ForStatementSyntax; var isBlockStatement = node is IfStatementSyntax || node is ForEachStatementSyntax || node is ForStatementSyntax; if (!isBlockStatement) { SGLogging.Log("Unsupported statement " + node.GetType() + " (" + node.ToString() + ")"); } return(new VariableState(node, VariableTaint.UNKNOWN)); } }
/// <summary> /// Logic for each method invocation (including constructor) /// The argument list is required because <code>InvocationExpressionSyntax</code> and /// <code>ObjectCreationExpressionSyntax</code> do not share a common interface. /// </summary> /// <param name="node"></param> /// <param name="argList"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitInvocationAndCreation(ExpressionSyntax node, ArgumentListSyntax argList, ExecutionState state) { var symbol = state.GetSymbol(node); MethodBehavior behavior = behaviorRepo.GetMethodBehavior(symbol); int i = 0; if (argList == null) { return(new VariableState(VariableTaint.UNKNOWN)); } foreach (var argument in argList.Arguments) { var argumentState = VisitExpression(argument.Expression, state); if (symbol != null) { SGLogging.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState); } if (behavior != null && //If the API is at risk (argumentState.taint == VariableTaint.TAINTED || //Tainted values argumentState.taint == VariableTaint.UNKNOWN) && Array.Exists(behavior.injectablesArguments, element => element == i) //If the current parameter can be injected. ) { var newRule = LocaleUtil.GetDescriptor(behavior.localeInjection); var diagnostic = Diagnostic.Create(newRule, node.GetLocation()); state.AnalysisContext.ReportDiagnostic(diagnostic); } else if (behavior != null && argumentState.taint == VariableTaint.CONSTANT && //Hard coded value Array.Exists(behavior.passwordArguments, element => element == i) //If the current parameter is a password ) { var newRule = LocaleUtil.GetDescriptor(behavior.localePassword); var diagnostic = Diagnostic.Create(newRule, node.GetLocation()); state.AnalysisContext.ReportDiagnostic(diagnostic); } //TODO: tainted all object passed in argument i++; } //Additionnal analysis by extension foreach (var ext in extensions) { ext.VisitInvocationAndCreation(node, argList, state); } return(new VariableState(VariableTaint.UNKNOWN)); }
public void AddTag(string variableAccess, VariableTag httpCookieSecure) { try { if (DebugMode) { SGLogging.Log(string.Format("Adding tag '{1}' to {0}", variableAccess, httpCookieSecure)); } Variables[variableAccess].AddTag(httpCookieSecure); } catch (KeyNotFoundException e) { } }
private static void VisitMethods(SyntaxNodeAnalysisContext ctx) { var node = ctx.Node as MethodDeclarationSyntax; if (node != null) { //This analyzer will trace the node only if it is in debug mode. if (SGLogging.IsConfigured()) { SGLogging.Log("== Method : " + node.Identifier.Text + " (BEGIN) ==", false); visitNodeRecursively(node, 0, ctx); SGLogging.Log("== Method : " + node.Identifier.Text + " (END) ==", false); } } }
private static void VisitMethodsEx(SyntaxNodeAnalysisContext ctx) { var node = ctx.Node as Microsoft.CodeAnalysis.VisualBasic.Syntax.MethodBlockSyntax; if (node != null) { //This analyzer will trace the node only if it is in debug mode. if (SGLogging.IsConfigured()) { SGLogging.Log("== Method : " + node.BlockStatement.GetText() + " (BEGIN) ==", false); visitNodeRecursivelyEx(node, 0, ctx); SGLogging.Log("== Method : " + node.BlockStatement.GetText() + " (END) ==", false); } } }
public void AddNewValue(string identifier, VariableState value) { if (Variables.ContainsKey(identifier)) //New variable in a different scope { if (DebugMode) { SGLogging.Log("Removing existing state for " + identifier); } Variables.Remove(identifier); } if (DebugMode) { SGLogging.Log(string.Format("Adding state for {0} ({1})", identifier, value)); } Variables.Add(identifier, value); }
private VariableState VisitObjectCreation(ObjectCreationExpressionSyntax node, ExecutionState state) { VariableState finalState = VisitInvocationAndCreation(node, node.ArgumentList, state); foreach (SyntaxNode child in node.DescendantNodes()) { if (child is NamedFieldInitializerSyntax) { finalState = finalState.merge(VisitNamedFieldInitializer((NamedFieldInitializerSyntax)child, state)); } else { SGLogging.Log(child.GetText().ToString().Trim() + " -> " + finalState); } } return(finalState); }
private VariableState VisitExpression(ExpressionSyntax expression, ExecutionState state) { //Invocation if (expression is InvocationExpressionSyntax) { var invocation = (InvocationExpressionSyntax)expression; return(VisitMethodInvocation(invocation, state)); } else if (expression is ObjectCreationExpressionSyntax) { var objCreation = (ObjectCreationExpressionSyntax)expression; return(VisitObjectCreation(objCreation, state)); } else if (expression is LiteralExpressionSyntax) { return(new VariableState(VariableTaint.CONSTANT)); } else if (expression is IdentifierNameSyntax) { var identifierName = (IdentifierNameSyntax)expression; return(VisitIdentifierName(identifierName, state)); } //Arithmetic : Addition else if (expression is BinaryExpressionSyntax) { var binaryExpression = (BinaryExpressionSyntax)expression; return(VisitBinaryExpression(binaryExpression, state)); } else if (expression is AssignmentExpressionSyntax) { var assignment = (AssignmentExpressionSyntax)expression; return(VisitAssignment(assignment, state)); } SGLogging.Log("Unsupported expression " + expression.GetType() + " (" + expression.ToString() + ")"); //Unsupported expression return(new VariableState(VariableTaint.UNKNOWN)); }
public void MergeValue(string identifier, VariableState value) { if (Variables.ContainsKey(identifier)) //Override existing value { var state = Variables[identifier]; var newState = state.merge(value); Variables.Remove(identifier); Variables.Add(identifier, newState); if (DebugMode) { SGLogging.Log(string.Format("Merging state for {0} ({1})", identifier, newState)); } } else { //Unexpected state if (DebugMode) { SGLogging.Log(string.Format("Merging state for {0} ({1}) .. /!\\ unexpected state", identifier, value)); } Variables.Add(identifier, value); } }
private VariableState VisitExpression(ExpressionSyntax expression, ExecutionState state) { //Invocation if (expression is InvocationExpressionSyntax) { var invocation = (InvocationExpressionSyntax)expression; return(VisitMethodInvocation(invocation, state)); } else if (expression is ObjectCreationExpressionSyntax) { var objCreation = (ObjectCreationExpressionSyntax)expression; return(VisitObjectCreation(objCreation, state)); } else if (expression is LiteralExpressionSyntax) { return(new VariableState(expression, VariableTaint.CONSTANT)); } else if (expression is IdentifierNameSyntax) { var identifierName = (IdentifierNameSyntax)expression; return(VisitIdentifierName(identifierName, state)); } //Arithmetic : Addition else if (expression is BinaryExpressionSyntax) { var binaryExpression = (BinaryExpressionSyntax)expression; return(VisitBinaryExpression(binaryExpression, state)); } //Handles in VisitNode() //else if (expression is AssignmentExpressionSyntax) //{ // var assignment = (AssignmentExpressionSyntax)expression; // return VisitAssignment(assignment, state); //} else if (expression is MemberAccessExpressionSyntax) { var memberAccess = (MemberAccessExpressionSyntax)expression; var leftExpression = memberAccess.Expression; var name = memberAccess.Name; return(VisitExpression(leftExpression, state)); } //else if (expression is ElementAccessExpressionSyntax) //{ // var elementAccess = (ElementAccessExpressionSyntax)expression; // return VisitElementAccess(elementAccess, elementAccess.ArgumentList, state); //} else if (expression is ArrayCreationExpressionSyntax) { var arrayCreation = (ArrayCreationExpressionSyntax)expression; return(VisitArrayCreation(arrayCreation, state)); } else if (expression is TypeOfExpressionSyntax) { var typeofEx = (TypeOfExpressionSyntax)expression; return(new VariableState(expression, VariableTaint.SAFE)); } //else if (expression is BinaryConditionalExpressionSyntax) //{ // var conditional = (BinaryConditionalExpressionSyntax)expression; // VisitExpression(conditional.FirstExpression, state); // var finalState = new VariableState(VariableTaint.SAFE); // var whenTrueState = VisitExpression(conditional.WhenTrue, state); // finalState.merge(whenTrueState); // var whenFalseState = VisitExpression(conditional.WhenFalse, state); // finalState.merge(whenFalseState); // return finalState; //} //else if (expression is CheckedExpressionSyntax) //{ // var checkedEx = (CheckedExpressionSyntax)expression; // return VisitExpression(checkedEx.Expression, state); //} else if (expression is QueryExpressionSyntax) { var query = (QueryExpressionSyntax)expression; var body = query.GetFirstToken(); return(new VariableState(expression, VariableTaint.UNKNOWN)); } else if (expression is InterpolatedStringExpressionSyntax) { var interpolatedString = (InterpolatedStringExpressionSyntax)expression; return(VisitInterpolatedString(interpolatedString, state)); } SGLogging.Log("Unsupported expression " + expression.GetType() + " (" + expression.ToString() + ")"); //Unsupported expression return(new VariableState(expression, VariableTaint.UNKNOWN)); }
private VariableState VisitExpression(ExpressionSyntax expression, ExecutionState state) { // TODO: Review other expresion types that are unique to VB. // TODO: Write tests to cover all these. //Invocation if (expression is InvocationExpressionSyntax) { var invocation = (InvocationExpressionSyntax)expression; return(VisitMethodInvocation(invocation, state)); } else if (expression is ObjectCreationExpressionSyntax) { var objCreation = (ObjectCreationExpressionSyntax)expression; return(VisitObjectCreation(objCreation, state)); } else if (expression is LiteralExpressionSyntax) { return(new VariableState(expression, VariableTaint.CONSTANT)); } else if (expression is IdentifierNameSyntax) { var identifierName = (IdentifierNameSyntax)expression; return(VisitIdentifierName(identifierName, state)); } //Arithmetic : Addition else if (expression is BinaryExpressionSyntax) { var binaryExpression = (BinaryExpressionSyntax)expression; return(VisitBinaryExpression(binaryExpression, state)); } else if (expression is MemberAccessExpressionSyntax) { var memberAccess = (MemberAccessExpressionSyntax)expression; var leftExpression = memberAccess.Expression; return(VisitExpression(leftExpression, state)); } else if (expression is ArrayCreationExpressionSyntax) { var arrayCreation = (ArrayCreationExpressionSyntax)expression; return(VisitArrayCreation(arrayCreation, state)); } else if (expression is TypeOfExpressionSyntax) { var typeofEx = (TypeOfExpressionSyntax)expression; return(new VariableState(expression, VariableTaint.SAFE)); } else if (expression is TernaryConditionalExpressionSyntax) { var conditional = (TernaryConditionalExpressionSyntax)expression; VisitExpression(conditional.Condition, state); var finalState = new VariableState(expression, VariableTaint.SAFE); var whenTrueState = VisitExpression(conditional.WhenTrue, state); finalState = finalState.merge(whenTrueState); var whenFalseState = VisitExpression(conditional.WhenFalse, state); finalState = finalState.merge(whenFalseState); return(finalState); } else if (expression is QueryExpressionSyntax) { var query = (QueryExpressionSyntax)expression; var body = query.Clauses; return(new VariableState(expression, VariableTaint.UNKNOWN)); } SGLogging.Log("Unsupported expression " + expression.GetType() + " (" + expression.ToString() + ")"); //Unsupported expression return(new VariableState(expression, VariableTaint.UNKNOWN)); }