1414 * limitations under the License.
1515 */
1616
17+ @file:JvmName(" AnalysisMain" )
1718package org.jacodb.analysis
19+
1820import kotlinx.serialization.Serializable
1921import mu.KLogging
20- import org.jacodb.analysis.analyzers.AliasAnalyzerFactory
21- import org.jacodb.analysis.analyzers.NpeAnalyzerFactory
22- import org.jacodb.analysis.analyzers.NpePrecalcBackwardAnalyzerFactory
23- import org.jacodb.analysis.analyzers.SqlInjectionAnalyzerFactory
24- import org.jacodb.analysis.analyzers.SqlInjectionBackwardAnalyzerFactory
25- import org.jacodb.analysis.analyzers.TaintAnalysisNode
26- import org.jacodb.analysis.analyzers.TaintAnalyzerFactory
27- import org.jacodb.analysis.analyzers.TaintBackwardAnalyzerFactory
28- import org.jacodb.analysis.analyzers.TaintNode
29- import org.jacodb.analysis.analyzers.UnusedVariableAnalyzerFactory
30- import org.jacodb.analysis.engine.IfdsBaseUnitRunner
31- import org.jacodb.analysis.engine.SequentialBidiIfdsUnitRunner
32- import org.jacodb.analysis.engine.TraceGraph
22+ import org.jacodb.analysis.engine.IfdsUnitManager
23+ import org.jacodb.analysis.engine.IfdsUnitRunner
24+ import org.jacodb.analysis.engine.Summary
25+ import org.jacodb.analysis.engine.UnitResolver
26+ import org.jacodb.analysis.engine.VulnerabilityInstance
27+ import org.jacodb.analysis.graph.newApplicationGraphForAnalysis
3328import org.jacodb.api.JcMethod
34- import org.jacodb.api.cfg.JcExpr
35- import org.jacodb.api.cfg.JcInst
36-
37- @Serializable
38- data class DumpableVulnerabilityInstance (
39- val vulnerabilityType : String ,
40- val sources : List <String >,
41- val sink : String ,
42- val traces : List <List <String >>
43- )
44-
45- @Serializable
46- data class DumpableAnalysisResult (val foundVulnerabilities : List <DumpableVulnerabilityInstance >)
47-
48- data class VulnerabilityInstance (
49- val vulnerabilityType : String ,
50- val traceGraph : TraceGraph
51- ) {
52- private fun JcInst.prettyPrint (): String {
53- return " ${toString()} (${location.method} :${location.lineNumber} )"
54- }
55-
56- fun toDumpable (maxPathsCount : Int ): DumpableVulnerabilityInstance {
57- return DumpableVulnerabilityInstance (
58- vulnerabilityType,
59- traceGraph.sources.map { it.statement.prettyPrint() },
60- traceGraph.sink.statement.prettyPrint(),
61- traceGraph.getAllTraces().take(maxPathsCount).map { intermediatePoints ->
62- intermediatePoints.map { it.statement.prettyPrint() }
63- }.toList()
64- )
65- }
66- }
29+ import org.jacodb.api.analysis.JcApplicationGraph
6730
68- fun List<VulnerabilityInstance>.toDumpable (maxPathsCount : Int = 3): DumpableAnalysisResult {
69- return DumpableAnalysisResult (map { it.toDumpable(maxPathsCount) })
70- }
31+ internal val logger = object : KLogging () {}.logger
7132
7233typealias AnalysesOptions = Map <String , String >
7334
7435@Serializable
7536data class AnalysisConfig (val analyses : Map <String , AnalysesOptions >)
7637
77- val UnusedVariableRunner = IfdsBaseUnitRunner (UnusedVariableAnalyzerFactory )
7838
79- fun newSqlInjectionRunner (maxPathLength : Int = 5) = SequentialBidiIfdsUnitRunner (
80- IfdsBaseUnitRunner (SqlInjectionAnalyzerFactory (maxPathLength)),
81- IfdsBaseUnitRunner (SqlInjectionBackwardAnalyzerFactory (maxPathLength)),
82- )
83-
84- fun newNpeRunner (maxPathLength : Int = 5) = SequentialBidiIfdsUnitRunner (
85- IfdsBaseUnitRunner (NpeAnalyzerFactory (maxPathLength)),
86- IfdsBaseUnitRunner (NpePrecalcBackwardAnalyzerFactory (maxPathLength)),
87- )
88-
89- fun newAliasRunner (
90- generates : (JcInst ) -> List <TaintAnalysisNode >,
91- sanitizes : (JcExpr , TaintNode ) -> Boolean ,
92- sinks : (JcInst ) -> List <TaintAnalysisNode >,
93- maxPathLength : Int = 5
94- ) = IfdsBaseUnitRunner (AliasAnalyzerFactory (generates, sanitizes, sinks, maxPathLength))
95-
96- fun newTaintRunner (
97- isSourceMethod : (JcMethod ) -> Boolean ,
98- isSanitizeMethod : (JcMethod ) -> Boolean ,
99- isSinkMethod : (JcMethod ) -> Boolean ,
100- maxPathLength : Int = 5
101- ) = SequentialBidiIfdsUnitRunner (
102- IfdsBaseUnitRunner (TaintAnalyzerFactory (isSourceMethod, isSanitizeMethod, isSinkMethod, maxPathLength)),
103- IfdsBaseUnitRunner (TaintBackwardAnalyzerFactory (isSourceMethod, isSinkMethod, maxPathLength))
104- )
105-
106- fun newTaintRunner (
107- sourceMethodMatchers : List <String >,
108- sanitizeMethodMatchers : List <String >,
109- sinkMethodMatchers : List <String >,
110- maxPathLength : Int = 5
111- ) = SequentialBidiIfdsUnitRunner (
112- IfdsBaseUnitRunner (TaintAnalyzerFactory (sourceMethodMatchers, sanitizeMethodMatchers, sinkMethodMatchers, maxPathLength)),
113- IfdsBaseUnitRunner (TaintBackwardAnalyzerFactory (sourceMethodMatchers, sinkMethodMatchers, maxPathLength))
114- )
115-
116- internal val logger = object : KLogging () {}.logger
39+ /* *
40+ * This is the entry point for every analysis.
41+ * Calling this function will find all vulnerabilities reachable from [methods].
42+ *
43+ * @param graph instance of [JcApplicationGraph] that provides mixture of CFG and call graph
44+ * (called supergraph in RHS95).
45+ * Usually built by [newApplicationGraphForAnalysis].
46+ *
47+ * @param unitResolver instance of [UnitResolver] which splits all methods into groups of methods, called units.
48+ * Units are analyzed concurrently, one unit will be analyzed with one call to [IfdsUnitRunner.run] method.
49+ * In general, larger units mean more precise, but also more resource-consuming analysis, so [unitResolver] allows
50+ * to reach compromise.
51+ * It is guaranteed that [Summary] passed to all units is the same, so they can share information through it.
52+ * However, the order of launching and terminating analysis for units is an implementation detail and may vary even for
53+ * consecutive calls of this method with same arguments.
54+ *
55+ * @param ifdsUnitRunner an [IfdsUnitRunner] instance that will be launched for each unit.
56+ * This is the main argument that defines the analysis.
57+ *
58+ * @param methods the list of method for analysis.
59+ * Each vulnerability will only be reported if it is reachable from one of these.
60+ *
61+ * @param timeoutMillis the maximum time for analysis.
62+ * Note that this does not include time for precalculations
63+ * (like searching for reachable methods and splitting them into units) and postcalculations (like restoring traces), so
64+ * the actual running time of this method may be longer.
65+ */
66+ fun runAnalysis (
67+ graph : JcApplicationGraph ,
68+ unitResolver : UnitResolver <* >,
69+ ifdsUnitRunner : IfdsUnitRunner ,
70+ methods : List <JcMethod >,
71+ timeoutMillis : Long = Long .MAX_VALUE
72+ ): List <VulnerabilityInstance > {
73+ return IfdsUnitManager (graph, unitResolver, ifdsUnitRunner, methods, timeoutMillis).analyze()
74+ }
0 commit comments