/// <summary>
        /// Determines if the given method is a tainted data source and get the tainted target set.
        /// </summary>
        /// <param name="sourceSymbolMap"></param>
        /// <param name="method"></param>
        /// <param name="arguments"></param>
        /// <param name="pointsTos"></param>
        /// <param name="valueContents"></param>
        /// <param name="taintedTargets"></param>
        /// <returns></returns>
        public static bool IsSourceMethod(
            this TaintedDataSymbolMap <SourceInfo> sourceSymbolMap,
            IMethodSymbol method,
            ImmutableArray <IArgumentOperation> arguments,
            ImmutableArray <PointsToAbstractValue> pointsTos,
            ImmutableArray <ValueContentAbstractValue> valueContents,
            out PooledHashSet <string> taintedTargets)
        {
            taintedTargets = null;
            foreach (SourceInfo sourceInfo in sourceSymbolMap.GetInfosForType(method.ContainingType))
            {
                foreach ((MethodMatcher methodMatcher, ImmutableHashSet <(PointsToCheck pointsToCheck, string)> pointsToTaintedTargets) in sourceInfo.TaintedMethodsNeedsPointsToAnalysis)
                {
                    if (methodMatcher(method.Name, arguments))
                    {
                        IEnumerable <(PointsToCheck, string target)> positivePointsToTaintedTargets = pointsToTaintedTargets.Where(s => s.pointsToCheck(pointsTos));
                        if (positivePointsToTaintedTargets != null)
                        {
                            if (taintedTargets == null)
                            {
                                taintedTargets = PooledHashSet <string> .GetInstance();
                            }

                            taintedTargets.UnionWith(positivePointsToTaintedTargets.Select(s => s.target));
                        }
                    }
                }

                foreach ((MethodMatcher methodMatcher, ImmutableHashSet <(ValueContentCheck valueContentCheck, string)> valueContentTaintedTargets) in sourceInfo.TaintedMethodsNeedsValueContentAnalysis)
                {
                    if (methodMatcher(method.Name, arguments))
                    {
                        IEnumerable <(ValueContentCheck, string target)> positiveValueContentTaintedTargets = valueContentTaintedTargets.Where(s => s.valueContentCheck(pointsTos, valueContents));
                        if (positiveValueContentTaintedTargets != null)
                        {
                            if (taintedTargets == null)
                            {
                                taintedTargets = PooledHashSet <string> .GetInstance();
                            }

                            taintedTargets.UnionWith(positiveValueContentTaintedTargets.Select(s => s.target));
                        }
                    }
                }
            }

            return(taintedTargets != null);
        }
Пример #2
0
        private static ISet <string> GetLanguageCodesForSupportedCountries(
            IEnumerable <string> countries)
        {
            PooledHashSet <string> instance = PooledHashSet <string> .GetInstance();

            try
            {
                foreach (string country in countries)
                {
                    instance.UnionWith(EmailAndPhoneNoMustNotBePresentInTheSource.GetSupportedLocales(country));
                }
                return((ISet <string>)instance.ToImmutableHashSet <string>());
            }
            finally
            {
                instance.Free();
            }
        }
            public override TaintedDataAbstractValue VisitInvocation_NonLambdaOrDelegateOrLocalFunction(
                IMethodSymbol method,
                IOperation?visitedInstance,
                ImmutableArray <IArgumentOperation> visitedArguments,
                bool invokedAsDelegate,
                IOperation originalOperation,
                TaintedDataAbstractValue defaultValue)
            {
                // Always invoke base visit.
                TaintedDataAbstractValue result = base.VisitInvocation_NonLambdaOrDelegateOrLocalFunction(
                    method,
                    visitedInstance,
                    visitedArguments,
                    invokedAsDelegate,
                    originalOperation,
                    defaultValue);

                IEnumerable <IArgumentOperation> taintedArguments = GetTaintedArguments(visitedArguments);

                if (taintedArguments.Any())
                {
                    ProcessTaintedDataEnteringInvocationOrCreation(method, taintedArguments, originalOperation);
                }

                PooledHashSet <string>?          taintedTargets              = null;
                PooledHashSet <(string, string)>?taintedParameterPairs       = null;
                PooledHashSet <(string, string)>?sanitizedParameterPairs     = null;
                PooledHashSet <string>?          taintedParameterNamesCached = null;

                try
                {
                    IEnumerable <string> GetTaintedParameterNames()
                    {
                        IEnumerable <string> taintedParameterNames = visitedArguments
                                                                     .Where(s => this.GetCachedAbstractValue(s).Kind == TaintedDataAbstractValueKind.Tainted)
                                                                     .Select(s => s.Parameter.Name);

                        if (visitedInstance != null && this.GetCachedAbstractValue(visitedInstance).Kind == TaintedDataAbstractValueKind.Tainted)
                        {
                            taintedParameterNames = taintedParameterNames.Concat(TaintedTargetValue.This);
                        }

                        return(taintedParameterNames);
                    }

                    taintedParameterNamesCached = PooledHashSet <string> .GetInstance();

                    taintedParameterNamesCached.UnionWith(GetTaintedParameterNames());

                    if (this.DataFlowAnalysisContext.SourceInfos.IsSourceMethod(
                            method,
                            visitedArguments,
                            new Lazy <PointsToAnalysisResult?>(() => DataFlowAnalysisContext.PointsToAnalysisResult),
                            new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(() => (DataFlowAnalysisContext.PointsToAnalysisResult, DataFlowAnalysisContext.ValueContentAnalysisResult)),
                            out taintedTargets))
                    {
                        bool rebuildTaintedParameterNames = false;

                        foreach (string taintedTarget in taintedTargets)
                        {
                            if (taintedTarget != TaintedTargetValue.Return)
                            {
                                IArgumentOperation argumentOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == taintedTarget);
                                if (argumentOperation != null)
                                {
                                    rebuildTaintedParameterNames = true;
                                    this.CacheAbstractValue(argumentOperation, TaintedDataAbstractValue.CreateTainted(argumentOperation.Parameter, argumentOperation.Syntax, method));
                                }
                                else
                                {
                                    Debug.Fail("Are the tainted data sources misconfigured?");
                                }
                            }
                            else
                            {
                                result = TaintedDataAbstractValue.CreateTainted(method, originalOperation.Syntax, this.OwningSymbol);
                            }
                        }

                        if (rebuildTaintedParameterNames)
                        {
                            taintedParameterNamesCached.Clear();
                            taintedParameterNamesCached.UnionWith(GetTaintedParameterNames());
                        }
                    }

                    if (this.DataFlowAnalysisContext.SourceInfos.IsSourceTransferMethod(
                            method,
                            visitedArguments,
                            taintedParameterNamesCached,
                            out taintedParameterPairs))
                    {
                        foreach ((string ifTaintedParameter, string thenTaintedTarget) in taintedParameterPairs)
                        {
                            IOperation thenTaintedTargetOperation = visitedInstance != null && thenTaintedTarget == TaintedTargetValue.This
                                ? visitedInstance
                                : visitedArguments.FirstOrDefault(o => o.Parameter.Name == thenTaintedTarget);
                            if (thenTaintedTargetOperation != null)
                            {
                                SetTaintedForEntity(
                                    thenTaintedTargetOperation,
                                    this.GetCachedAbstractValue(
                                        visitedInstance != null && ifTaintedParameter == TaintedTargetValue.This
                                            ? visitedInstance
                                            : visitedArguments.FirstOrDefault(o => o.Parameter.Name == ifTaintedParameter)));
                            }
                            else
                            {
                                Debug.Fail("Are the tainted data sources misconfigured?");
                            }
                        }
                    }

                    if (visitedInstance != null && this.IsSanitizingInstanceMethod(method))
                    {
                        SetTaintedForEntity(visitedInstance, TaintedDataAbstractValue.NotTainted);
                    }

                    if (this.IsSanitizingMethod(
                            method,
                            visitedArguments,
                            taintedParameterNamesCached,
                            out sanitizedParameterPairs))
                    {
                        if (sanitizedParameterPairs.Count == 0)
                        {
                            // it was either sanitizing constructor or
                            // the short form or registering sanitizer method by just the name
                            result = TaintedDataAbstractValue.NotTainted;
                        }
                        else
                        {
                            foreach ((string ifTaintedParameter, string thenSanitizedTarget) in sanitizedParameterPairs)
                            {
                                if (thenSanitizedTarget == TaintedTargetValue.Return)
                                {
                                    result = TaintedDataAbstractValue.NotTainted;
                                    continue;
                                }

                                IArgumentOperation thenSanitizedTargetOperation = visitedArguments.FirstOrDefault(o => o.Parameter.Name == thenSanitizedTarget);
                                if (thenSanitizedTargetOperation != null)
                                {
                                    SetTaintedForEntity(thenSanitizedTargetOperation, TaintedDataAbstractValue.NotTainted);
                                }
                                else
                                {
                                    Debug.Fail("Are the tainted data sanitizers misconfigured?");
                                }
                            }
                        }
                    }
                }
                finally
                {
                    taintedTargets?.Dispose();
                    taintedParameterPairs?.Dispose();
                    sanitizedParameterPairs?.Dispose();
                    taintedParameterNamesCached?.Dispose();
                }

                return(result);
            }
Пример #4
0
 public void AddTrackedEntities(PooledHashSet <AnalysisEntity> builder) => builder.UnionWith(CoreAnalysisData.Keys);