Пример #1
0
        private VariableState VisitAssignment(VisualBasicSyntaxNode node,
                                              ExpressionSyntax leftExpression,
                                              ExpressionSyntax rightExpression,
                                              ExecutionState state)
        {
            var            symbol   = state.GetSymbol(leftExpression);
            MethodBehavior behavior = BehaviorRepo.GetMethodBehavior(symbol);

            var variableState = VisitExpression(rightExpression, state);

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

            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);
        }
        /// <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(node, VariableTaint.Unknown));
            }

            var returnState = new VariableState(node, VariableTaint.Safe);

            foreach (var argument in argList.Arguments)
            {
                var argumentState = VisitExpression(argument.Expression, state);

                if (symbol != null)
                {
                    Logger.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState);
                }

                if (behavior != null)
                {
                    //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());
                        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());
                        state.AnalysisContext.ReportDiagnostic(diagnostic);
                    }
                    else if (Array.Exists(behavior.TaintFromArguments, element => element == i))
                    {
                        returnState = returnState.Merge(argumentState);
                    }
                }

                //TODO: tainted all object passed in argument

                i++;
            }

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

            var hasTaintFromArguments = behavior?.TaintFromArguments?.Length > 0;

            return(hasTaintFromArguments ? returnState : new VariableState(node, VariableTaint.Unknown));
        }
Пример #3
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);
        }