private void setNamedArguments(FlowOutputSet callInput, CallSignature?callSignature, Signature signature, IEnumerable <ValuePoint> arguments) { int i = 0; foreach (var arg in arguments) { if (i >= signature.FormalParams.Count) { break; } var param = signature.FormalParams[i]; var argumentVar = callInput.GetVariable(new VariableIdentifier(param.Name)); // var argumentValue = arg.Value.ReadMemory(Output); List <ValueInfo> values = new List <ValueInfo>(); var varID = getVariableIdentifier(arg.Value); List <Value> argumentValues = new List <Value>(arg.Value.ReadMemory(Output).PossibleValues); values.Add(new ValueInfo(argumentValues, varID)); bool nullValue = hasPossibleNullValue(arg); TaintInfo argTaint = mergeTaint(values, nullValue); setTaint(argumentVar, argTaint); /*var argTaint = getTaint(arg.Value); * * setTaint(argumentVar, argTaint); * //argumentVar.WriteMemory(callInput.Snapshot, argumentValue);*/ ++i; } // TODO: if (arguments.Count() < signature.FormalParams.Count) and exists i > arguments.Count() signature.FormalParams[i].InitValue != null }
private void initTaintedVariable(FlowOutputSet outSet, String name) { outSet.Snapshot.SetMode(SnapshotMode.InfoLevel); var TaintedVar = outSet.GetVariable(new VariableIdentifier(name), true); var taint = new TaintInfo(); taint.taint = new Taint(true); taint.priority = new TaintPriority(true); taint.tainted = true; var Taint = outSet.CreateInfo(taint); //TaintedVar.WriteMemory(outSet.Snapshot, new MemoryEntry(Taint)); var entry = TaintedVar.ReadIndex(EntryInput.Snapshot, MemberIdentifier.getAnyMemberIdentifier()); entry.WriteMemory(EntryInput.Snapshot, new MemoryEntry(Taint)); /* * TaintedVar = outSet.GetVariable(new VariableIdentifier(name), true); * Taint = outSet.CreateInfo(taint); * * TaintedVar.WriteMemory(outSet.Snapshot, new MemoryEntry(Taint));*/ }
/// <summary> /// Visits a jump statement point /// </summary> /// <param name="p">point to visit</param> public override void VisitJump(JumpStmtPoint p) { _currentPoint = p; switch (p.Jump.Type) { case JumpStmt.Types.Return: var returnVar = Output.GetLocalControlVariable(SnapshotBase.ReturnValue); /*var returnValue = p.Expression.Value.ReadMemory(Input); * returnVar.WriteMemory(Output, returnValue);*/ if (p.Expression != null) { var varID = getVariableIdentifier(p.Expression.Value); List <Value> possibleValues = new List <Value>(p.Expression.Value.ReadMemory(p.Expression.OutSnapshot).PossibleValues); List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(possibleValues, varID)); bool nullValue = hasPossibleNullValue(p.Expression) || hasPossibleNullValue(p.Expression); TaintInfo outputTaint = mergeTaint(values, nullValue); returnVar.WriteMemory(Output, new MemoryEntry(Output.CreateInfo(outputTaint))); } break; default: throw new NotImplementedException(); } }
/// <summary> /// Visits a native analyzer program point. If function is a sanitizer, the output is sanitized, /// if it is a reporting function, a warning is created. /// </summary> /// <param name="p">program point to visit</param> public override void VisitNativeAnalyzer(NativeAnalyzerPoint p) { _currentPoint = p; string functionName = p.OwningPPGraph.FunctionName; // 1. Get values of arguments of the function // TODO: code duplication: the following code, code in SimpleFunctionResolver, and NativeFunctionAnalyzer. Move the code to some API (? FlowInputSet) Input.SetMode(SnapshotMode.MemoryLevel); MemoryEntry argc = InputSet.ReadVariable(new VariableIdentifier(".argument_count")).ReadMemory(Input); Input.SetMode(SnapshotMode.InfoLevel); int argumentCount = ((IntegerValue)argc.PossibleValues.ElementAt(0)).Value; List <MemoryEntry> arguments = new List <MemoryEntry>(); List <ValueInfo> values = new List <ValueInfo>(); bool nullValue = false; for (int i = 0; i < argumentCount; i++) { arguments.Add(OutputSet.ReadVariable(Argument(i)).ReadMemory(OutputSet.Snapshot)); List <Value> argumentValues = new List <Value>(arguments.Last().PossibleValues); if (hasPossibleNullValue(OutputSet.ReadVariable(Argument(i)))) { nullValue = true; } VariableIdentifier varID = null; Value toRemove = null; foreach (Value val in argumentValues) { if (val is InfoValue <VariableIdentifier> ) { varID = (val as InfoValue <VariableIdentifier>).Data; toRemove = val; } } if (toRemove != null) { argumentValues.Remove(toRemove); } values.Add(new ValueInfo(argumentValues, varID)); } TaintInfo outputTaint = mergeTaint(values, nullValue); // try to sanitize the taint info if (outputTaint != null) { sanitize(p, ref outputTaint); warningsReportingFunct(p, outputTaint); } // 2. Propagate arguments to the return value. // TODO: quick fix if (outputTaint.tainted || outputTaint.nullValue) { FunctionResolverBase.SetReturn(OutputSet, new MemoryEntry(Output.CreateInfo(outputTaint))); } }
/// <summary> /// Visits a ConditionalExPoint point and propagates the taint /// </summary> /// <param name="p">point to visit</param> public override void VisitValue(ValuePoint p) { _currentPoint = p; if (p is ConditionalExPoint) { var pEx = p as ConditionalExPoint; var possibleValues = pEx.Condition.Value.ReadMemory(Output).PossibleValues; if (pEx.TrueAssume.Assumed && pEx.FalseAssume.Assumed) { var truevarID = getVariableIdentifier(pEx.TrueOperand.Value); var falsevarID = getVariableIdentifier(pEx.FalseOperand.Value); List <Value> trueValues = new List <Value>(pEx.TrueOperand.Value.ReadMemory(pEx.TrueOperand.OutSnapshot).PossibleValues); List <Value> falseValues = new List <Value>(pEx.FalseOperand.Value.ReadMemory(pEx.FalseOperand.OutSnapshot).PossibleValues); //merge taint info from both branches List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(trueValues, truevarID)); values.Add(new ValueInfo(falseValues, falsevarID)); bool nullValue = hasPossibleNullValue(pEx.TrueOperand) || hasPossibleNullValue(pEx.FalseOperand); TaintInfo outputTaint = mergeTaint(values, nullValue); pEx.SetValueContent(new MemoryEntry(Output.CreateInfo(outputTaint))); } else if (pEx.TrueAssume.Assumed) { var truevarID = getVariableIdentifier(pEx.TrueOperand.Value); List <Value> trueValues = new List <Value>(pEx.TrueOperand.Value.ReadMemory(Output).PossibleValues); //only true value is used List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(trueValues, truevarID)); bool nullValue = hasPossibleNullValue(pEx.TrueOperand); TaintInfo outputTaint = mergeTaint(values, nullValue); pEx.SetValueContent(new MemoryEntry(Output.CreateInfo(outputTaint))); } else { var falsevarID = getVariableIdentifier(pEx.FalseOperand.Value); List <Value> falseValues = new List <Value>(pEx.FalseOperand.Value.ReadMemory(Output).PossibleValues); //only false value is used List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(falseValues, falsevarID)); bool nullValue = hasPossibleNullValue(pEx.FalseOperand); TaintInfo outputTaint = mergeTaint(values, nullValue); pEx.SetValueContent(new MemoryEntry(Output.CreateInfo(outputTaint))); } } }
/// <summary> /// If function is a reporting function, a warning might be created. /// </summary> /// <param name="p">program point with a function</param> /// <param name="taintInfo">TaintInfo that is being sanitized</param> private void warningsReportingFunct(NativeAnalyzerPoint p, TaintInfo taintInfo) { NativeAnalyzerMethod method = p.Analyzer.Method; QualifiedName functName = getMethodName(p); functAnalyzer = NativeFunctionAnalyzer.CreateInstance(); List <FlagType> flags; if (functAnalyzer.ReportingFunctions.TryGetValue(functName, out flags)) { createWarnings(p, taintInfo, flags); } }
/// <summary> /// If the function is a sanitizer, the sanitized taint flows are removed /// </summary> /// <param name="p">program point with a function</param> /// <param name="taintInfo">TaintInfo that is being sanitized</param> private void sanitize(NativeAnalyzerPoint p, ref TaintInfo taintInfo) { NativeAnalyzerMethod method = p.Analyzer.Method; QualifiedName functName = getMethodName(p); functAnalyzer = NativeFunctionAnalyzer.CreateInstance(); List <FlagType> flags; if (functAnalyzer.SanitizingFunctions.TryGetValue(functName, out flags)) { taintInfo.setSanitized(flags); } }
/// <summary> /// Visits a concatenation expression point and propagates the taint from all operands. /// </summary> /// <param name="p">point to visit</param> public override void VisitConcat(ConcatExPoint p) { _currentPoint = p; List <ValueInfo> values = new List <ValueInfo>(); bool nullValue = false; foreach (var operand in p.Parts) { nullValue = addOperandValues(values, operand, nullValue); } TaintInfo outputTaint = mergeTaint(values, nullValue); p.SetValueContent(new MemoryEntry(Output.CreateInfo(outputTaint))); }
private void createWarnings(ProgramPointBase p, TaintInfo taintInfo, List <FlagType> flags, String message = null) { if (taintInfo.nullValue) { String taint = taintInfo.printNullFlows(); String nullMessage = message; if (message == "Eval shoudn't contain anything from user input") { nullMessage = "Eval shoudn't contain null"; } if (flags == null) { createWarning(p, FlagType.HTMLDirty, nullMessage, taint, true, false); } else { foreach (FlagType flag in flags) { createWarning(p, flag, nullMessage, taint, true, false); } } } if (flags == null) { if (!taintInfo.tainted) { return; } String taint = taintInfo.print(); Boolean priority = !taintInfo.priority.allFalse(); createWarning(p, FlagType.HTMLDirty, message, taint, false, priority); } else { foreach (FlagType flag in flags) { if (!(taintInfo.taint.get(flag))) { continue; } String taint = taintInfo.print(flag); createWarning(p, flag, message, taint, false, taintInfo.priority.get(flag)); } } }
/// <summary> /// Visits including point /// </summary> /// <param name="p">program point to visit</param> public override void VisitInclude(IncludingExPoint p) { _currentPoint = p; var varID = getVariableIdentifier(p.Value); List <Value> argumentValues = new List <Value>(p.IncludePath.Value.ReadMemory(Output).PossibleValues); List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(argumentValues, varID)); bool nullValue = hasPossibleNullValue(p.IncludePath); TaintInfo outputTaint = mergeTaint(values, nullValue); createWarnings(p, outputTaint, new List <FlagType>() { FlagType.FilePathDirty }); }
/// <summary> /// Visits a binary expression point and propagates the taint from both the operands. /// </summary> /// <param name="p">point to visit</param> public override void VisitBinary(BinaryExPoint p) { _currentPoint = p; List <ValueInfo> values = new List <ValueInfo>(); bool nullValue = false; nullValue = addOperandValues(values, p.LeftOperand, nullValue); nullValue = addOperandValues(values, p.RightOperand, nullValue); TaintInfo outputTaint = mergeTaint(values, nullValue); outputTaint.setSanitized(new List <FlagType>() { FlagType.FilePathDirty, FlagType.HTMLDirty, FlagType.SQLDirty }); p.SetValueContent(new MemoryEntry(Output.CreateInfo(outputTaint))); }
/// <summary> /// Visits unary expression point - if operation is print, warning might be created /// </summary> /// <param name="p"></param> public override void VisitUnary(UnaryExPoint p) { _currentPoint = p; if (p.Expression.PublicOperation == Operations.Print) { var varID = getVariableIdentifier(p.Operand.Value); List <Value> argumentValues = new List <Value>(p.Operand.Value.ReadMemory(Output).PossibleValues); List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(argumentValues, varID)); bool nullValue = hasPossibleNullValue(p.Operand); TaintInfo outputTaint = mergeTaint(values, nullValue); createWarnings(p, outputTaint, new List <FlagType>() { FlagType.HTMLDirty }); } }
/// <summary> /// Visits eval point /// </summary> /// <param name="p">program point to visit</param> public override void VisitRCall(RCallPoint p) { _currentPoint = p; OutputSet.Snapshot.SetMode(SnapshotMode.InfoLevel); if (p is EvalExPoint) { EvalExPoint pEval = p as EvalExPoint; var varID = getVariableIdentifier(pEval.EvalCode.Value); List <Value> argumentValues = new List <Value>(pEval.EvalCode.Value.ReadMemory(Output).PossibleValues); List <ValueInfo> values = new List <ValueInfo>(); values.Add(new ValueInfo(argumentValues, varID)); bool nullValue = hasPossibleNullValue(pEval.EvalCode); TaintInfo outputTaint = mergeTaint(values, nullValue); createWarnings(p, outputTaint, null, "Eval shoudn't contain anything from user input"); } /* if (p is FunctionCallPoint) * { * FunctionCallPoint pCall = p as FunctionCallPoint; * * List<ValueInfo> values = new List<ValueInfo>(); * * List<ValuePoint> args = new List<ValuePoint>(pCall.Arguments); * bool nullValue = false; * * foreach (ValuePoint arg in args) * { * var varID = getVariableIdentifier(arg.Value); * List<Value> argumentValues = new List<Value>(arg.Value.ReadMemory(Output).PossibleValues); * values.Add(new ValueInfo(argumentValues, varID)); * nullValue |= hasPossibleNullValue(arg.Value); * } * * TaintInfo outputTaint = mergeTaint(values, nullValue); * * if (outputTaint.tainted || outputTaint.nullValue) * FunctionResolverBase.SetReturn(OutputSet, new MemoryEntry(Output.CreateInfo(outputTaint))); * }*/ }
/// <summary> /// Visits echo statement /// </summary> /// <param name="p">program point to visit</param> public override void VisitEcho(EchoStmtPoint p) { _currentPoint = p; var count = p.Echo.Parameters.Count; List <ValuePoint> valpoints = new List <ValuePoint>(p.Parameters); List <ValueInfo> values = new List <ValueInfo>(); bool nullValue = false; foreach (ValuePoint val in valpoints) { var varID = getVariableIdentifier(val.Value); List <Value> argumentValues = new List <Value>(val.Value.ReadMemory(Output).PossibleValues); values.Add(new ValueInfo(argumentValues, varID)); nullValue |= hasPossibleNullValue(val); } TaintInfo outputTaint = mergeTaint(values, nullValue); createWarnings(p, outputTaint, new List <FlagType>() { FlagType.HTMLDirty }); }
public TaintFlow(TaintInfo info, VariableIdentifier varID) { flow = info; var = varID; }
/// <summary> /// Sets the taint information to the given entry /// </summary> /// <param name="variable">entry to set the taint to</param> /// <param name="taint">taint to be set</param> private void setTaint(ReadWriteSnapshotEntryBase variable, TaintInfo taint) { var infoValue = Output.CreateInfo(taint); variable.WriteMemory(Output, new MemoryEntry(infoValue)); }
/// <summary> /// Merges multiple taint information into one. /// </summary> /// <param name="values">info values with taint information</param> /// <param name="nullValue">indicator of null flow</param> /// <returns>merged taint information</returns> private TaintInfo mergeTaint(List <ValueInfo> values, bool nullValue) { TaintInfo info = new TaintInfo(); info.point = _currentPoint; TaintPriority priority = new TaintPriority(true); List <TaintInfo> processedTaintInfos = new List <TaintInfo>(); //if _currentPoint is a ConcatExPoint, its priority is high whenever one of the values has high priority if (_currentPoint is ConcatExPoint) { priority.setAll(false); } Taint taint = new Taint(false); bool existsNullFlow = false; bool existsFlow = false; bool tainted = false; foreach (var pair in values) { existsFlow |= (pair.values.Count > 0); foreach (var infoValue in pair.values) { if (infoValue is UndefinedValue) { continue; } if (!(infoValue is InfoValue <TaintInfo>)) { continue; } TaintInfo varInfo = (((InfoValue <TaintInfo>)infoValue).Data); if (processedTaintInfos.Contains(varInfo)) { continue; } processedTaintInfos.Add(varInfo); existsNullFlow |= varInfo.nullValue; tainted |= varInfo.tainted; /* If _currentPoint is not ConcatExPoint, the priority is low whenever one of the values * has a low priority. * If _currentPoint is ConcatExPoint, the priority is high whenever one of the values has * a high priority */ if (!(_currentPoint is ConcatExPoint)) { priority.copyTaint(false, varInfo.priority); } if (_currentPoint is ConcatExPoint) { priority.copyTaint(true, varInfo.priority); } taint.copyTaint(true, varInfo.taint); info.possibleTaintFlows.Add(new TaintFlow(varInfo, pair.variable)); } } info.nullValue = existsNullFlow; info.tainted = tainted; if (!existsFlow) { priority.setAll(false); } if (nullValue && !existsNullFlow) { if (!existsFlow) { priority.setAll(true); } info.nullValue = true; info.tainted = true; } info.priority = priority; info.taint = taint; return(info); }