mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Initial support for source models
This commit is contained in:
@@ -33,5 +33,5 @@ string captureSink(Callable api) {
|
||||
from Callable api, string sink
|
||||
where
|
||||
sink = captureSink(api) and
|
||||
not api.getCompilationUnit().getFile().getAbsolutePath().matches("%src/test/%")
|
||||
not isInTestFile(api)
|
||||
select sink order by sink
|
||||
|
||||
43
java/ql/src/utils/model-generator/CaptureSourceModels.ql
Normal file
43
java/ql/src/utils/model-generator/CaptureSourceModels.ql
Normal file
@@ -0,0 +1,43 @@
|
||||
import java
|
||||
import Telemetry.ExternalAPI
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
import ModelGeneratorUtils
|
||||
private import semmle.code.java.dataflow.internal.FlowSummaryImplSpecific
|
||||
private import semmle.code.java.dataflow.internal.FlowSummaryImpl
|
||||
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "Configuration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { sourceNode(source, _) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(Callable c |
|
||||
sink.asExpr().getEnclosingCallable() = c and
|
||||
c.isPublic() and
|
||||
c.fromSource()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: internals
|
||||
cached
|
||||
predicate specificSourceNode(DataFlow::Node node, string output, string kind) {
|
||||
exists(InterpretNode n | Private::External::isSourceNode(n, output, kind) and n.asNode() = node)
|
||||
}
|
||||
|
||||
string captureSink(Callable api) {
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, Configuration config, string kind, string output |
|
||||
config.hasFlow(src, sink) and
|
||||
specificSourceNode(sink, output, kind) and
|
||||
api = src.asExpr().getEnclosingCallable() and
|
||||
result = asSourceModel(api, output, kind)
|
||||
)
|
||||
}
|
||||
|
||||
from Callable api, string sink
|
||||
where
|
||||
sink = captureSink(api) and
|
||||
not isInTestFile(api)
|
||||
select sink order by sink
|
||||
@@ -140,8 +140,7 @@ class TargetAPI extends Callable {
|
||||
this.isPublic() and
|
||||
this.fromSource() and
|
||||
this.getDeclaringType().isPublic() and
|
||||
not this.getCompilationUnit().getFile().getAbsolutePath().matches("%src/test/%") and
|
||||
not this.getCompilationUnit().getFile().getAbsolutePath().matches("%src/guava-tests/%")
|
||||
not isInTestFile(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ private class {0}{1}Csv extends {2} {{
|
||||
}}
|
||||
}}
|
||||
"""
|
||||
if rows.strip() == "":
|
||||
return ""
|
||||
return classTemplate.format(shortname.capitalize(), kind.capitalize(), superclass, rows)
|
||||
|
||||
|
||||
@@ -111,6 +113,8 @@ summaryCsv = asCsvModel("SummaryModelCsv", "summary", summaryRows)
|
||||
sinkRows = runQuery("sink models", "CaptureSinkModels.ql")
|
||||
sinkCsv = asCsvModel("SinkModelCsv", "sinks", sinkRows)
|
||||
|
||||
sourceRows = runQuery("source models", "CaptureSourceModels.ql")
|
||||
sourceCsv = asCsvModel("SourceModelCsv", "sources", sourceRows)
|
||||
|
||||
qllTemplate = """
|
||||
/** Definitions of taint steps in the {0} framework */
|
||||
@@ -120,12 +124,16 @@ private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
{1}
|
||||
{2}
|
||||
{3}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
qllContents = qllTemplate.format(shortname, summaryCsv, sinkCsv)
|
||||
qllContents = qllTemplate.format(shortname, summaryCsv, sinkCsv, sourceCsv)
|
||||
|
||||
|
||||
with open(frameworkTarget, "w") as frameworkQll:
|
||||
frameworkQll.write(qllContents)
|
||||
|
||||
print("")
|
||||
print("CSV model written to " + frameworkTarget)
|
||||
|
||||
@@ -29,6 +29,13 @@ string asSinkModel(Callable api, string input, string kind) {
|
||||
+ kind + ";" //
|
||||
}
|
||||
|
||||
bindingset[output, kind]
|
||||
string asSourceModel(Callable api, string output, string kind) {
|
||||
result =
|
||||
asPartialModel(api) + output + ";" //
|
||||
+ kind + ";" //
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the first 6 columns for CSV rows.
|
||||
*/
|
||||
@@ -50,3 +57,8 @@ string parameterAccess(Parameter p) {
|
||||
then result = "Element of Argument[" + p.getPosition() + "]"
|
||||
else result = "Argument[" + p.getPosition() + "]"
|
||||
}
|
||||
|
||||
predicate isInTestFile(Callable api) {
|
||||
api.getCompilationUnit().getFile().getAbsolutePath().matches("%src/test/%") or
|
||||
api.getCompilationUnit().getFile().getAbsolutePath().matches("%src/guava-tests/%")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user