@@ -29,11 +29,42 @@ import semmle.code.java.frameworks.struts.StrutsActions
2929import semmle.code.java.frameworks.Thrift
3030import semmle.code.java.frameworks.javaee.jsf.JSFRenderer
3131private import semmle.code.java.dataflow.ExternalFlow
32+ private import semmle.code.java.dataflow.ExternalFlowConfiguration
33+
34+ /**
35+ * A data flow source.
36+ */
37+ abstract class SourceNode extends DataFlow:: Node {
38+ /**
39+ * Gets a string that represents the source kind with respect to threat modeling.
40+ */
41+ abstract string getThreatModel ( ) ;
42+ }
43+
44+ /**
45+ * A class of data flow sources that respects the
46+ * current threat model configuration.
47+ */
48+ class ThreatModelFlowSource extends DataFlow:: Node {
49+ ThreatModelFlowSource ( ) {
50+ // Expansive threat model.
51+ currentThreatModel ( "all" ) and
52+ ( this instanceof SourceNode or sourceNode ( this , _) )
53+ or
54+ exists ( string kind |
55+ // Specific threat model.
56+ currentThreatModel ( kind ) and
57+ ( this .( SourceNode ) .getThreatModel ( ) = kind or sourceNode ( this , kind ) )
58+ )
59+ }
60+ }
3261
3362/** A data flow source of remote user input. */
34- abstract class RemoteFlowSource extends DataFlow :: Node {
63+ abstract class RemoteFlowSource extends SourceNode {
3564 /** Gets a string that describes the type of this remote flow source. */
3665 abstract string getSourceType ( ) ;
66+
67+ override string getThreatModel ( ) { result = "remote" }
3768}
3869
3970/**
@@ -175,14 +206,47 @@ abstract class UserInput extends DataFlow::Node { }
175206private class RemoteUserInput extends UserInput instanceof RemoteFlowSource { }
176207
177208/** A node with input that may be controlled by a local user. */
178- abstract class LocalUserInput extends UserInput { }
209+ abstract class LocalUserInput extends UserInput , SourceNode {
210+ override string getThreatModel ( ) { result = "local" }
211+ }
179212
180213/**
214+ * DEPRECATED: Use the threat models feature.
215+ * That is, use `ThreatModelFlowSource` as the class of nodes for sources
216+ * and set up the threat model configuration to filter source nodes.
217+ * Alternatively, use `getThreatModel` to filter nodes to create the
218+ * class of nodes you need.
219+ *
181220 * A node with input from the local environment, such as files, standard in,
182221 * environment variables, and main method parameters.
183222 */
184- class EnvInput extends LocalUserInput {
223+ deprecated class EnvInput extends DataFlow :: Node {
185224 EnvInput ( ) {
225+ this instanceof EnvironmentInput or
226+ this instanceof CliInput or
227+ this instanceof FileInput
228+ }
229+ }
230+
231+ /**
232+ * A node with input from the local environment, such as
233+ * environment variables.
234+ */
235+ private class EnvironmentInput extends LocalUserInput {
236+ EnvironmentInput ( ) {
237+ // Results from various specific methods.
238+ this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof EnvReadMethod
239+ }
240+
241+ override string getThreatModel ( ) { result = "environment" }
242+ }
243+
244+ /**
245+ * A node with input from the command line, such as standard in
246+ * and main method parameters.
247+ */
248+ private class CliInput extends LocalUserInput {
249+ CliInput ( ) {
186250 // Parameters to a main method.
187251 exists ( MainMethod main | this .asParameter ( ) = main .getParameter ( 0 ) )
188252 or
@@ -191,23 +255,46 @@ class EnvInput extends LocalUserInput {
191255 f .getAnAnnotation ( ) .getType ( ) .getQualifiedName ( ) = "org.kohsuke.args4j.Argument"
192256 )
193257 or
194- // Results from various specific methods.
195- this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof EnvReadMethod
196- or
197258 // Access to `System.in`.
198259 exists ( Field f | this .asExpr ( ) = f .getAnAccess ( ) | f instanceof SystemIn )
199- or
260+ }
261+
262+ override string getThreatModel ( ) { result = "commandargs" }
263+ }
264+
265+ /**
266+ * A node with input from the local environment, such as files.
267+ */
268+ private class FileInput extends LocalUserInput {
269+ FileInput ( ) {
200270 // Access to files.
201271 this .asExpr ( )
202272 .( ConstructorCall )
203273 .getConstructedType ( )
204274 .hasQualifiedName ( "java.io" , "FileInputStream" )
205275 }
276+
277+ override string getThreatModel ( ) { result = "file" }
206278}
207279
208- /** A node with input from a database. */
209- class DatabaseInput extends LocalUserInput {
210- DatabaseInput ( ) { this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof ResultSetGetStringMethod }
280+ /**
281+ * DEPRECATED: Use the threat models feature.
282+ * That is, use `ThreatModelFlowSource` as the class of nodes for sources
283+ * and set up the threat model configuration to filter source nodes.
284+ * Alternatively, use `getThreatModel` to filter nodes to create the
285+ * class of nodes you need.
286+ *
287+ * A node with input from a database.
288+ */
289+ deprecated class DatabaseInput = DbInput ;
290+
291+ /**
292+ * A node with input from a database.
293+ */
294+ private class DbInput extends LocalUserInput {
295+ DbInput ( ) { this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof ResultSetGetStringMethod }
296+
297+ override string getThreatModel ( ) { result = "database" }
211298}
212299
213300/** A method that reads from the environment, such as `System.getProperty` or `System.getenv`. */
0 commit comments