Example #1
0
            // So we can treat the array as tainted when it's passed to other object constructors.
            // See HttpRequest_Form_Array_List_Diagnostic and HttpRequest_Form_List_Diagnostic tests.
            public override TaintedDataAbstractValue VisitArrayInitializer(IArrayInitializerOperation operation, object argument)
            {
                HashSet <SymbolAccess>   sourceOrigins     = null;
                TaintedDataAbstractValue baseAbstractValue = base.VisitArrayInitializer(operation, argument);

                if (baseAbstractValue.Kind == TaintedDataAbstractValueKind.Tainted)
                {
                    sourceOrigins = new HashSet <SymbolAccess>(baseAbstractValue.SourceOrigins);
                }

                IEnumerable <TaintedDataAbstractValue> taintedAbstractValues =
                    operation.ElementValues
                    .Select <IOperation, TaintedDataAbstractValue>(e => this.GetCachedAbstractValue(e))
                    .Where(v => v.Kind == TaintedDataAbstractValueKind.Tainted);

                if (baseAbstractValue.Kind == TaintedDataAbstractValueKind.Tainted)
                {
                    taintedAbstractValues = taintedAbstractValues.Concat(baseAbstractValue);
                }

                if (taintedAbstractValues.Any())
                {
                    return(TaintedDataAbstractValue.MergeTainted(taintedAbstractValues));
                }
                else
                {
                    return(baseAbstractValue);
                }
            }
            // So we can treat the array as tainted when it's passed to other object constructors.
            // See HttpRequest_Form_Array_List_Diagnostic and HttpRequest_Form_List_Diagnostic tests.
            public override TaintedDataAbstractValue VisitArrayInitializer(IArrayInitializerOperation operation, object argument)
            {
                HashSet <SymbolAccess>   sourceOrigins     = null;
                TaintedDataAbstractValue baseAbstractValue = base.VisitArrayInitializer(operation, argument);

                if (baseAbstractValue.Kind == TaintedDataAbstractValueKind.Tainted)
                {
                    sourceOrigins = new HashSet <SymbolAccess>(baseAbstractValue.SourceOrigins);
                }

                IEnumerable <TaintedDataAbstractValue> taintedAbstractValues =
                    operation.ElementValues
                    .Select <IOperation, TaintedDataAbstractValue>(e => this.GetCachedAbstractValue(e))
                    .Where(v => v.Kind == TaintedDataAbstractValueKind.Tainted);

                if (baseAbstractValue.Kind == TaintedDataAbstractValueKind.Tainted)
                {
                    taintedAbstractValues = taintedAbstractValues.Concat(baseAbstractValue);
                }

                TaintedDataAbstractValue result = null;

                if (taintedAbstractValues.Any())
                {
                    result = TaintedDataAbstractValue.MergeTainted(taintedAbstractValues);
                }

                IArrayCreationOperation arrayCreationOperation = operation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation);

                if (arrayCreationOperation?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                    this.DataFlowAnalysisContext.SourceInfos.IsSourceConstantArrayOfType(arrayTypeSymbol) &&
                    operation.ElementValues.All(s => GetValueContentAbstractValue(s).IsLiteralState))
                {
                    TaintedDataAbstractValue taintedDataAbstractValue = TaintedDataAbstractValue.CreateTainted(arrayTypeSymbol, arrayCreationOperation.Syntax, this.OwningSymbol);
                    result = result == null ? taintedDataAbstractValue : TaintedDataAbstractValue.MergeTainted(result, taintedDataAbstractValue);
                }

                if (result != null)
                {
                    return(result);
                }
                else
                {
                    return(baseAbstractValue);
                }
            }
            public override TaintedDataAbstractValue DefaultVisit(IOperation operation, object argument)
            {
                // This handles most cases of tainted data flowing from child operations to parent operations.
                // Examples:
                // - tainted input parameters to method calls returns, and out/ref parameters, tainted (assuming no interprocedural)
                // - adding a tainted value to something makes the result tainted
                // - instantiating an object with tainted data makes the new object tainted

                List <TaintedDataAbstractValue> taintedValues = null;

                foreach (IOperation childOperation in operation.Children)
                {
                    TaintedDataAbstractValue childValue = Visit(childOperation, argument);
                    if (childValue.Kind == TaintedDataAbstractValueKind.Tainted)
                    {
                        if (taintedValues == null)
                        {
                            taintedValues = new List <TaintedDataAbstractValue>();
                        }

                        taintedValues.Add(childValue);
                    }
                }

                if (taintedValues != null)
                {
                    if (taintedValues.Count == 1)
                    {
                        return(taintedValues[0]);
                    }
                    else
                    {
                        return(TaintedDataAbstractValue.MergeTainted(taintedValues));
                    }
                }
                else
                {
                    return(ValueDomain.UnknownOrMayBeValue);
                }
            }
            public override TaintedDataAbstractValue Merge(TaintedDataAbstractValue value1, TaintedDataAbstractValue value2)
            {
                //     N T
                //   +----
                // N | N T
                // T | T T

                if (value1 == null)
                {
                    return(value2);
                }
                else if (value2 == null)
                {
                    return(value1);
                }

                if (value1.Kind == TaintedDataAbstractValueKind.Tainted && value2.Kind == TaintedDataAbstractValueKind.Tainted)
                {
                    // If both are tainted, we need to merge their origins.
                    return(TaintedDataAbstractValue.MergeTainted(value1, value2));
                }

                return(value1.Kind > value2.Kind ? value1 : value2);
            }