@@ -11,6 +11,72 @@ private import semmle.code.java.security.TaintedPathQuery
11
11
private import semmle.code.java.security.SqlInjectionQuery
12
12
private import AutomodelJavaUtil
13
13
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
+
14
80
/** An expression that may correspond to a sink model. */
15
81
private class PotentialSinkModelExpr extends Expr {
16
82
/**
@@ -36,6 +102,12 @@ private class PotentialSinkModelExpr extends Expr {
36
102
signature = ExternalFlow:: paramsString ( callable )
37
103
)
38
104
}
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
+ }
39
111
}
40
112
41
113
private string pyBool ( boolean b ) {
@@ -46,21 +118,12 @@ private string pyBool(boolean b) {
46
118
47
119
/**
48
120
* 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`.
50
123
*/
51
124
string 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"
64
127
}
65
128
66
129
/**
@@ -78,17 +141,17 @@ string getSinkModelQueryRepr(PotentialSinkModelExpr e) {
78
141
private module SinkTallier< DataFlow:: ConfigSig Config> {
79
142
module ConfigFlow = TaintTracking:: Global< Config > ;
80
143
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
83
146
c =
84
147
strictcount ( ConfigFlow:: PathNode sink |
85
148
ConfigFlow:: flowPath ( _, sink ) and
86
- s = getSinkModelRepr ( sink .getNode ( ) .asExpr ( ) )
149
+ s = sink .getNode ( ) .asExpr ( ) . ( PotentialSinkModelExpr ) . getSinkModel ( )
87
150
)
88
151
}
89
152
}
90
153
91
- predicate sinkModelTallyPerQuery ( string queryName , int alertCount , string sinkModel ) {
154
+ predicate sinkModelTallyPerQuery ( string queryName , int alertCount , SinkModel sinkModel ) {
92
155
queryName = "java/request-forgery" and
93
156
SinkTallier< RequestForgeryConfig > :: getSinkModelCount ( alertCount , sinkModel )
94
157
or
@@ -115,7 +178,7 @@ predicate sinkModelTallyPerQuery(string queryName, int alertCount, string sinkMo
115
178
SinkTallier< QueryInjectionFlowConfig > :: getSinkModelCount ( alertCount , sinkModel )
116
179
}
117
180
118
- predicate sinkModelTally ( int alertCount , string sinkModel ) {
181
+ predicate sinkModelTally ( int alertCount , SinkModel sinkModel ) {
119
182
sinkModelTallyPerQuery ( _, _, sinkModel ) and
120
183
alertCount = sum ( int c | sinkModelTallyPerQuery ( _, c , sinkModel ) )
121
184
}
0 commit comments