mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Java: Use an IPA type instead of a string
While the string representation is useful for quickly modifying queries, it's a bit clunky when the data needs to be further parsed. Instead, the two queries now select all of the columns of the sinkmodel separately (which makes it easy to pull them out of the relevant output later on).
This commit is contained in:
@@ -11,6 +11,72 @@ private import semmle.code.java.security.TaintedPathQuery
|
||||
private import semmle.code.java.security.SqlInjectionQuery
|
||||
private import AutomodelJavaUtil
|
||||
|
||||
private newtype TSinkModel =
|
||||
MkSinkModel(
|
||||
string package, string type, boolean subtypes, string name, string signature, string input,
|
||||
string ext, string kind, string provenance
|
||||
) {
|
||||
ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||
}
|
||||
|
||||
class SinkModel extends TSinkModel {
|
||||
string package;
|
||||
string type;
|
||||
boolean subtypes;
|
||||
string name;
|
||||
string signature;
|
||||
string input;
|
||||
string ext;
|
||||
string kind;
|
||||
string provenance;
|
||||
|
||||
SinkModel() {
|
||||
this = MkSinkModel(package, type, subtypes, name, signature, input, ext, kind, provenance)
|
||||
}
|
||||
|
||||
/** Gets the package for this sink model. */
|
||||
string getPackage() { result = package }
|
||||
|
||||
/** Gets the type for this sink model. */
|
||||
string getType() { result = type }
|
||||
|
||||
/** Gets whether this sink model considers subtypes. */
|
||||
boolean getSubtypes() { result = subtypes }
|
||||
|
||||
/** Gets the name for this sink model. */
|
||||
string getName() { result = name }
|
||||
|
||||
/** Gets the signature for this sink model. */
|
||||
string getSignature() { result = signature }
|
||||
|
||||
/** Gets the input for this sink model. */
|
||||
string getInput() { result = input }
|
||||
|
||||
/** Gets the extension for this sink model. */
|
||||
string getExt() { result = ext }
|
||||
|
||||
/** Gets the kind for this sink model. */
|
||||
string getKind() { result = kind }
|
||||
|
||||
/** Gets the provenance for this sink model. */
|
||||
string getProvenance() { result = provenance }
|
||||
|
||||
/** Gets a string representation of this sink model. */
|
||||
string toString() {
|
||||
result =
|
||||
"SinkModel(" + package + ", " + type + ", " + subtypes + ", " + name + ", " + signature + ", "
|
||||
+ input + ", " + ext + ", " + kind + ", " + provenance + ")"
|
||||
}
|
||||
|
||||
/** Gets a string representation of this sink model as it would appear in a Models-as-Data file. */
|
||||
string getRepr() {
|
||||
result =
|
||||
"\"" + package + "\", \"" + type + "\", " + pyBool(subtypes) + ", \"" + name + "\", \"" +
|
||||
signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance +
|
||||
"\""
|
||||
}
|
||||
}
|
||||
|
||||
/** An expression that may correspond to a sink model. */
|
||||
private class PotentialSinkModelExpr extends Expr {
|
||||
/**
|
||||
@@ -36,6 +102,12 @@ private class PotentialSinkModelExpr extends Expr {
|
||||
signature = ExternalFlow::paramsString(callable)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a sink model that corresponds to this expression. */
|
||||
SinkModel getSinkModel() {
|
||||
this.hasSignature(result.getPackage(), result.getType(), result.getSubtypes(), result.getName(),
|
||||
result.getSignature(), result.getInput())
|
||||
}
|
||||
}
|
||||
|
||||
private string pyBool(boolean b) {
|
||||
@@ -46,21 +118,12 @@ private string pyBool(boolean b) {
|
||||
|
||||
/**
|
||||
* Gets a string representation of the existing sink model at the expression `e`, in the format in
|
||||
* which it would appear in a Models-as-Data file.
|
||||
* which it would appear in a Models-as-Data file. Also restricts the provenance of the sink model
|
||||
* to be `ai-generated`.
|
||||
*/
|
||||
string getSinkModelRepr(PotentialSinkModelExpr e) {
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string input,
|
||||
string ext, string kind, string provenance
|
||||
|
|
||||
e.hasSignature(package, type, subtypes, name, signature, input) and
|
||||
ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
provenance = "ai-generated" and
|
||||
result =
|
||||
"\"" + package + "\", \"" + type + "\", " + pyBool(subtypes) + ", \"" + name + "\", \"" +
|
||||
signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance +
|
||||
"\""
|
||||
)
|
||||
result = e.getSinkModel().getRepr() and
|
||||
e.getSinkModel().getProvenance() = "ai-generated"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,17 +141,17 @@ string getSinkModelQueryRepr(PotentialSinkModelExpr e) {
|
||||
private module SinkTallier<DataFlow::ConfigSig Config> {
|
||||
module ConfigFlow = TaintTracking::Global<Config>;
|
||||
|
||||
predicate getSinkModelCount(int c, string s) {
|
||||
s = getSinkModelRepr(any(ConfigFlow::PathNode sink).getNode().asExpr()) and
|
||||
predicate getSinkModelCount(int c, SinkModel s) {
|
||||
s = any(ConfigFlow::PathNode sink).getNode().asExpr().(PotentialSinkModelExpr).getSinkModel() and
|
||||
c =
|
||||
strictcount(ConfigFlow::PathNode sink |
|
||||
ConfigFlow::flowPath(_, sink) and
|
||||
s = getSinkModelRepr(sink.getNode().asExpr())
|
||||
s = sink.getNode().asExpr().(PotentialSinkModelExpr).getSinkModel()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate sinkModelTallyPerQuery(string queryName, int alertCount, string sinkModel) {
|
||||
predicate sinkModelTallyPerQuery(string queryName, int alertCount, SinkModel sinkModel) {
|
||||
queryName = "java/request-forgery" and
|
||||
SinkTallier<RequestForgeryConfig>::getSinkModelCount(alertCount, sinkModel)
|
||||
or
|
||||
@@ -115,7 +178,7 @@ predicate sinkModelTallyPerQuery(string queryName, int alertCount, string sinkMo
|
||||
SinkTallier<QueryInjectionFlowConfig>::getSinkModelCount(alertCount, sinkModel)
|
||||
}
|
||||
|
||||
predicate sinkModelTally(int alertCount, string sinkModel) {
|
||||
predicate sinkModelTally(int alertCount, SinkModel sinkModel) {
|
||||
sinkModelTallyPerQuery(_, _, sinkModel) and
|
||||
alertCount = sum(int c | sinkModelTallyPerQuery(_, c, sinkModel))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
private import java
|
||||
private import AutomodelAlertSinkUtil
|
||||
|
||||
from int alertCount, string sinkModel
|
||||
where sinkModelTally(alertCount, sinkModel)
|
||||
select alertCount, sinkModel
|
||||
from int alertCount, SinkModel s
|
||||
where sinkModelTally(alertCount, s) and s.getProvenance() = "ai-generated"
|
||||
select alertCount, s.getPackage() as package, s.getType() as type, s.getSubtypes() as subtypes,
|
||||
s.getName() as name, s.getSignature() as signature, s.getInput() as input, s.getExt() as ext,
|
||||
s.getKind() as kind, s.getProvenance() as provenance
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
private import java
|
||||
private import AutomodelAlertSinkUtil
|
||||
|
||||
from string queryId, int alertCount, string sinkModel
|
||||
where sinkModelTallyPerQuery(queryId, alertCount, sinkModel)
|
||||
select queryId, alertCount, sinkModel
|
||||
from string queryId, int alertCount, SinkModel s
|
||||
where
|
||||
sinkModelTallyPerQuery(queryId, alertCount, s) and
|
||||
s.getProvenance() = "ai-generated"
|
||||
select queryId, alertCount, s.getPackage() as package, s.getType() as type,
|
||||
s.getSubtypes() as subtypes, s.getName() as name, s.getSignature() as signature,
|
||||
s.getInput() as input, s.getExt() as ext, s.getKind() as kind, s.getProvenance() as provenance
|
||||
|
||||
Reference in New Issue
Block a user