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));
        }
示例#6
0
 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);
                }
            }
        }
示例#8
0
        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);
                }
            }
        }
示例#9
0
 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));
        }
示例#12
0
 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));
        }