mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Python: Some renaming of flow states
This commit is contained in:
@@ -17,7 +17,7 @@ import semmle.python.Concepts
|
|||||||
module NoSqlInjection {
|
module NoSqlInjection {
|
||||||
private newtype TFlowState =
|
private newtype TFlowState =
|
||||||
TStringInput() or
|
TStringInput() or
|
||||||
TDictInput()
|
TInterpretedStringInput()
|
||||||
|
|
||||||
/** A flow state, tracking the structure of the input. */
|
/** A flow state, tracking the structure of the input. */
|
||||||
abstract class FlowState extends TFlowState {
|
abstract class FlowState extends TFlowState {
|
||||||
@@ -30,29 +30,33 @@ module NoSqlInjection {
|
|||||||
override string toString() { result = "StringInput" }
|
override string toString() { result = "StringInput" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A state where input is a dictionary. */
|
/**
|
||||||
class DictInput extends FlowState, TDictInput {
|
* A state where input is a string that has been interpreted.
|
||||||
override string toString() { result = "DictInput" }
|
* For instance, it could have been turned into a dictionary,
|
||||||
|
* or evaluated as javascript code.
|
||||||
|
*/
|
||||||
|
class InterpretedStringInput extends FlowState, TInterpretedStringInput {
|
||||||
|
override string toString() { result = "InterpretedStringInput" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A source allowing string inputs. */
|
/** A source allowing string inputs. */
|
||||||
abstract class StringSource extends DataFlow::Node { }
|
abstract class StringSource extends DataFlow::Node { }
|
||||||
|
|
||||||
/** A source allowing dictionary inputs. */
|
/** A source of interpreted strings. */
|
||||||
abstract class DictSource extends DataFlow::Node { }
|
abstract class InterpretedStringSource extends DataFlow::Node { }
|
||||||
|
|
||||||
/** A sink vulnerable to user controlled strings. */
|
/** A sink vulnerable to user controlled strings. */
|
||||||
abstract class StringSink extends DataFlow::Node { }
|
abstract class StringSink extends DataFlow::Node { }
|
||||||
|
|
||||||
/** A sink vulnerable to user controlled dictionaries. */
|
/** A sink vulnerable to user controlled interpreted strings. */
|
||||||
abstract class DictSink extends DataFlow::Node { }
|
abstract class InterpretedStringSink extends DataFlow::Node { }
|
||||||
|
|
||||||
/** A data flow node where a string is converted into a dictionary. */
|
/** A data flow node where a string is being interpreted. */
|
||||||
abstract class StringToDictConversion extends DataFlow::Node {
|
abstract class StringInterpretation extends DataFlow::Node {
|
||||||
/** Gets the argument that specifies the string to be converted. */
|
/** Gets the argument that specifies the string to be interpreted. */
|
||||||
abstract DataFlow::Node getAnInput();
|
abstract DataFlow::Node getAnInput();
|
||||||
|
|
||||||
/** Gets the resulting dictionary. */
|
/** Gets the result of interpreting the string. */
|
||||||
abstract DataFlow::Node getOutput();
|
abstract DataFlow::Node getOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,14 +72,23 @@ module NoSqlInjection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A NoSQL query that is vulnerable to user controlled dictionaries. */
|
/** A NoSQL query that is vulnerable to user controlled InterpretedStringionaries. */
|
||||||
class NoSqlExecutionAsDictSink extends DictSink {
|
class NoSqlExecutionAsInterpretedStringSink extends InterpretedStringSink {
|
||||||
NoSqlExecutionAsDictSink() { this = any(NoSqlExecution noSqlExecution).getQuery() }
|
NoSqlExecutionAsInterpretedStringSink() { this = any(NoSqlExecution noSqlExecution).getQuery() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A JSON decoding converts a string to a dictionary. */
|
/** A JSON decoding converts a string to a Dictionary. */
|
||||||
class JsonDecoding extends Decoding, StringToDictConversion {
|
class JsonDecoding extends Decoding, StringInterpretation {
|
||||||
JsonDecoding() { this.getFormat() in ["JSON", "NoSQL"] }
|
JsonDecoding() { this.getFormat() = "JSON" }
|
||||||
|
|
||||||
|
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }
|
||||||
|
|
||||||
|
override DataFlow::Node getOutput() { result = Decoding.super.getOutput() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A NoSQL decoding interprets a string. */
|
||||||
|
class NoSqlDecoding extends Decoding, StringInterpretation {
|
||||||
|
NoSqlDecoding() { this.getFormat() = "NoSQL" }
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }
|
override DataFlow::Node getAnInput() { result = Decoding.super.getAnInput() }
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ module NoSqlInjectionConfig implements DataFlow::StateConfigSig {
|
|||||||
source instanceof C::StringSource and
|
source instanceof C::StringSource and
|
||||||
state instanceof C::StringInput
|
state instanceof C::StringInput
|
||||||
or
|
or
|
||||||
source instanceof C::DictSource and
|
source instanceof C::InterpretedStringSource and
|
||||||
state instanceof C::DictInput
|
state instanceof C::InterpretedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||||
@@ -27,29 +27,30 @@ module NoSqlInjectionConfig implements DataFlow::StateConfigSig {
|
|||||||
(
|
(
|
||||||
state instanceof C::StringInput
|
state instanceof C::StringInput
|
||||||
or
|
or
|
||||||
// since dictionaries can encode strings
|
// since InterpretedStrings can include strings,
|
||||||
state instanceof C::DictInput
|
// e.g. JSON objects can encode strings.
|
||||||
|
state instanceof C::InterpretedStringInput
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
sink instanceof C::DictSink and
|
sink instanceof C::InterpretedStringSink and
|
||||||
state instanceof C::DictInput
|
state instanceof C::InterpretedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node, FlowState state) {
|
predicate isBarrier(DataFlow::Node node, FlowState state) {
|
||||||
// Block `StringInput` paths here, since they change state to `DictInput`
|
// Block `StringInput` paths here, since they change state to `InterpretedStringInput`
|
||||||
exists(C::StringToDictConversion c | node = c.getOutput()) and
|
exists(C::StringInterpretation c | node = c.getOutput()) and
|
||||||
state instanceof C::StringInput
|
state instanceof C::StringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(
|
predicate isAdditionalFlowStep(
|
||||||
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
|
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
|
||||||
) {
|
) {
|
||||||
exists(C::StringToDictConversion c |
|
exists(C::StringInterpretation c |
|
||||||
nodeFrom = c.getAnInput() and
|
nodeFrom = c.getAnInput() and
|
||||||
nodeTo = c.getOutput()
|
nodeTo = c.getOutput()
|
||||||
) and
|
) and
|
||||||
stateFrom instanceof C::StringInput and
|
stateFrom instanceof C::StringInput and
|
||||||
stateTo instanceof C::DictInput
|
stateTo instanceof C::InterpretedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) {
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user