// 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); }