Skip to content

Commit 39c3dfa

Browse files
authored
Bring over scan from query-database (#1071)
1 parent 39a60b9 commit 39c3dfa

2 files changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.shiftleft.console.scan
2+
3+
import io.shiftleft.codepropertygraph.Cpg
4+
import io.shiftleft.console.Query
5+
import io.shiftleft.passes.{DiffGraph, KeyPoolCreator, ParallelCpgPass}
6+
7+
class ScanPass(cpg: Cpg, queries: List[Query])
8+
extends ParallelCpgPass[Query](cpg,
9+
keyPools = Some(KeyPoolCreator.obtain(queries.size.toLong, 42949672950L).iterator)) {
10+
11+
override def partIterator: Iterator[Query] = queries.iterator
12+
13+
override def runOnPart(query: Query): Iterator[DiffGraph] = {
14+
val diffGraph = DiffGraph.newBuilder
15+
query(cpg).foreach(diffGraph.addNode)
16+
Iterator(diffGraph.build)
17+
}
18+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package io.shiftleft.console
2+
3+
import io.shiftleft.codepropertygraph.Cpg
4+
import io.shiftleft.codepropertygraph.generated.{NodeTypes, nodes}
5+
import overflowdb.traversal._
6+
import io.shiftleft.semanticcpg.language._
7+
8+
package object scan {
9+
10+
implicit class ScannerStarters(val cpg: Cpg) extends AnyVal {
11+
def finding: Traversal[nodes.Finding] =
12+
cpg.graph.nodes(NodeTypes.FINDING).cast[nodes.Finding]
13+
}
14+
15+
implicit class QueryWrapper(q: Query) {
16+
17+
/**
18+
* Obtain list of findings by running query on CPG
19+
* */
20+
def apply(cpg: Cpg): List[nodes.NewFinding] = {
21+
q.f(cpg)
22+
.map(
23+
evidence =>
24+
finding(evidence = evidence,
25+
name = q.name,
26+
author = q.author,
27+
title = q.title,
28+
description = q.description,
29+
score = q.score))
30+
.l
31+
}
32+
}
33+
34+
private object FindingKeys {
35+
val name = "name"
36+
val author = "author"
37+
val title = "title"
38+
val description = "description"
39+
val score = "score"
40+
}
41+
42+
implicit class ScannerFindingStep(val traversal: Traversal[nodes.Finding]) extends AnyRef {
43+
44+
def name: Traversal[String] = traversal.map(_.name)
45+
46+
def author: Traversal[String] = traversal.map(_.author)
47+
48+
def title: Traversal[String] = traversal.map(_.title)
49+
50+
def description: Traversal[String] = traversal.map(_.description)
51+
52+
def score: Traversal[Double] = traversal.map(_.score)
53+
54+
}
55+
56+
implicit class ScannerFindingExtension(val node: nodes.Finding) extends AnyRef {
57+
58+
def name: String = getValue(FindingKeys.name)
59+
60+
def author: String = getValue(FindingKeys.author)
61+
62+
def title: String = getValue(FindingKeys.title)
63+
64+
def description: String = getValue(FindingKeys.description)
65+
66+
def score: Double = getValue(FindingKeys.score).toDouble
67+
68+
protected def getValue(key: String, default: String = ""): String =
69+
node.keyValuePairs.find(_.key == key).map(_.value).getOrElse(default)
70+
71+
}
72+
73+
private def finding(evidence: nodes.StoredNode,
74+
name: String,
75+
author: String,
76+
title: String,
77+
description: String,
78+
score: Double): nodes.NewFinding = {
79+
nodes.NewFinding(
80+
evidence = List(evidence),
81+
keyValuePairs = List(
82+
nodes.NewKeyValuePair(FindingKeys.name, name),
83+
nodes.NewKeyValuePair(FindingKeys.author, author),
84+
nodes.NewKeyValuePair(FindingKeys.title, title),
85+
nodes.NewKeyValuePair(FindingKeys.description, description),
86+
nodes.NewKeyValuePair(FindingKeys.score, score.toString)
87+
)
88+
)
89+
}
90+
91+
/**
92+
* Print human readable list of findings to standard out.
93+
* */
94+
def outputFindings(cpg: Cpg): Unit = {
95+
cpg.finding.sortBy(_.score.toInt).foreach { finding =>
96+
val evidence = finding.evidence.headOption
97+
.map { e =>
98+
s"${e.location.filename}:${e.location.lineNumber.getOrElse(0)}:${e.location.methodFullName}"
99+
}
100+
.getOrElse("")
101+
println(s"Result: ${finding.score} : ${finding.title}: $evidence")
102+
}
103+
}
104+
105+
}

0 commit comments

Comments
 (0)