public static void AssertOutEdges(this BidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph, CFGBlock block, int expectedOutEdges, string message = "") { IEnumerable<TaggedEdge<CFGBlock, EdgeTag>> edges; graph.TryGetOutEdges(block, out edges); Assert.AreEqual(expectedOutEdges, edges.Count(), message); }
public bool IsSink(CFGBlock target) { Preconditions.NotNull(target, "target"); if (target.AstEntryNode == null) { return false; } return this.sinks.Contains(target.AstEntryNode.LocalName); }
public void Initialize(CFGBlock cfgBlock) { var taintInfo = CFGTaintInfo.Default; if (cfgBlock.IsRoot) { var varStorage = ImmutableDictionary<EdgeType, ImmutableVariableStorage>.Empty.Add(EdgeType.Normal, initialTaint); taintInfo = new CFGTaintInfo(initialTaint, varStorage); } _taints.Add(cfgBlock, taintInfo); }
private void AnalyzeEcho(CFGBlock block, CFGTaintInfo taintInfo) { //var xssTaintedVars = taintInfo.In.Where(info => info.Value.XssTaint.TaintTags.Contains(XSSTaint.XSS_ALL)) // .Select(info => info.Key); //foreach (var taintedVar in xssTaintedVars) //{ // if (block.AstEntryNode.InnerText.Contains(taintedVar)) // { // vulnerabilityReporter.ReportVulnerability(block, "XSS"); // } //} }
public bool Analyze2(CFGBlock block, IBidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph) { var oldTaint = Taints[block]; var newTaint = AnalyzeNode2(block, graph); if (MonotonicChange(oldTaint, newTaint)) { _taints[block] = newTaint; return true; } return false; }
public void AnalyzeSink(CFGBlock target, CFGTaintInfo taintInfo) { switch (target.AstEntryNode.LocalName) { case AstConstants.Nodes.Stmt_Echo: AnalyzeEcho(target, taintInfo); break; case AstConstants.Nodes.Expr_Print: break; default: break; } }
private void BFS(CFGBlock root, BidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> _graph) { Console.WriteLine("Total BFS recursions: " + BFSRUNS + " Active BFS: " + activebfs + " nodes currently in graph: " + nodeList.Count); BFSRUNS++; activebfs++; Queue<CFGBlock> queue = new Queue<CFGBlock> (); queue.Enqueue (root); while (queue.Any ()) { var node = queue.Dequeue (); if (visited.Contains(node)) continue; visited.Add (node); var cNode = MakeCNode (node); if (cNode != null) cNode.graph = _graph; if (node.AstEntryNode != null && node.AstEntryNode.LocalName == AstConstants.Nodes.Expr_Include) { File output = null; resolver.TryResolveInclude (node.AstEntryNode, out output); if (output != null && !inFile.Contains(output)) { var _root = output.CFG.Roots ().Single (v => v.IsSpecialBlock); inFile.Add(output); //Console.WriteLine("Recursive call: " + output.Name); BFS (_root, (BidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>>)output.CFG); //Console.WriteLine("Finished call: " + output.Name); //Console.WriteLine("Still " + inFile.Count() + " files left"); inFile.Remove(output); } } foreach (var edge in _graph.OutEdges(node)) if (!visited.Contains (edge.Target)) //No loops, please queue.Enqueue (edge.Target); } activebfs--; }
private void ForStatementEnter(XmlNode node) { CFGBlock forLoopInit = new CFGBlock(); if (!CurrentBlock.BreaksOutOfScope) { forLoopInit = ConnectNewBlockTo(CurrentBlock, EdgeType.Normal); } forLoopInit.AstEntryNode = ForLoop.GetInitNode(node); DoNotVisitChildren(forLoopInit.AstEntryNode); CFGBlock conditionBlock = ConnectNewBlockTo(forLoopInit, EdgeType.Normal); conditionBlock.AstEntryNode = node; DoNotVisitChildren(Conditional.GetCondNode(node)); CFGBlock loopUpdateBlock = new CFGBlock { AstEntryNode = ForLoop.GetLoopNode(node) }; DoNotVisitChildren(loopUpdateBlock.AstEntryNode); var edge = new TaggedEdge<CFGBlock, EdgeTag>(loopUpdateBlock, conditionBlock, new EdgeTag(EdgeType.Normal)); Graph.AddVerticesAndEdge(edge); CFGBlock loopBodyBlock = ConnectNewBlockTo(conditionBlock, EdgeType.True); CFGBlock loopDoneBlock = ConnectNewBlockTo(conditionBlock, EdgeType.False); var loopScope = new LoopScope(forLoopInit) { LoopConditionBlock = loopUpdateBlock, LoopBodyStartBlock = loopBodyBlock, LoopUpdateBlock = loopUpdateBlock, ContinueDestination = loopUpdateBlock, EndBlock = loopDoneBlock }; scopeHandler.EnterLoop(loopScope); CurrentBlock = loopBodyBlock; }
private void WhileOrForeachStatementEnter(XmlNode node) { CFGBlock conditionBlock = new CFGBlock(); if (!CurrentBlock.BreaksOutOfScope) { conditionBlock = ConnectNewBlockTo(CurrentBlock, EdgeType.Normal); } CFGBlock loopBodyBlock; CFGBlock loopExitBlock; if (node.LocalName == AstConstants.Nodes.Stmt_Foreach) { loopBodyBlock = ConnectNewBlockTo(conditionBlock, EdgeType.Normal); loopExitBlock = ConnectNewBlockTo(conditionBlock, EdgeType.Normal); } else { loopBodyBlock = ConnectNewBlockTo(conditionBlock, EdgeType.True); loopExitBlock = ConnectNewBlockTo(conditionBlock, EdgeType.False); } conditionBlock.AstEntryNode = node; var whileLoopScope = new LoopScope(conditionBlock) { LoopConditionBlock = conditionBlock, LoopBodyStartBlock = loopBodyBlock, ContinueDestination = conditionBlock, EndBlock = loopExitBlock }; scopeHandler.EnterLoop(whileLoopScope); if (node.LocalName == AstConstants.Nodes.Stmt_Foreach) { DoNotVisitChildren(node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Expr)); DoNotVisitChildren(node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.KeyVar)); DoNotVisitChildren(node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.ValueVar)); } else { DoNotVisitChildren(Conditional.GetCondNode(node)); } CurrentBlock = loopBodyBlock; }
public void TraverseStart(object sender, XmlStartTraverseEventArgs e) { Graph = new BidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>>(); var root = new CFGBlock(isSpecial: true) { IsRoot = true }; _exitBlock = new CFGBlock(isSpecial: true) { IsLeaf = true }; Graph.AddVertex(root); Graph.AddVertex(_exitBlock); CurrentBlock = root; }
public IEnumerable<TaggedEdge<CFGBlock, EdgeTag>> NextEdges(IBidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph, CFGBlock block) { return graph.InEdges(block); }
//HashSet<CFGBlock> CnodesVisited = new HashSet<CFGBlock>(); private CTLLTLNode MakeCNode(CFGBlock block) { var v = Stopwatch.StartNew(); if (nodeList.Exists (x => x.block == block)) return null; v.Stop(); var cNode = new CTLLTLNode (); cNode.block = block; GetBlockName (cNode); cNode.nodeName = nodeList.Count + 1 + ""; nodeList.Add (cNode); //CnodesVisited.Add(cNode.block); if (cNode.block.AstEntryNode != null && (nodeList.Count % 1000) == 0) Console.WriteLine("Added node: " + cNode.block.AstEntryNode.LocalName + " total in list: " + nodeList.Count + " Loop took: " + v.Elapsed); return cNode; }
private CFGTaintInfo AnalyzeNode2(CFGBlock block, IBidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph) { var oldTaint = Taints[block]; var predecessorsOut = graph.InEdges(block); var outTaints = predecessorsOut.Select(p => new { EdgeType = p.Tag, Source = p.Source }) .Where(s => Taints[s.Source].Out != null && Taints[s.Source].Out.Any()) .Select(s => Taints[s.Source].Out[s.EdgeType.EdgeType]) .Where(o => o != null); ImmutableVariableStorage newInTaint; if (outTaints.Any()) { newInTaint = oldTaint.In.Merge(outTaints.Aggregate((current, next) => current.Merge(next))); } else { newInTaint = oldTaint.In; } ImmutableDictionary<EdgeType, ImmutableVariableStorage> newOutTaint; if (block.AstEntryNode == null) { newOutTaint = ImmutableDictionary<EdgeType, ImmutableVariableStorage>.Empty.Add(EdgeType.Normal, newInTaint); } else { var newOut = _blockAnalyzer.Analyze(block.AstEntryNode, newInTaint); var newOutWithCondSani = _conditionTaintAnalyser.AnalyzeCond(block.AstEntryNode, newOut); newOutTaint = newOutWithCondSani.ToImmutableDictionary(); } return new CFGTaintInfo(newInTaint, newOutTaint); }
private Edge<CFGBlock> ConnectBlocks(CFGBlock source, CFGBlock target, EdgeType edgeType) { var edge = new TaggedEdge<CFGBlock, EdgeTag>(source, target, new EdgeTag(edgeType)); Graph.AddEdge(edge); return edge; }
public LoopScope(CFGBlock entryBlock) { Preconditions.NotNull(entryBlock, "entryBlock"); this.EntryBlock = entryBlock; }
private void ElseStatementsEnter(XmlNode node) { var ifblock = (IfScope)scopeHandler.CurrentScope; if(ifblock.ElseifBlock == null) ifblock.TrueNode = CurrentBlock; var falseNode = new CFGBlock(); TaggedEdge<CFGBlock, EdgeTag> newEdge; if (ifblock.ElseifBlock == null) { newEdge = new TaggedEdge<CFGBlock, EdgeTag>(ifblock.IfConditionNode, falseNode, new EdgeTag(EdgeType.False)); } else { newEdge = new TaggedEdge<CFGBlock, EdgeTag>(ifblock.ElseifBlock, falseNode, new EdgeTag(EdgeType.False)); } Graph.AddVerticesAndEdge(newEdge); CurrentBlock = falseNode; }
private void ElseIfStatementsEnter(XmlNode node) { var conditionNode = new CFGBlock { AstEntryNode = node }; var trueNode = new CFGBlock(); var currentScope = scopeHandler.GetIfStmt(); TaggedEdge<CFGBlock, EdgeTag> toCurrentConditionNode; if (currentScope.ElseifBlock != null) toCurrentConditionNode = new TaggedEdge<CFGBlock, EdgeTag>(currentScope.ElseifBlock, conditionNode, new EdgeTag(EdgeType.False)); else toCurrentConditionNode = new TaggedEdge<CFGBlock, EdgeTag>(currentScope.EntryBlock, conditionNode, new EdgeTag(EdgeType.False)); var toTrueNodeEdge = new TaggedEdge<CFGBlock, EdgeTag>(conditionNode, trueNode, new EdgeTag(EdgeType.True)); Graph.AddVerticesAndEdge(toCurrentConditionNode); currentScope.ElseifBlock = conditionNode; Graph.AddVerticesAndEdge(toTrueNodeEdge); DoNotVisitChildren(Conditional.GetCondNode(node)); CurrentBlock = trueNode; }
private void DoStatementEnter(XmlNode node) { var loopEntryBlock = new CFGBlock(); if (!CurrentBlock.BreaksOutOfScope) { loopEntryBlock = ConnectNewBlockTo(CurrentBlock, EdgeType.Normal); } Graph.AddVertex(loopEntryBlock); CurrentBlock = loopEntryBlock; CFGBlock conditionBlock = new CFGBlock { AstEntryNode = node }; CFGBlock loopDoneBlock = ConnectNewBlockTo(conditionBlock, EdgeType.False); ConnectBlocks(conditionBlock, loopEntryBlock, EdgeType.True); var loopScope = new LoopScope(loopEntryBlock) { LoopBodyStartBlock = loopEntryBlock, LoopConditionBlock = conditionBlock, ContinueDestination = conditionBlock, EndBlock = loopDoneBlock, }; scopeHandler.EnterLoop(loopScope); DoNotVisitChildren(Conditional.GetCondNode(node)); }
private CFGBlock ConnectNewBlockTo(CFGBlock block, EdgeType edgeType) { var newBlock = new CFGBlock(); var edge = new TaggedEdge<CFGBlock, EdgeTag>(block, newBlock, new EdgeTag(edgeType)); Graph.AddVerticesAndEdge(edge); return newBlock; }
private void IfStatementEnter(XmlNode node) { if (CurrentBlock.BreaksOutOfScope) { CurrentBlock = new CFGBlock(); Graph.AddVertex(CurrentBlock); } CFGBlock conditionBlock = ConnectNewBlockTo(CurrentBlock, EdgeType.Normal); CurrentBlock = conditionBlock; CFGBlock trueBlock = ConnectNewBlockTo(CurrentBlock, EdgeType.True); CurrentBlock = trueBlock; conditionBlock.AstEntryNode = node; var ifScope = new IfScope(conditionBlock, trueBlock) { EndBlock = new CFGBlock() }; Graph.AddVertex(ifScope.EndBlock); DoNotVisitChildren(Conditional.GetCondNode(node)); scopeHandler.PushIfStmt(ifScope); }
private void NormalStatementEnter(XmlNode node) { if (CurrentBlock.BreaksOutOfScope) { CurrentBlock = new CFGBlock(); Graph.AddVertex(CurrentBlock); } else { CurrentBlock = ConnectNewBlockTo(CurrentBlock, EdgeType.Normal); } CurrentBlock.AstEntryNode = node; DoNotVisitChildren(node); }
private void SwitchCaseStatementEnter(XmlNode node) { var conditionNode = new CFGBlock(); var trueNode = new CFGBlock(); conditionNode.AstEntryNode = node; var currentScope = (SwitchScope)scopeHandler.GetInnermostLoop(); TaggedEdge<CFGBlock, EdgeTag> toCurrentConditionNode; if (CurrentBlock == currentScope.EntryBlock) { toCurrentConditionNode = new TaggedEdge<CFGBlock, EdgeTag>(CurrentBlock, conditionNode, new EdgeTag(EdgeType.Normal)); } else { if(currentScope.CurrentCondition != null) toCurrentConditionNode = new TaggedEdge<CFGBlock, EdgeTag>(currentScope.CurrentCondition, conditionNode, new EdgeTag(EdgeType.False)); else toCurrentConditionNode = new TaggedEdge<CFGBlock, EdgeTag>(currentScope.EntryBlock, conditionNode, new EdgeTag(EdgeType.Normal)); } var toTrueNodeEdge = new TaggedEdge<CFGBlock, EdgeTag>(conditionNode, trueNode, new EdgeTag(EdgeType.True)); if (Case.IsDefaultCase(node)) { currentScope.DefaultBlock = conditionNode; currentScope.DefaultTrueBlock = trueNode; } else { Graph.AddVerticesAndEdge(toCurrentConditionNode); currentScope.CurrentCondition = conditionNode; } Graph.AddVerticesAndEdge(toTrueNodeEdge); if (!CurrentBlock.BreaksOutOfScope && CurrentBlock != currentScope.EntryBlock) { var fallthrough = new TaggedEdge<CFGBlock, EdgeTag>(CurrentBlock, trueNode, new EdgeTag(EdgeType.Normal)); Graph.AddEdge(fallthrough); } CurrentBlock = trueNode; DoNotVisitChildren(Conditional.GetCondNode(node)); }
public SwitchScope(CFGBlock switchConditionNode, CFGBlock endNode) { EntryBlock = switchConditionNode; EndBlock = endNode; }
private void SwitchStatementEnter(XmlNode node) { if (CurrentBlock.BreaksOutOfScope) { CurrentBlock = new CFGBlock(); Graph.AddVertex(CurrentBlock); } var switchScope = new SwitchScope(new CFGBlock() { AstEntryNode = node }, new CFGBlock()); var edgeToSwitch = new TaggedEdge<CFGBlock, EdgeTag>(CurrentBlock, switchScope.SwitchStartNode, new EdgeTag(EdgeType.Normal)); Graph.AddVerticesAndEdge(edgeToSwitch); Graph.AddVertex(switchScope.EndBlock); CurrentBlock = switchScope.SwitchStartNode; scopeHandler.EnterLoop(switchScope); DoNotVisitChildren(Conditional.GetCondNode(node)); }
private void FunctionMethodEnter(XmlNode node) { var ext = new FunctionCallExtractor (); Function f = null; string methodName = ext.ExtractFunctionCall (node).Name; string functionName = null; if (node.LocalName == AstConstants.Nodes.Expr_FuncCall) f = FunctionsHandler.Instance.CustomFunctions.Find (x => x.Name == ext.ExtractFunctionCall (node).Name || x.Aliases.Any (y => y == ext.ExtractFunctionCall (node).Name)); else if (node.LocalName == AstConstants.Nodes.Expr_MethodCall) { var varNode = node.GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Var); string className = ""; //PHP: (new ClassName(args))->MethodName(args); //Extract the ClassName directly, in this case there can be only one ClassName! if (varNode.FirstChild.LocalName == AstConstants.Nodes.Expr_New) { className = varNode.FirstChild .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Class) .GetSubNode (AstConstants.Node + ":" + AstConstants.Nodes.Name) .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Parts).FirstChild.FirstChild.InnerText; } //Look up the function name in the list of variables else { try {classVarList.TryGetValue (varNode.FirstChild .GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).InnerText, out className);} catch {} } methodName = node.GetSubNode (AstConstants.Subnode + ":" + AstConstants.Subnodes.Name).FirstChild.InnerText; functionName = className + "->" + methodName; f = FunctionsHandler.Instance.CustomFunctions.Find (x => x.Name == functionName || x.Aliases.Any (y => y == functionName)); } if (CurrentBlock.BreaksOutOfScope) { CurrentBlock = new CFGBlock (); Graph.AddVertex (CurrentBlock); } else { CurrentBlock = ConnectNewBlockTo (CurrentBlock, EdgeType.Normal); } CurrentBlock.AstEntryNode = node; if (f==null) f = HandleWPFunctions(methodName, node, functionName); if (f != null && !inFunctions.Contains(f)) { inFunctions.Add(f); foreach (XmlNode n in f.AstNode.ChildNodes) { if (n.LocalName == "stmts") foreach (XmlNode s in n.FirstChild.ChildNodes) { DepthFirstImpl (s); } } inFunctions.Remove(f); } //else throw new NullReferenceException("The function did not exist"); //This should never happen }