@@ -11,6 +11,72 @@ private import semmle.code.java.security.TaintedPathQuery
1111private import semmle.code.java.security.SqlInjectionQuery
1212private import AutomodelJavaUtil
1313
14+ private newtype TSinkModel =
15+ MkSinkModel (
16+ string package , string type , boolean subtypes , string name , string signature , string input ,
17+ string ext , string kind , string provenance
18+ ) {
19+ ExternalFlow:: sinkModel ( package , type , subtypes , name , signature , ext , input , kind , provenance )
20+ }
21+
22+ class SinkModel extends TSinkModel {
23+ string package ;
24+ string type ;
25+ boolean subtypes ;
26+ string name ;
27+ string signature ;
28+ string input ;
29+ string ext ;
30+ string kind ;
31+ string provenance ;
32+
33+ SinkModel ( ) {
34+ this = MkSinkModel ( package , type , subtypes , name , signature , input , ext , kind , provenance )
35+ }
36+
37+ /** Gets the package for this sink model. */
38+ string getPackage ( ) { result = package }
39+
40+ /** Gets the type for this sink model. */
41+ string getType ( ) { result = type }
42+
43+ /** Gets whether this sink model considers subtypes. */
44+ boolean getSubtypes ( ) { result = subtypes }
45+
46+ /** Gets the name for this sink model. */
47+ string getName ( ) { result = name }
48+
49+ /** Gets the signature for this sink model. */
50+ string getSignature ( ) { result = signature }
51+
52+ /** Gets the input for this sink model. */
53+ string getInput ( ) { result = input }
54+
55+ /** Gets the extension for this sink model. */
56+ string getExt ( ) { result = ext }
57+
58+ /** Gets the kind for this sink model. */
59+ string getKind ( ) { result = kind }
60+
61+ /** Gets the provenance for this sink model. */
62+ string getProvenance ( ) { result = provenance }
63+
64+ /** Gets a string representation of this sink model. */
65+ string toString ( ) {
66+ result =
67+ "SinkModel(" + package + ", " + type + ", " + subtypes + ", " + name + ", " + signature + ", "
68+ + input + ", " + ext + ", " + kind + ", " + provenance + ")"
69+ }
70+
71+ /** Gets a string representation of this sink model as it would appear in a Models-as-Data file. */
72+ string getRepr ( ) {
73+ result =
74+ "\"" + package + "\", \"" + type + "\", " + pyBool ( subtypes ) + ", \"" + name + "\", \"" +
75+ signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance +
76+ "\""
77+ }
78+ }
79+
1480/** An expression that may correspond to a sink model. */
1581private class PotentialSinkModelExpr extends Expr {
1682 /**
@@ -36,6 +102,12 @@ private class PotentialSinkModelExpr extends Expr {
36102 signature = ExternalFlow:: paramsString ( callable )
37103 )
38104 }
105+
106+ /** Gets a sink model that corresponds to this expression. */
107+ SinkModel getSinkModel ( ) {
108+ this .hasSignature ( result .getPackage ( ) , result .getType ( ) , result .getSubtypes ( ) , result .getName ( ) ,
109+ result .getSignature ( ) , result .getInput ( ) )
110+ }
39111}
40112
41113private string pyBool ( boolean b ) {
@@ -46,21 +118,12 @@ private string pyBool(boolean b) {
46118
47119/**
48120 * Gets a string representation of the existing sink model at the expression `e`, in the format in
49- * which it would appear in a Models-as-Data file.
121+ * which it would appear in a Models-as-Data file. Also restricts the provenance of the sink model
122+ * to be `ai-generated`.
50123 */
51124string getSinkModelRepr ( PotentialSinkModelExpr e ) {
52- exists (
53- string package , string type , boolean subtypes , string name , string signature , string input ,
54- string ext , string kind , string provenance
55- |
56- e .hasSignature ( package , type , subtypes , name , signature , input ) and
57- ExternalFlow:: sinkModel ( package , type , subtypes , name , signature , ext , input , kind , provenance ) and
58- provenance = "ai-generated" and
59- result =
60- "\"" + package + "\", \"" + type + "\", " + pyBool ( subtypes ) + ", \"" + name + "\", \"" +
61- signature + "\", \"" + ext + "\", \"" + input + "\", \"" + kind + "\", \"" + provenance +
62- "\""
63- )
125+ result = e .getSinkModel ( ) .getRepr ( ) and
126+ e .getSinkModel ( ) .getProvenance ( ) = "ai-generated"
64127}
65128
66129/**
@@ -78,17 +141,17 @@ string getSinkModelQueryRepr(PotentialSinkModelExpr e) {
78141private module SinkTallier< DataFlow:: ConfigSig Config> {
79142 module ConfigFlow = TaintTracking:: Global< Config > ;
80143
81- predicate getSinkModelCount ( int c , string s ) {
82- s = getSinkModelRepr ( any ( ConfigFlow:: PathNode sink ) .getNode ( ) .asExpr ( ) ) and
144+ predicate getSinkModelCount ( int c , SinkModel s ) {
145+ s = any ( ConfigFlow:: PathNode sink ) .getNode ( ) .asExpr ( ) . ( PotentialSinkModelExpr ) . getSinkModel ( ) and
83146 c =
84147 strictcount ( ConfigFlow:: PathNode sink |
85148 ConfigFlow:: flowPath ( _, sink ) and
86- s = getSinkModelRepr ( sink .getNode ( ) .asExpr ( ) )
149+ s = sink .getNode ( ) .asExpr ( ) . ( PotentialSinkModelExpr ) . getSinkModel ( )
87150 )
88151 }
89152}
90153
91- predicate sinkModelTallyPerQuery ( string queryName , int alertCount , string sinkModel ) {
154+ predicate sinkModelTallyPerQuery ( string queryName , int alertCount , SinkModel sinkModel ) {
92155 queryName = "java/request-forgery" and
93156 SinkTallier< RequestForgeryConfig > :: getSinkModelCount ( alertCount , sinkModel )
94157 or
@@ -115,7 +178,7 @@ predicate sinkModelTallyPerQuery(string queryName, int alertCount, string sinkMo
115178 SinkTallier< QueryInjectionFlowConfig > :: getSinkModelCount ( alertCount , sinkModel )
116179}
117180
118- predicate sinkModelTally ( int alertCount , string sinkModel ) {
181+ predicate sinkModelTally ( int alertCount , SinkModel sinkModel ) {
119182 sinkModelTallyPerQuery ( _, _, sinkModel ) and
120183 alertCount = sum ( int c | sinkModelTallyPerQuery ( _, c , sinkModel ) )
121184}
0 commit comments