private IReadOnlyDictionary <int, PostCondition> GetPostConditions(MethodBehavior behavior, bool isExtensionMethod, ArgumentListSyntax argList, ExecutionState state)
        {
            if (behavior.Conditions == null)
            {
                return(behavior.PostConditions);
            }

            foreach (var condition in behavior.Conditions)
            {
                if (CheckPrecondition(condition.If, isExtensionMethod, argList, state))
                {
                    return(condition.Then);
                }
            }

            return(behavior.PostConditions);
        }
Esempio n. 2
0
        /// <summary>
        /// Identifier name include variable name.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private VariableState VisitIdentifierName(IdentifierNameSyntax expression, ExecutionState state)
        {
            var value = ResolveIdentifier(expression.Identifier);

            if (state.VariableStates.TryGetValue(value, out var varState))
            {
                return(varState);
            }

            var symbol = state.GetSymbol(expression);

            switch (symbol)
            {
            case null:
                return(new VariableState(expression, VariableTaint.Unknown));

            case IFieldSymbol field:
                if (field.IsConst)
                {
                    return(new VariableState(expression, VariableTaint.Constant));
                }

                if (!field.IsReadOnly)
                {
                    return(new VariableState(expression, VariableTaint.Unknown));
                }

                switch (field.GetTypeName())     // todo: move out to config of readonly values, that are constant in fact
                {
                case "System.String.Empty":
                case "System.IntPtr.Zero":
                case "System.IO.Path.AltDirectorySeparatorChar":
                case "System.IO.Path.DirectorySeparatorChar":
                case "System.IO.Path.InvalidPathChars":
                case "System.IO.Path.PathSeparator":
                case "System.IO.Path.VolumeSeparatorChar":
                    return(new VariableState(expression, VariableTaint.Constant));
                }

                return(new VariableState(expression, VariableTaint.Unknown));

            case IPropertySymbol prop:
                if (prop.IsVirtual || prop.IsOverride || prop.IsAbstract)
                {
                    return(new VariableState(expression, VariableTaint.Unknown));
                }

                // TODO: Use public API
                var syntaxNodeProperty = prop.GetMethod.GetType().GetTypeInfo().BaseType.GetTypeInfo().GetDeclaredProperty("Syntax");
                var syntaxNode         = (VisualBasicSyntaxNode)syntaxNodeProperty?.GetValue(prop.GetMethod);
                switch (syntaxNode)
                {
                case null:
                    return(new VariableState(expression, VariableTaint.Unknown));

                case AccessorBlockSyntax blockSyntax:
                    // Recursion prevention: set the value into the map if we'll get back resolving it while resolving it dependency
                    state.AddNewValue(value, new VariableState(expression, VariableTaint.Unknown));
                    return(VisitBlock(blockSyntax, state));
                }

                return(new VariableState(expression, VariableTaint.Unknown));
            }

            return(new VariableState(expression, VariableTaint.Unknown));
        }
Esempio n. 3
0
        private VariableState VisitArrayCreation(SyntaxNode node, CollectionInitializerSyntax arrayInit, ExecutionState state)
        {
            var finalState = new VariableState(node, VariableTaint.Safe);

            if (arrayInit == null)
            {
                return(finalState);
            }

            foreach (var ex in arrayInit.Initializers)
            {
                var exprState = VisitExpression(ex, state);
                finalState = finalState.Merge(exprState);
            }

            return(finalState);
        }
Esempio n. 4
0
 private VariableState VisitAssignmentStatement(AssignmentStatementSyntax node, ExecutionState state)
 {
     return(VisitAssignment(node, node.Left, node.Right, state));
 }
Esempio n. 5
0
        private VariableState VisitObjectCreation(ObjectCreationExpressionSyntax node, ExecutionState state)
        {
            VariableState finalState = VisitInvocationAndCreation(node, node.ArgumentList, state);

            foreach (SyntaxNode child in node.DescendantNodes())
            {
                if (child is NamedFieldInitializerSyntax namedFieldInitializerSyntax)
                {
                    finalState = finalState.Merge(VisitNamedFieldInitializer(namedFieldInitializerSyntax, state));
                }
                else
                {
                    Logger.Log(child.GetText().ToString().Trim() + " -> " + finalState);
                }
            }

            return(finalState);
        }
Esempio n. 6
0
        /// <summary>
        /// Unwrap
        /// </summary>
        /// <param name="declaration"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private VariableState VisitLocalDeclaration(LocalDeclarationStatementSyntax declaration, ExecutionState state)
        {
            foreach (var i in declaration.Declarators)
            {
                return(VisitVariableDeclaration(i, state));
            }

            return(new VariableState(declaration, VariableTaint.Unknown));
        }
Esempio n. 7
0
        private VariableState VisitExpression(ExpressionSyntax expression, ExecutionState state)
        {
            // TODO: Review other expression types that are unique to VB.
            // TODO: Write tests to cover all these.

            switch (expression)
            {
            case InvocationExpressionSyntax invocationExpressionSyntax:
                return(VisitMethodInvocation(invocationExpressionSyntax, state));

            case ObjectCreationExpressionSyntax objectCreationExpressionSyntax:
                return(VisitObjectCreation(objectCreationExpressionSyntax, state));

            case LiteralExpressionSyntax _:
                return(new VariableState(expression, VariableTaint.Constant));

            case IdentifierNameSyntax identifierNameSyntax:
                return(VisitIdentifierName(identifierNameSyntax, state));

            case BinaryExpressionSyntax binaryExpressionSyntax:
                return(VisitBinaryExpression(binaryExpressionSyntax, state));

            case MemberAccessExpressionSyntax memberAccessExpressionSyntax:
                return(VisitExpression(memberAccessExpressionSyntax.Name, state));

            case ArrayCreationExpressionSyntax arrayCreationExpressionSyntax:
                return(VisitArrayCreation(arrayCreationExpressionSyntax, arrayCreationExpressionSyntax.Initializer, state));

            case CollectionInitializerSyntax collectionInitializerSyntax:
                return(VisitArrayCreation(collectionInitializerSyntax, collectionInitializerSyntax, state));

            case TypeOfExpressionSyntax typeOfExpressionSyntax:
                return(new VariableState(typeOfExpressionSyntax, VariableTaint.Safe));

            case GetTypeExpressionSyntax getTypeExpressionSyntax:
                return(new VariableState(getTypeExpressionSyntax, VariableTaint.Safe));

            case TernaryConditionalExpressionSyntax ternaryConditionalExpressionSyntax:
            {
                VisitExpression(ternaryConditionalExpressionSyntax.Condition, state);
                var finalState = new VariableState(ternaryConditionalExpressionSyntax, VariableTaint.Safe);

                var whenTrueState = VisitExpression(ternaryConditionalExpressionSyntax.WhenTrue, state);
                finalState = finalState.Merge(whenTrueState);
                var whenFalseState = VisitExpression(ternaryConditionalExpressionSyntax.WhenFalse, state);
                finalState = finalState.Merge(whenFalseState);

                return(finalState);
            }

            case QueryExpressionSyntax queryExpressionSyntax:
                return(new VariableState(queryExpressionSyntax, VariableTaint.Unknown));

            case DirectCastExpressionSyntax directCastExpressionSyntax:
                return(VisitExpression(directCastExpressionSyntax.Expression, state));

            case CTypeExpressionSyntax cTypeExpressionSyntax:
                return(VisitExpression(cTypeExpressionSyntax.Expression, state));
            }

            Logger.Log("Unsupported expression " + expression.GetType() + " (" + expression + ")");
            return(new VariableState(expression, VariableTaint.Unknown));
        }
 /// <summary>
 /// Identifier name include variable name.
 /// </summary>
 /// <param name="expression"></param>
 /// <param name="state"></param>
 /// <returns></returns>
 private VariableState VisitIdentifierName(IdentifierNameSyntax expression, ExecutionState state)
 {
     return(ResolveVariableState(expression, state));
 }
 private VariableState VisitMemberAccessExpression(MemberAccessExpressionSyntax expression, ExecutionState state)
 {
     return(ResolveVariableState(expression, state));
 }
        private VariableState VisitAssignmentStatement(AssignmentStatementSyntax node, ExecutionState state)
        {
            var assigmentState = VisitAssignment(node, node.Left, node.Right, state);

            return(MergeVariableState(node.Left, assigmentState, state));
        }
        private VariableState VisitNamedFieldInitializer(NamedFieldInitializerSyntax node, ExecutionState state, VariableState currentScope)
        {
            var assigmentState = VisitAssignment(node, node.Name, node.Expression, state);

            return(MergeVariableState(node.Name, assigmentState, state, currentScope));
        }
        private VariableState VisitMemberAccessExpression(MemberAccessExpressionSyntax expression, ExecutionState state)
        {
            var varState = VisitIdentifierName(expression, state);

            if (varState.Taint == VariableTaint.Constant || expression.Expression == null)
            {
                return(varState);
            }

            var expressionState = VisitExpression(expression.Expression, state);

            varState.MergeTaint(expressionState.Taint);

            return(varState);
        }
        /// <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>
        private VariableState VisitInvocationAndCreation(ExpressionSyntax node,
                                                         ArgumentListSyntax argList,
                                                         ExecutionState state,
                                                         VariableTaint?initialTaint        = null,
                                                         VariableState memberVariableState = null)
        {
            var symbol = state.GetSymbol(node);

            if (symbol == null)
            {
                return(new VariableState(node, initialTaint ?? VariableTaint.Unknown));
            }

            var  methodSymbol      = symbol as IMethodSymbol;
            bool isExtensionMethod = methodSymbol?.ReducedFrom != null;
            var  behavior          = symbol.GetMethodBehavior(ProjectConfiguration.Behavior);
            IReadOnlyDictionary <int, PostCondition> postConditions = null;

            if (behavior != null)
            {
                postConditions = GetPostConditions(behavior, isExtensionMethod, argList, state);
            }

            PostCondition returnPostCondition = null;

            postConditions?.TryGetValue(-1, out returnPostCondition);

            VariableState returnState = initialTaint != null && !symbol.IsStatic
                                            ? new VariableState(node, initialTaint.Value)
                                            : new VariableState(node, argList?.Arguments.Count > 0 && behavior != null
                                                                          ? VariableTaint.Unset
                                                                          : VariableTaint.Unknown);

            var argCount       = argList?.Arguments.Count;
            var argumentStates = argCount.HasValue &&
                                 argCount.Value > 0 &&
                                 (postConditions?.Any(c => c.Key != -1 && (c.Value.Taint != 0ul || c.Value.TaintFromArguments.Any())) == true ||
                                  methodSymbol != null && methodSymbol.Parameters.Any(x => x.RefKind != RefKind.None))
                                     ? new VariableState[argCount.Value]
                                     : null;

            for (var i = 0; i < argList?.Arguments.Count; i++)
            {
                var argument      = argList.Arguments[i];
                var argumentState = VisitExpression(argument.Expression, state);
                if (argumentStates != null)
                {
                    argumentStates[i] = argumentState;
                }

#if DEBUG
                Logger.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState);
#endif

                var adjustedArgumentIdx = isExtensionMethod ? i + 1 : i;

                if (behavior != null)
                {
                    if ((argumentState.Taint & (ProjectConfiguration.AuditMode
                                                    ? VariableTaint.Tainted | VariableTaint.Unknown
                                                    : VariableTaint.Tainted)) != 0)
                    {
                        //If the current parameter can be injected.
                        if (behavior.InjectableArguments.TryGetValue(adjustedArgumentIdx, out var injectableArgument) &&
                            (injectableArgument.RequiredTaintBits & (ulong)argumentState.Taint) != injectableArgument.RequiredTaintBits)
                        {
                            var newRule    = LocaleUtil.GetDescriptor(injectableArgument.Locale);
                            var diagnostic = Diagnostic.Create(newRule, argument.Expression.GetLocation(), GetMethodName(node), (i + 1).ToNthString());
                            state.AnalysisContext.ReportDiagnostic(diagnostic);
                        }
                    }
                    else if (argumentState.Taint == VariableTaint.Constant)
                    {
                        if (behavior.InjectableArguments.TryGetValue(adjustedArgumentIdx, out var injectableArgument) &&
                            injectableArgument.Not && (injectableArgument.RequiredTaintBits & (ulong)argumentState.Taint) != 0ul)
                        {
                            var newRule    = LocaleUtil.GetDescriptor(injectableArgument.Locale);
                            var diagnostic = Diagnostic.Create(newRule, argument.Expression.GetLocation(), GetMethodName(node), (i + 1).ToNthString());
                            state.AnalysisContext.ReportDiagnostic(diagnostic);
                        }
                    }
                }

                var argumentToSearch = adjustedArgumentIdx;
                if (methodSymbol != null &&
                    i >= methodSymbol.Parameters.Length &&
                    methodSymbol.Parameters[methodSymbol.Parameters.Length - 1].IsParams)
                {
                    argumentToSearch = isExtensionMethod ? methodSymbol.Parameters.Length : methodSymbol.Parameters.Length - 1;
                }

                if (returnPostCondition == null ||
                    returnPostCondition.TaintFromArguments.Contains(argumentToSearch))
                {
                    returnState.MergeTaint(argumentState.Taint);
                }

                //TODO: taint all objects passed as arguments
                //if (argument.Expression is IdentifierNameSyntax identifierNameSyntax)
                //{
                //    var argumentType = state.AnalysisContext.SemanticModel.GetTypeInfo(argument.Expression).Type;
                //    if (argumentType.IsReferenceType &&
                //        argumentType.IsType("System.String")) // string is immutable
                //    {
                //        state.MergeValue(ResolveIdentifier(identifierNameSyntax.Identifier),
                //                         argumentState.Merge(new VariableState(argument, VariableTaint.Unknown)));
                //    }
                //}
            }

            if (returnPostCondition != null)
            {
                returnState.ApplyTaint(returnPostCondition.Taint);
            }

            if (argumentStates != null)
            {
                for (var i = 0; i < argList.Arguments.Count; i++)
                {
                    var adjustedPostConditionIdx = isExtensionMethod ? i + 1 : i;

                    if (postConditions != null && postConditions.TryGetValue(adjustedPostConditionIdx, out var postCondition))
                    {
                        foreach (var argIdx in postCondition.TaintFromArguments)
                        {
                            var adjustedArgumentIdx = isExtensionMethod ? argIdx + 1 : argIdx;
                            argumentStates[adjustedPostConditionIdx].MergeTaint(argumentStates[adjustedArgumentIdx].Taint);
                        }

                        argumentStates[adjustedPostConditionIdx].ApplyTaint(postCondition.Taint);
                    }
                    else if (methodSymbol != null)
                    {
                        if (i >= methodSymbol.Parameters.Length)
                        {
                            if (!methodSymbol.Parameters[methodSymbol.Parameters.Length - 1].IsParams)
                            {
                                throw new IndexOutOfRangeException();
                            }
                        }
                        else if (methodSymbol.Parameters[i].RefKind != RefKind.None)
                        {
                            argumentStates[i].MergeTaint(returnState.Taint);
                        }
                    }
                }
            }

            if (memberVariableState != null &&
                methodSymbol != null &&
                methodSymbol.ReturnsVoid &&
                !methodSymbol.IsStatic &&
                methodSymbol.Parameters.All(x => x.RefKind == RefKind.None))
            {
                memberVariableState.MergeTaint(returnState.Taint);
            }

            //Additional analysis by extension
            foreach (var ext in Extensions)
            {
                ext.VisitInvocationAndCreation(node, argList, state, ProjectConfiguration);
            }

            return(returnState);
        }
        private bool CheckPrecondition(IReadOnlyDictionary <int, object> condition, bool isExtensionMethod, ArgumentListSyntax argList, ExecutionState state)
        {
            for (var i = 0; i < argList?.Arguments.Count; i++)
            {
                var argument            = argList.Arguments[i];
                var adjustedArgumentIdx = isExtensionMethod ? i + 1 : i;

                if (!condition.TryGetValue(adjustedArgumentIdx, out var preconditionArgumentValue))
                {
                    continue;
                }

                var calculatedArgumentValue = state.AnalysisContext.SemanticModel.GetConstantValue(argument.Expression);
                if (calculatedArgumentValue.HasValue && calculatedArgumentValue.Value.Equals(preconditionArgumentValue))
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
Esempio n. 15
0
 public virtual void VisitInvocationAndCreation(VBSyntax.ExpressionSyntax node, VBSyntax.ArgumentListSyntax argList, ExecutionState state)
 {
 }
        private VariableState ResolveVariableState(ExpressionSyntax expression, ExecutionState state)
        {
            var varState = GetVariableState(expression, state);

            if (varState != null)
            {
                return(varState);
            }

            var symbol = state.GetSymbol(expression);

            switch (symbol)
            {
            case null:
                return(new VariableState(expression, VariableTaint.Unknown));

            case IFieldSymbol field:
                if (field.IsConst)
                {
                    return(new VariableState(expression, VariableTaint.Constant));
                }

                if (!field.IsReadOnly)
                {
                    return(new VariableState(expression, VariableTaint.Unknown));
                }

                var contantFields = ConfigurationManager.Instance.GetProjectConfiguration(state.AnalysisContext.Options.AdditionalFiles)
                                    .ConstantFields;

                if (contantFields.Contains(field.GetTypeName()))
                {
                    return(new VariableState(expression, VariableTaint.Constant));
                }

                return(new VariableState(expression, VariableTaint.Unknown));

            case IPropertySymbol prop:
                if (prop.IsVirtual || prop.IsOverride || prop.IsAbstract)
                {
                    return(new VariableState(expression, VariableTaint.Unknown));
                }

                // TODO: Use public API
                var syntaxNodeProperty = prop.GetMethod.GetType().GetTypeInfo().BaseType.GetTypeInfo().GetDeclaredProperty("Syntax");
                var syntaxNode         = (VisualBasicSyntaxNode)syntaxNodeProperty?.GetValue(prop.GetMethod);
                switch (syntaxNode)
                {
                case null:
                    return(new VariableState(expression, VariableTaint.Unknown));

                case AccessorBlockSyntax blockSyntax:
                    // Recursion prevention: set the value into the map if we'll get back resolving it while resolving it dependency
                    MergeVariableState(expression, new VariableState(expression, VariableTaint.Unknown), state);
                    return(VisitBlock(blockSyntax, state));
                }

                return(new VariableState(expression, VariableTaint.Unknown));
            }

            return(new VariableState(expression, VariableTaint.Unknown));
        }
Esempio n. 17
0
        /// <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)
        {
            //Logger.Log(node.GetType().ToString());

            switch (node)
            {
            case LocalDeclarationStatementSyntax localDeclaration:
                return(VisitLocalDeclaration(localDeclaration, state));

            case VariableDeclaratorSyntax variableDeclaration:
                return(VisitVariableDeclaration(variableDeclaration, state));

            case AssignmentStatementSyntax assignment:
                return(VisitAssignmentStatement(assignment, state));

            case ExpressionStatementSyntax expressionStatement:
                return(VisitExpressionStatement(expressionStatement, state));

            case ExpressionSyntax expression:
                return(VisitExpression(expression, state));

            case MethodBlockSyntax methodBlock:
                return(VisitMethodDeclaration(methodBlock, methodBlock.SubOrFunctionStatement.ParameterList, state));

            case ConstructorBlockSyntax constructorBlockSyntax:
                return(VisitMethodDeclaration(constructorBlockSyntax, constructorBlockSyntax.SubNewStatement.ParameterList, state));

            case PropertyBlockSyntax propertyBlockSyntax:
            {
                foreach (var accessor in propertyBlockSyntax.Accessors)
                {
                    VisitBlock(accessor, state);
                }

                return(new VariableState(node, VariableTaint.Unknown));
            }

            case ReturnStatementSyntax returnStatementSyntax:
                if (returnStatementSyntax.Expression == null)
                {
                    return(new VariableState(node, VariableTaint.Unknown));
                }

                return(VisitExpression(returnStatementSyntax.Expression, state));

            case ForEachStatementSyntax forEachSyntax:
                return(VisitForEach(forEachSyntax, state));
            }

            foreach (var n in node.ChildNodes())
            {
                VisitNode(n, state);
            }

            var isBlockStatement = node is IfStatementSyntax ||
                                   node is ForStatementSyntax;

            if (!isBlockStatement)
            {
                Logger.Log("Unsupported statement " + node.GetType() + " (" + node + ")");
            }

            return(new VariableState(node, VariableTaint.Unknown));
        }
 /// <summary>
 /// Entry point that visits the method statements.
 /// </summary>
 private VariableState VisitMethodDeclaration(BaseMethodDeclarationSyntax node, ExecutionState state)
 {
     if (ProjectConfiguration.AuditMode)
     {
         TaintParameters(node, state);
     }
     else
     {
         var symbol = state.AnalysisContext.SemanticModel.GetDeclaredSymbol(node);
         if (symbol != null)
         {
             if (symbol is IMethodSymbol methodSymbol && methodSymbol.IsStatic && methodSymbol.Name == "Main")
             {
                 TaintParameters(node, state);
             }
             else if (symbol.IsTaintEntryPoint(ProjectConfiguration.TaintEntryPoints))
             {
                 TaintParameters(node, state);
             }
         }
     }
Esempio n. 19
0
        /// <summary>
        /// Evaluate expression that contains a list of assignment.
        /// </summary>
        /// <param name="declaration"></param>
        /// <param name="state"></param>
        private VariableState VisitVariableDeclaration(VariableDeclaratorSyntax declaration, ExecutionState state)
        {
            var lastState = new VariableState(declaration, VariableTaint.Unknown);

            foreach (var variable in declaration.Names)
            {
                var identifier  = variable.Identifier;
                var initializer = declaration.Initializer;
                if (initializer != null)
                {
                    EqualsValueSyntax equalsClause = initializer;

                    VariableState varState = VisitExpression(equalsClause.Value, state);

                    //varState.SetType(lastState.type);
                    state.AddNewValue(ResolveIdentifier(identifier), varState);
                    lastState = varState;
                }

                if (declaration.AsClause is AsNewClauseSyntax asNewClauseSyntax)
                {
                    VariableState varState = VisitExpression(asNewClauseSyntax.NewExpression, state);
                    state.AddNewValue(ResolveIdentifier(identifier), varState);
                    lastState = varState;
                }
            }

            return(lastState);
        }
        private VariableState VisitBlock(BlockSyntax node, ExecutionState state)
        {
            var lastState = new VariableState(node, VariableTaint.Unknown);

            return(VisitStatements(node.Statements, state, lastState));
        }
Esempio n. 21
0
        /// <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,
                                                         VariableState?initialVariableState = null)
        {
            var symbol = state.GetSymbol(node);

            if (symbol == null)
            {
                return(new VariableState(node, VariableTaint.Unknown));
            }

            var behavior    = BehaviorRepo.GetMethodBehavior(symbol);
            var returnState = initialVariableState.HasValue && !symbol.IsStatic
                                  ? initialVariableState.Value
                                  : new VariableState(node,
                                                      behavior?.TaintFromArguments?.Any() == true ? VariableTaint.Safe
                                                                                                  : VariableTaint.Unknown);

            for (var i = 0; i < argList?.Arguments.Count; i++)
            {
                var argument      = argList.Arguments[i];
                var argumentState = VisitExpression(argument.GetExpression(), state);

                Logger.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState);

                if (behavior == null)
                {
                    continue;
                }

                //If the API is at risk
                if ((argumentState.Taint == VariableTaint.Tainted ||
                     argumentState.Taint == VariableTaint.Unknown) && //Tainted values
                    //If the current parameter can be injected.
                    Array.Exists(behavior.InjectablesArguments, element => element == i))
                {
                    var newRule    = LocaleUtil.GetDescriptor(behavior.LocaleInjection);
                    var diagnostic = Diagnostic.Create(newRule, node.GetLocation(), GetMethodName(node), (i + 1).ToNthString());
                    state.AnalysisContext.ReportDiagnostic(diagnostic);
                }
                else if (argumentState.Taint == VariableTaint.Constant && //Hard coded value
                                                                          //If the current parameter is a password
                         Array.Exists(behavior.PasswordArguments, element => element == i))
                {
                    var newRule    = LocaleUtil.GetDescriptor(behavior.LocalePassword);
                    var diagnostic = Diagnostic.Create(newRule, node.GetLocation(), GetMethodName(node), (i + 1).ToNthString());
                    state.AnalysisContext.ReportDiagnostic(diagnostic);
                }
                else if (Array.Exists(behavior.TaintFromArguments, element => element == i))
                {
                    returnState = returnState.Merge(argumentState);
                }

                //TODO: taint all objects passed as arguments
            }

            //Additional analysis by extension
            foreach (var ext in Extensions)
            {
                ext.VisitInvocationAndCreation(node, argList, state);
            }

            return(returnState);
        }
        private VariableState VisitStatements(SyntaxList <StatementSyntax> statements, ExecutionState state, VariableState lastState)
        {
            foreach (StatementSyntax statement in statements)
            {
                var statementState = VisitNode(statement, state);
                lastState = statementState;

                foreach (var ext in Extensions)
                {
                    ext.VisitStatement(statement, state, ProjectConfiguration);
                }
            }

            return(lastState);
        }
Esempio n. 23
0
 private VariableState VisitNamedFieldInitializer(NamedFieldInitializerSyntax node, ExecutionState state)
 {
     return(VisitAssignment(node, node.Name, node.Expression, state));
 }
Esempio n. 24
0
        private VariableState VisitAssignment(VisualBasicSyntaxNode node,
                                              ExpressionSyntax leftExpression,
                                              ExpressionSyntax rightExpression,
                                              ExecutionState state)
        {
            var            leftSymbol = state.GetSymbol(leftExpression);
            MethodBehavior behavior   = null;

            if (leftSymbol != null)
            {
                behavior = leftSymbol.GetMethodBehavior(state.AnalysisContext.Options.AdditionalFiles);
            }

            var variableState = VisitExpression(rightExpression, state);

            //Additional analysis by extension
            foreach (var ext in Extensions)
            {
                ext.VisitAssignment(node, state, behavior, leftSymbol, variableState);
            }

            if (leftSymbol != null)
            {
                var rightTypeSymbol = state.AnalysisContext.SemanticModel.GetTypeInfo(rightExpression).Type;
                if (rightTypeSymbol == null)
                {
                    return(new VariableState(rightExpression, VariableTaint.Unknown));
                }

                var leftTypeSymbol = state.AnalysisContext.SemanticModel.GetTypeInfo(leftExpression).Type;
                if (!state.AnalysisContext.SemanticModel.Compilation.ClassifyConversion(rightTypeSymbol, leftTypeSymbol).Exists)
                {
                    return(new VariableState(rightExpression, VariableTaint.Unknown));
                }
            }

            IdentifierNameSyntax parentIdentifierSyntax = GetParentIdentifier(leftExpression);

            if (parentIdentifierSyntax != null)
            {
                state.MergeValue(ResolveIdentifier(parentIdentifierSyntax.Identifier), variableState);
            }

            if (behavior != null &&                              //Injection
                behavior.IsInjectableField &&
                variableState.Taint != VariableTaint.Constant && //Skip safe values
                variableState.Taint != VariableTaint.Safe)
            {
                var newRule    = LocaleUtil.GetDescriptor(behavior.LocaleInjection, "title_assignment");
                var diagnostic = Diagnostic.Create(newRule, node.GetLocation());
                state.AnalysisContext.ReportDiagnostic(diagnostic);
            }

            if (behavior != null &&                            //Known Password API
                behavior.IsPasswordField &&
                variableState.Taint == VariableTaint.Constant) //Only constant
            {
                var newRule    = LocaleUtil.GetDescriptor(behavior.LocalePassword, "title_assignment");
                var diagnostic = Diagnostic.Create(newRule, node.GetLocation());
                state.AnalysisContext.ReportDiagnostic(diagnostic);
            }

            //TODO: taint the variable being assigned.

            return(variableState);
        }
Esempio n. 25
0
        /// <summary>
        /// Combine the state of the two operands. Binary expression include concatenation.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private VariableState VisitBinaryExpression(BinaryExpressionSyntax expression, ExecutionState state)
        {
            VariableState left  = VisitExpression(expression.Left, state);
            VariableState right = VisitExpression(expression.Right, state);

            return(left.Merge(right));
        }
Esempio n. 26
0
 public virtual void VisitEnd(SyntaxNode node, ExecutionState state)
 {
 }
Esempio n. 27
0
 private VariableState VisitExpressionStatement(ExpressionStatementSyntax node, ExecutionState state)
 {
     return(VisitExpression(node.Expression, state)); //Simply unwrap the expression
 }
Esempio n. 28
0
 public virtual void VisitStatement(VBSyntax.StatementSyntax node, ExecutionState state)
 {
 }
Esempio n. 29
0
        /// <summary>
        /// Entry point that visits the method statements.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private VariableState VisitMethodDeclaration(MethodBlockBaseSyntax node, ParameterListSyntax parameterList, ExecutionState state)
        {
            foreach (ParameterSyntax parameter in parameterList.Parameters)
            {
                state.AddNewValue(ResolveIdentifier(parameter.Identifier.Identifier),
                                  new VariableState(parameter, VariableTaint.Tainted));
            }

            return(VisitBlock(node, state));
        }
        private VariableState VisitObjectCreation(ObjectCreationExpressionSyntax node, ExecutionState state)
        {
            VariableState finalState = VisitInvocationAndCreation(node, node.ArgumentList, state);

            foreach (SyntaxNode child in node.DescendantNodes())
            {
                if (child is AssignmentExpressionSyntax assignmentExpressionSyntax)
                {
                    var assignmentState = VisitAssignment(assignmentExpressionSyntax, state);
                    MergeVariableState(assignmentExpressionSyntax.Left, assignmentState, state, finalState);
                }
                else
                {
#if DEBUG
                    Logger.Log(child.GetText().ToString().Trim() + " -> " + finalState);
#endif
                }
            }

            return(finalState);
        }