Skip to content

Commit 4f58b19

Browse files
committed
PS: Add wrapper classes for local and remote flow sources.
1 parent 2ffbf17 commit 4f58b19

File tree

4 files changed

+149
-1
lines changed

4 files changed

+149
-1
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/** Provides classes representing various flow sources for taint tracking. */
2+
import semmle.code.powershell.dataflow.internal.DataFlowPublic as DataFlow
3+
import semmle.code.powershell.dataflow.flowsources.Remote
4+
import semmle.code.powershell.dataflow.flowsources.Local
5+
import semmle.code.powershell.frameworks.data.internal.ApiGraphModels
6+
7+
/**
8+
* A data flow source.
9+
*/
10+
abstract class SourceNode extends DataFlow::Node {
11+
/**
12+
* Gets a string that represents the source kind with respect to threat modeling.
13+
*/
14+
abstract string getThreatModel();
15+
16+
/** Gets a string that describes the type of this flow source. */
17+
abstract string getSourceType();
18+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Provides classes representing sources of local input.
3+
*/
4+
5+
import powershell
6+
private import FlowSources
7+
8+
/** A data flow source of local data. */
9+
abstract class LocalFlowSource extends SourceNode {
10+
override string getSourceType() { result = "local flow source" }
11+
12+
override string getThreatModel() { result = "local" }
13+
}
14+
15+
private class ExternalLocalFlowSource extends LocalFlowSource {
16+
ExternalLocalFlowSource() { this = ModelOutput::getASourceNode("local", _).asSource() }
17+
18+
override string getSourceType() { result = "external" }
19+
}
20+
21+
/** A data flow source of local user input. */
22+
abstract class LocalUserInputSource extends LocalFlowSource { }
23+
24+
/**
25+
* A dataflow source that represents the access of an environment variable.
26+
*/
27+
abstract class EnvironmentVariableSource extends LocalFlowSource {
28+
override string getThreatModel() { result = "environment" }
29+
30+
override string getSourceType() { result = "environment variable" }
31+
}
32+
33+
private class ExternalEnvironmentVariableSource extends EnvironmentVariableSource {
34+
ExternalEnvironmentVariableSource() {
35+
this = ModelOutput::getASourceNode("environment", _).asSource()
36+
}
37+
}
38+
39+
/**
40+
* A dataflow source that represents the access of a command line argument.
41+
*/
42+
abstract class CommandLineArgumentSource extends LocalFlowSource {
43+
override string getThreatModel() { result = "commandargs" }
44+
45+
override string getSourceType() { result = "command line argument" }
46+
}
47+
48+
private class ExternalCommandLineArgumentSource extends CommandLineArgumentSource {
49+
ExternalCommandLineArgumentSource() {
50+
this = ModelOutput::getASourceNode("command-line", _).asSource()
51+
}
52+
}
53+
54+
/**
55+
* A data flow source that represents the parameters of the `Main` method of a program.
56+
*/
57+
private class MainMethodArgumentSource extends CommandLineArgumentSource {
58+
MainMethodArgumentSource() { this.asParameter().getFunction() instanceof TopLevel }
59+
}
60+
61+
/**
62+
* A data flow source that represents the access of a value from the Windows registry.
63+
*/
64+
abstract class WindowsRegistrySource extends LocalFlowSource {
65+
override string getThreatModel() { result = "windows-registry" }
66+
67+
override string getSourceType() { result = "a value from the Windows registry" }
68+
}
69+
70+
private class ExternalWindowsRegistrySource extends WindowsRegistrySource {
71+
ExternalWindowsRegistrySource() {
72+
this = ModelOutput::getASourceNode("windows-registry", _).asSource()
73+
}
74+
}
75+
76+
/**
77+
* A dataflow source that represents the reading from stdin.
78+
*/
79+
abstract class StdinSource extends LocalFlowSource {
80+
override string getThreatModel() { result = "stdin" }
81+
82+
override string getSourceType() { result = "read from stdin" }
83+
}
84+
85+
private class ExternalStdinSource extends StdinSource {
86+
ExternalStdinSource() { this = ModelOutput::getASourceNode("stdin", _).asSource() }
87+
}

powershell/ql/lib/semmle/code/powershell/frameworks/data/ModelsAsData.qll

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,48 @@
44
*/
55

66
private import powershell
7-
private import semmle.code.powershell.dataflow.RemoteFlowSources
7+
private import semmle.code.powershell.ApiGraphs
8+
private import internal.ApiGraphModels as Shared
9+
private import internal.ApiGraphModelsSpecific as Specific
10+
import Shared::ModelInput as ModelInput
11+
import Shared::ModelOutput as ModelOutput
12+
private import semmle.code.powershell.dataflow.flowsources.FlowSources
813
private import semmle.code.powershell.dataflow.FlowSummary
14+
15+
/**
16+
* A remote flow source originating from a CSV source row.
17+
*/
18+
private class RemoteFlowSourceFromCsv extends RemoteFlowSource::Range {
19+
RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").asSource() }
20+
21+
override string getSourceType() { result = "Remote flow (from model)" }
22+
}
23+
24+
private class SummarizedCallableFromModel extends SummarizedCallable {
25+
string type;
26+
string path;
27+
28+
SummarizedCallableFromModel() {
29+
ModelOutput::relevantSummaryModel(type, path, _, _, _, _) and
30+
this = type + ";" + path
31+
}
32+
33+
override Call getACall() {
34+
exists(API::MethodAccessNode base |
35+
ModelOutput::resolvedSummaryBase(type, path, base) and
36+
result = base.asCall().asExpr().getExpr()
37+
)
38+
}
39+
40+
override predicate propagatesFlow(
41+
string input, string output, boolean preservesValue, string model
42+
) {
43+
exists(string kind | ModelOutput::relevantSummaryModel(type, path, input, output, kind, model) |
44+
kind = "value" and
45+
preservesValue = true
46+
or
47+
kind = "taint" and
48+
preservesValue = false
49+
)
50+
}
51+
}

0 commit comments

Comments
 (0)