Skip to content

Commit f3a0161

Browse files
committed
Python: rename flow states
Close to being a revert of github@3043633 but with slightly shorter names and added comments.
1 parent e170805 commit f3a0161

File tree

2 files changed

+43
-40
lines changed

2 files changed

+43
-40
lines changed

python/ql/lib/semmle/python/security/dataflow/NoSQLInjectionCustomizations.qll

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,50 @@ import semmle.python.Concepts
1616
*/
1717
module NoSqlInjection {
1818
private newtype TFlowState =
19-
TStringInput() or
20-
TInterpretedStringInput()
19+
TString() or
20+
TDict()
2121

22-
/** A flow state, tracking the structure of the input. */
22+
/** A flow state, tracking the structure of the data. */
2323
abstract class FlowState extends TFlowState {
2424
/** Gets a textual representation of this element. */
2525
abstract string toString();
2626
}
2727

28-
/** A state where input is only a string. */
29-
class StringInput extends FlowState, TStringInput {
30-
override string toString() { result = "StringInput" }
28+
/** A state where the tracked data is only a string. */
29+
class String extends FlowState, TString {
30+
override string toString() { result = "String" }
3131
}
3232

3333
/**
34-
* A state where input is a string that has been interpreted.
35-
* For instance, it could have been turned into a dictionary,
36-
* or evaluated as javascript code.
34+
* A state where the tracked data has been converted to
35+
* a dictionary.
36+
*
37+
* We include cases where data represent JSON objects, so
38+
* it could actually still be just a string. It could
39+
* also contain query operators, or even JavaScript code.
3740
*/
38-
class InterpretedStringInput extends FlowState, TInterpretedStringInput {
39-
override string toString() { result = "InterpretedStringInput" }
41+
class Dict extends FlowState, TDict {
42+
override string toString() { result = "Dict" }
4043
}
4144

4245
/** A source allowing string inputs. */
4346
abstract class StringSource extends DataFlow::Node { }
4447

45-
/** A source of interpreted strings. */
46-
abstract class InterpretedStringSource extends DataFlow::Node { }
48+
/** A source of allowing dictionaries. */
49+
abstract class DictSource extends DataFlow::Node { }
4750

4851
/** A sink vulnerable to user controlled strings. */
4952
abstract class StringSink extends DataFlow::Node { }
5053

51-
/** A sink vulnerable to user controlled interpreted strings. */
52-
abstract class InterpretedStringSink extends DataFlow::Node { }
54+
/** A sink vulnerable to user controlled dictionaries. */
55+
abstract class DictSink extends DataFlow::Node { }
5356

54-
/** A data flow node where a string is being interpreted. */
55-
abstract class StringInterpretation extends DataFlow::Node {
56-
/** Gets the argument that specifies the string to be interpreted. */
57+
/** A data flow node where a string is converted into a dictionary. */
58+
abstract class StringToDictConversion extends DataFlow::Node {
59+
/** Gets the argument that specifies the string to be converted. */
5760
abstract DataFlow::Node getAnInput();
5861

59-
/** Gets the result of interpreting the string. */
62+
/** Gets the resulting dictionary. */
6063
abstract DataFlow::Node getOutput();
6164
}
6265

@@ -72,22 +75,22 @@ module NoSqlInjection {
7275
}
7376
}
7477

75-
/** A NoSQL query that is vulnerable to user controlled InterpretedStringionaries. */
76-
class NoSqlExecutionAsInterpretedStringSink extends InterpretedStringSink {
77-
NoSqlExecutionAsInterpretedStringSink() { this = any(NoSqlExecution noSqlExecution).getQuery() }
78+
/** A NoSQL query that is vulnerable to user controlled dictionaries. */
79+
class NoSqlExecutionAsDictSink extends DictSink {
80+
NoSqlExecutionAsDictSink() { this = any(NoSqlExecution noSqlExecution).getQuery() }
7881
}
7982

80-
/** A JSON decoding converts a string to a Dictionary. */
81-
class JsonDecoding extends Decoding, StringInterpretation {
83+
/** A JSON decoding converts a string to a dictionary. */
84+
class JsonDecoding extends Decoding, StringToDictConversion {
8285
JsonDecoding() { this.getFormat() = "JSON" }
8386

8487
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }
8588

8689
override DataFlow::Node getOutput() { result = Decoding.super.getOutput() }
8790
}
8891

89-
/** A NoSQL decoding interprets a string. */
90-
class NoSqlDecoding extends Decoding, StringInterpretation {
92+
/** A NoSQL decoding interprets a string as a dictionary. */
93+
class NoSqlDecoding extends Decoding, StringToDictConversion {
9194
NoSqlDecoding() { this.getFormat() = "NoSQL" }
9295

9396
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }

python/ql/lib/semmle/python/security/dataflow/NoSQLInjectionQuery.qll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,41 @@ module NoSqlInjectionConfig implements DataFlow::StateConfigSig {
1616

1717
predicate isSource(DataFlow::Node source, FlowState state) {
1818
source instanceof C::StringSource and
19-
state instanceof C::StringInput
19+
state instanceof C::String
2020
or
21-
source instanceof C::InterpretedStringSource and
22-
state instanceof C::InterpretedStringInput
21+
source instanceof C::DictSource and
22+
state instanceof C::Dict
2323
}
2424

2525
predicate isSink(DataFlow::Node sink, FlowState state) {
2626
sink instanceof C::StringSink and
2727
(
28-
state instanceof C::StringInput
28+
state instanceof C::String
2929
or
30-
// since InterpretedStrings can include strings,
30+
// since Dicts can include strings,
3131
// e.g. JSON objects can encode strings.
32-
state instanceof C::InterpretedStringInput
32+
state instanceof C::Dict
3333
)
3434
or
35-
sink instanceof C::InterpretedStringSink and
36-
state instanceof C::InterpretedStringInput
35+
sink instanceof C::DictSink and
36+
state instanceof C::Dict
3737
}
3838

3939
predicate isBarrier(DataFlow::Node node, FlowState state) {
40-
// Block `StringInput` paths here, since they change state to `InterpretedStringInput`
41-
exists(C::StringInterpretation c | node = c.getOutput()) and
42-
state instanceof C::StringInput
40+
// Block `String` paths here, since they change state to `Dict`
41+
exists(C::StringToDictConversion c | node = c.getOutput()) and
42+
state instanceof C::String
4343
}
4444

4545
predicate isAdditionalFlowStep(
4646
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
4747
) {
48-
exists(C::StringInterpretation c |
48+
exists(C::StringToDictConversion c |
4949
nodeFrom = c.getAnInput() and
5050
nodeTo = c.getOutput()
5151
) and
52-
stateFrom instanceof C::StringInput and
53-
stateTo instanceof C::InterpretedStringInput
52+
stateFrom instanceof C::String and
53+
stateTo instanceof C::Dict
5454
}
5555

5656
predicate isBarrier(DataFlow::Node node) {

0 commit comments

Comments
 (0)