mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'main' into jorgectf/python/deserialization
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* (in that the `.expected` file should always be empty).
|
||||
*
|
||||
* To add this framework to a new language:
|
||||
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `LineComment` class. This class
|
||||
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `ExpectationComment` class. This class
|
||||
* must support a `getContents` method that returns the contents of the given comment, _excluding_
|
||||
* the comment indicator itself. It should also define `toString` and `getLocation` as usual.
|
||||
*
|
||||
@@ -60,8 +60,8 @@
|
||||
*
|
||||
* Example:
|
||||
* ```cpp
|
||||
* int i = x + 5; // $const=5
|
||||
* int j = y + (7 - 3) // $const=7 const=3 const=4 // The result of the subtraction is a constant.
|
||||
* int i = x + 5; // $ const=5
|
||||
* int j = y + (7 - 3) // $ const=7 const=3 const=4 // The result of the subtraction is a constant.
|
||||
* ```
|
||||
*
|
||||
* For tests that contain known missing and spurious results, it is possible to further
|
||||
@@ -194,7 +194,7 @@ private int getEndOfColumnPosition(int start, string content) {
|
||||
}
|
||||
|
||||
private predicate getAnExpectation(
|
||||
LineComment comment, TColumn column, string expectation, string tags, string value
|
||||
ExpectationComment comment, TColumn column, string expectation, string tags, string value
|
||||
) {
|
||||
exists(string content |
|
||||
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
|
||||
@@ -247,14 +247,14 @@ private newtype TFailureLocatable =
|
||||
) {
|
||||
test.hasActualResult(location, element, tag, value)
|
||||
} or
|
||||
TValidExpectation(LineComment comment, string tag, string value, string knownFailure) {
|
||||
TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
|
||||
exists(TColumn column, string tags |
|
||||
getAnExpectation(comment, column, _, tags, value) and
|
||||
tag = tags.splitAt(",") and
|
||||
knownFailure = getColumnString(column)
|
||||
)
|
||||
} or
|
||||
TInvalidExpectation(LineComment comment, string expectation) {
|
||||
TInvalidExpectation(ExpectationComment comment, string expectation) {
|
||||
getAnExpectation(comment, _, expectation, _, _) and
|
||||
not expectation.regexpMatch(expectationPattern())
|
||||
}
|
||||
@@ -292,7 +292,7 @@ class ActualResult extends FailureLocatable, TActualResult {
|
||||
}
|
||||
|
||||
abstract private class Expectation extends FailureLocatable {
|
||||
LineComment comment;
|
||||
ExpectationComment comment;
|
||||
|
||||
override string toString() { result = comment.toString() }
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@ import python
|
||||
* A class representing line comments in Python. As this is the only form of comment Python
|
||||
* permits, we simply reuse the `Comment` class.
|
||||
*/
|
||||
class LineComment = Comment;
|
||||
class ExpectationComment = Comment;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -422,6 +422,18 @@ def test_call_extra_keyword_flow():
|
||||
SINK(f_extra_keyword_flow(**{SOURCE: None})) #$ MISSING:flow="SOURCE -> f_extra_keyword(..)"
|
||||
|
||||
|
||||
# 6.11. Boolean operations
|
||||
|
||||
def test_or(x = False):
|
||||
# if we don't know the value of the lhs, we should always add flow
|
||||
SINK(x or SOURCE) #$ flow="SOURCE -> BoolExpr"
|
||||
|
||||
|
||||
def test_and(x = True):
|
||||
# if we don't know the value of the lhs, we should always add flow
|
||||
SINK(x and SOURCE) #$ flow="SOURCE -> BoolExpr"
|
||||
|
||||
|
||||
# 6.12. Assignment expressions
|
||||
def test_assignment_expression():
|
||||
x = NONSOURCE
|
||||
|
||||
@@ -72,9 +72,14 @@
|
||||
| test.py:6:15:6:15 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
| test.py:6:15:6:15 | SSA variable x | test.py:7:12:7:12 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:29:7:29 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:24 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:47:7:47 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:42 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:53 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:66 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:71:7:78 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:10:10:10 | ControlFlowNode for x | test.py:10:10:10:10 | SSA variable x |
|
||||
|
||||
@@ -30,20 +30,22 @@
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:6:13:6:18 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:11:17:11:22 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | GSSA Variable object | examples.py:11:17:11:22 | ControlFlowNode for object |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module examples | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module examples | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj | examples.py:13:20:13:24 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj | examples.py:54:11:54:15 | ControlFlowNode for MyObj |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.SINK_F | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:0:0:0:0 | ModuleVariableNode for examples.SINK_F | examples.py:21:5:21:10 | ControlFlowNode for SINK_F |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:6:7:6:11 | GSSA Variable MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:1:6:20 | ControlFlowNode for ClassExpr | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module examples |
|
||||
| examples.py:6:7:6:11 | ControlFlowNode for MyObj | examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj |
|
||||
| examples.py:6:7:6:11 | ControlFlowNode for MyObj | examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:0:0:0:0 | ModuleVariableNode for examples.MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:25:9:25:13 | ControlFlowNode for MyObj |
|
||||
| examples.py:6:7:6:11 | GSSA Variable MyObj | examples.py:49:7:49:11 | ControlFlowNode for MyObj |
|
||||
@@ -470,78 +472,82 @@
|
||||
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:53:28:53:28 | ControlFlowNode for x |
|
||||
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() |
|
||||
| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:47:13:47:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:47:13:47:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:54:13:54:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:54:13:54:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:81:11:81:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:81:11:81:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:86:11:86:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:86:11:86:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test | test.py:63:9:63:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test | test.py:63:9:63:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test | test.py:73:9:73:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test | test.py:73:9:73:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:50:5:50:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:50:5:50:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:57:5:57:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:57:5:57:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:67:5:67:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:67:5:67:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:77:5:77:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:77:5:77:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:82:5:82:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:82:5:82:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:87:5:87:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:87:5:87:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:97:5:97:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test | test.py:97:5:97:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:61:9:61:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:61:9:61:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:71:9:71:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:71:9:71:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:97:33:97:38 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test | test.py:97:33:97:38 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test | test.py:97:10:97:31 | ControlFlowNode for fields_with_local_flow |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test | test.py:97:10:97:31 | ControlFlowNode for fields_with_local_flow |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:12:9:12:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:12:9:12:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:14:9:14:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:14:9:14:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:19:9:19:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:19:9:19:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:21:9:21:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable print in Module test | test.py:21:9:21:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable setFoo in Module test | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for Global Variable setFoo in Module test | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:47:13:47:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:47:13:47:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:54:13:54:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:54:13:54:17 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:81:11:81:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:81:11:81:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:86:11:86:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:86:11:86:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj | test.py:63:9:63:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj | test.py:63:9:63:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj | test.py:73:9:73:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj | test.py:73:9:73:17 | ControlFlowNode for NestedObj |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:50:5:50:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:50:5:50:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:57:5:57:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:57:5:57:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:67:5:67:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:67:5:67:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:77:5:77:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:77:5:77:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:82:5:82:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:82:5:82:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:87:5:87:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:87:5:87:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:97:5:97:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK | test.py:97:5:97:8 | ControlFlowNode for SINK |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:49:19:49:24 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:56:18:56:23 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:61:9:61:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:61:9:61:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:71:9:71:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:71:9:71:14 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:81:17:81:22 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:86:21:86:26 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:97:33:97:38 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE | test.py:97:33:97:38 | ControlFlowNode for SOURCE |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow | test.py:97:10:97:31 | ControlFlowNode for fields_with_local_flow |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow | test.py:97:10:97:31 | ControlFlowNode for fields_with_local_flow |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:12:9:12:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:12:9:12:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:14:9:14:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:14:9:14:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:19:9:19:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:19:9:19:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:21:9:21:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.print | test.py:21:9:21:13 | ControlFlowNode for print |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.setFoo | test.py:49:5:49:10 | ControlFlowNode for setFoo |
|
||||
| test.py:2:13:2:26 | ControlFlowNode for Str | test.py:2:1:2:9 | GSSA Variable NONSOURCE |
|
||||
| test.py:2:13:2:26 | ControlFlowNode for Str | test.py:2:1:2:9 | GSSA Variable NONSOURCE |
|
||||
| test.py:3:1:3:6 | GSSA Variable SOURCE | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test |
|
||||
| test.py:3:1:3:6 | GSSA Variable SOURCE | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SOURCE in Module test |
|
||||
| test.py:3:1:3:6 | ControlFlowNode for SOURCE | test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE |
|
||||
| test.py:3:1:3:6 | ControlFlowNode for SOURCE | test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE |
|
||||
| test.py:3:1:3:6 | GSSA Variable SOURCE | test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE |
|
||||
| test.py:3:1:3:6 | GSSA Variable SOURCE | test.py:0:0:0:0 | ModuleVariableNode for test.SOURCE |
|
||||
| test.py:3:10:3:17 | ControlFlowNode for Str | test.py:3:1:3:6 | GSSA Variable SOURCE |
|
||||
| test.py:3:10:3:17 | ControlFlowNode for Str | test.py:3:1:3:6 | GSSA Variable SOURCE |
|
||||
| test.py:6:1:6:17 | ControlFlowNode for FunctionExpr | test.py:6:5:6:13 | GSSA Variable is_source |
|
||||
| test.py:6:1:6:17 | ControlFlowNode for FunctionExpr | test.py:6:5:6:13 | GSSA Variable is_source |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for Global Variable is_source in Module test |
|
||||
| test.py:6:5:6:13 | ControlFlowNode for is_source | test.py:0:0:0:0 | ModuleVariableNode for test.is_source |
|
||||
| test.py:6:5:6:13 | ControlFlowNode for is_source | test.py:0:0:0:0 | ModuleVariableNode for test.is_source |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for test.is_source |
|
||||
| test.py:6:5:6:13 | GSSA Variable is_source | test.py:0:0:0:0 | ModuleVariableNode for test.is_source |
|
||||
| test.py:6:15:6:15 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
| test.py:6:15:6:15 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
| test.py:6:15:6:15 | ControlFlowNode for x | test.py:6:15:6:15 | SSA variable x |
|
||||
@@ -602,6 +608,8 @@
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:12 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:12:7:24 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:12:7:24 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:12:7:78 | ControlFlowNode for BoolExpr | test.py:11:8:11:19 | ControlFlowNode for is_source() |
|
||||
| test.py:7:12:7:78 | ControlFlowNode for BoolExpr | test.py:11:8:11:19 | ControlFlowNode for is_source() |
|
||||
| test.py:7:12:7:78 | ControlFlowNode for BoolExpr | test.py:18:8:18:19 | ControlFlowNode for is_source() |
|
||||
@@ -618,6 +626,8 @@
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:29 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:29:7:42 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:29:7:42 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:58:7:58 | ControlFlowNode for x |
|
||||
@@ -626,16 +636,24 @@
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:47 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:47:7:53 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:47:7:53 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:58 | ControlFlowNode for x | test.py:7:71:7:71 | ControlFlowNode for x |
|
||||
| test.py:7:58:7:66 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:58:7:66 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:71:7:78 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:7:71:7:78 | ControlFlowNode for Compare | test.py:7:12:7:78 | ControlFlowNode for BoolExpr |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | ControlFlowNode for FunctionExpr | test.py:10:5:10:8 | GSSA Variable SINK |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:1:10:12 | GSSA Variable is_source | test.py:11:8:11:16 | ControlFlowNode for is_source |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK in Module test |
|
||||
| test.py:10:5:10:8 | ControlFlowNode for SINK | test.py:0:0:0:0 | ModuleVariableNode for test.SINK |
|
||||
| test.py:10:5:10:8 | ControlFlowNode for SINK | test.py:0:0:0:0 | ModuleVariableNode for test.SINK |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for test.SINK |
|
||||
| test.py:10:5:10:8 | GSSA Variable SINK | test.py:0:0:0:0 | ModuleVariableNode for test.SINK |
|
||||
| test.py:10:10:10:10 | ControlFlowNode for x | test.py:10:10:10:10 | SSA variable x |
|
||||
| test.py:10:10:10:10 | ControlFlowNode for x | test.py:10:10:10:10 | SSA variable x |
|
||||
| test.py:10:10:10:10 | ControlFlowNode for x | test.py:10:10:10:10 | SSA variable x |
|
||||
@@ -684,8 +702,10 @@
|
||||
| test.py:17:1:17:14 | ControlFlowNode for FunctionExpr | test.py:17:5:17:10 | GSSA Variable SINK_F |
|
||||
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:17:1:17:14 | GSSA Variable is_source | test.py:18:8:18:16 | ControlFlowNode for is_source |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for Global Variable SINK_F in Module test |
|
||||
| test.py:17:5:17:10 | ControlFlowNode for SINK_F | test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F |
|
||||
| test.py:17:5:17:10 | ControlFlowNode for SINK_F | test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F |
|
||||
| test.py:17:5:17:10 | GSSA Variable SINK_F | test.py:0:0:0:0 | ModuleVariableNode for test.SINK_F |
|
||||
| test.py:17:12:17:12 | ControlFlowNode for x | test.py:17:12:17:12 | SSA variable x |
|
||||
| test.py:17:12:17:12 | ControlFlowNode for x | test.py:17:12:17:12 | SSA variable x |
|
||||
| test.py:17:12:17:12 | ControlFlowNode for x | test.py:17:12:17:12 | SSA variable x |
|
||||
@@ -722,8 +742,10 @@
|
||||
| test.py:19:34:19:34 | [post arg] ControlFlowNode for x | test.py:42:12:42:18 | [post arg] ControlFlowNode for Attribute |
|
||||
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
|
||||
| test.py:25:1:25:20 | ControlFlowNode for ClassExpr | test.py:25:7:25:11 | GSSA Variable MyObj |
|
||||
| test.py:25:7:25:11 | GSSA Variable MyObj | test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test |
|
||||
| test.py:25:7:25:11 | GSSA Variable MyObj | test.py:0:0:0:0 | ModuleVariableNode for Global Variable MyObj in Module test |
|
||||
| test.py:25:7:25:11 | ControlFlowNode for MyObj | test.py:0:0:0:0 | ModuleVariableNode for test.MyObj |
|
||||
| test.py:25:7:25:11 | ControlFlowNode for MyObj | test.py:0:0:0:0 | ModuleVariableNode for test.MyObj |
|
||||
| test.py:25:7:25:11 | GSSA Variable MyObj | test.py:0:0:0:0 | ModuleVariableNode for test.MyObj |
|
||||
| test.py:25:7:25:11 | GSSA Variable MyObj | test.py:0:0:0:0 | ModuleVariableNode for test.MyObj |
|
||||
| test.py:25:13:25:18 | ControlFlowNode for object | test.py:33:17:33:22 | ControlFlowNode for object |
|
||||
| test.py:25:13:25:18 | ControlFlowNode for object | test.py:33:17:33:22 | ControlFlowNode for object |
|
||||
| test.py:26:5:26:28 | ControlFlowNode for FunctionExpr | test.py:26:9:26:16 | SSA variable __init__ |
|
||||
@@ -805,8 +827,10 @@
|
||||
| test.py:30:20:30:22 | ControlFlowNode for foo | test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] |
|
||||
| test.py:33:1:33:24 | ControlFlowNode for ClassExpr | test.py:33:7:33:15 | GSSA Variable NestedObj |
|
||||
| test.py:33:1:33:24 | ControlFlowNode for ClassExpr | test.py:33:7:33:15 | GSSA Variable NestedObj |
|
||||
| test.py:33:7:33:15 | GSSA Variable NestedObj | test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test |
|
||||
| test.py:33:7:33:15 | GSSA Variable NestedObj | test.py:0:0:0:0 | ModuleVariableNode for Global Variable NestedObj in Module test |
|
||||
| test.py:33:7:33:15 | ControlFlowNode for NestedObj | test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj |
|
||||
| test.py:33:7:33:15 | ControlFlowNode for NestedObj | test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj |
|
||||
| test.py:33:7:33:15 | GSSA Variable NestedObj | test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj |
|
||||
| test.py:33:7:33:15 | GSSA Variable NestedObj | test.py:0:0:0:0 | ModuleVariableNode for test.NestedObj |
|
||||
| test.py:34:5:34:23 | ControlFlowNode for FunctionExpr | test.py:34:9:34:16 | SSA variable __init__ |
|
||||
| test.py:34:5:34:23 | ControlFlowNode for FunctionExpr | test.py:34:9:34:16 | SSA variable __init__ |
|
||||
| test.py:34:5:34:23 | GSSA Variable MyObj | test.py:35:20:35:24 | ControlFlowNode for MyObj |
|
||||
@@ -865,8 +889,10 @@
|
||||
| test.py:41:1:41:19 | ControlFlowNode for FunctionExpr | test.py:41:5:41:10 | GSSA Variable setFoo |
|
||||
| test.py:41:1:41:19 | GSSA Variable SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:41:1:41:19 | GSSA Variable SINK_F | test.py:42:5:42:10 | ControlFlowNode for SINK_F |
|
||||
| test.py:41:5:41:10 | GSSA Variable setFoo | test.py:0:0:0:0 | ModuleVariableNode for Global Variable setFoo in Module test |
|
||||
| test.py:41:5:41:10 | GSSA Variable setFoo | test.py:0:0:0:0 | ModuleVariableNode for Global Variable setFoo in Module test |
|
||||
| test.py:41:5:41:10 | ControlFlowNode for setFoo | test.py:0:0:0:0 | ModuleVariableNode for test.setFoo |
|
||||
| test.py:41:5:41:10 | ControlFlowNode for setFoo | test.py:0:0:0:0 | ModuleVariableNode for test.setFoo |
|
||||
| test.py:41:5:41:10 | GSSA Variable setFoo | test.py:0:0:0:0 | ModuleVariableNode for test.setFoo |
|
||||
| test.py:41:5:41:10 | GSSA Variable setFoo | test.py:0:0:0:0 | ModuleVariableNode for test.setFoo |
|
||||
| test.py:41:12:41:14 | ControlFlowNode for obj | test.py:41:12:41:14 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | ControlFlowNode for obj | test.py:41:12:41:14 | SSA variable obj |
|
||||
| test.py:41:12:41:14 | ControlFlowNode for obj | test.py:41:12:41:14 | SSA variable obj |
|
||||
@@ -1191,8 +1217,10 @@
|
||||
| test.py:90:1:90:30 | ControlFlowNode for FunctionExpr | test.py:90:5:90:26 | GSSA Variable fields_with_local_flow |
|
||||
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:90:1:90:30 | GSSA Variable MyObj | test.py:91:11:91:15 | ControlFlowNode for MyObj |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for Global Variable fields_with_local_flow in Module test |
|
||||
| test.py:90:5:90:26 | ControlFlowNode for fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow |
|
||||
| test.py:90:5:90:26 | ControlFlowNode for fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow |
|
||||
| test.py:90:5:90:26 | GSSA Variable fields_with_local_flow | test.py:0:0:0:0 | ModuleVariableNode for test.fields_with_local_flow |
|
||||
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:90:28:90:28 | SSA variable x |
|
||||
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:90:28:90:28 | SSA variable x |
|
||||
| test.py:90:28:90:28 | ControlFlowNode for x | test.py:90:28:90:28 | SSA variable x |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
foo = 3
|
||||
@@ -0,0 +1,36 @@
|
||||
// This query should be more focused yet.
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.FlowTest
|
||||
private import semmle.python.dataflow.new.internal.PrintNode
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DP
|
||||
|
||||
class ImportTimeLocalFlowTest extends FlowTest {
|
||||
ImportTimeLocalFlowTest() { this = "ImportTimeLocalFlowTest" }
|
||||
|
||||
override string flowTag() { result = "importTimeFlow" }
|
||||
|
||||
override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and
|
||||
// results are displayed next to `nodeTo`, so we need a line to write on
|
||||
nodeTo.getLocation().getStartLine() > 0 and
|
||||
nodeTo.asVar() instanceof GlobalSsaVariable and
|
||||
DP::importTimeLocalFlowStep(nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
class RuntimeLocalFlowTest extends FlowTest {
|
||||
RuntimeLocalFlowTest() { this = "RuntimeLocalFlowTest" }
|
||||
|
||||
override string flowTag() { result = "runtimeFlow" }
|
||||
|
||||
override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and
|
||||
// results are displayed next to `nodeTo`, so we need a line to write on
|
||||
nodeTo.getLocation().getStartLine() > 0 and
|
||||
(
|
||||
nodeFrom instanceof DataFlow::ModuleVariableNode or
|
||||
nodeTo instanceof DataFlow::ModuleVariableNode
|
||||
) and
|
||||
DP::runtimeJumpStep(nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# constant
|
||||
foo = 42
|
||||
|
||||
import base
|
||||
|
||||
def passOn(x):
|
||||
return x
|
||||
|
||||
# depends on other constant
|
||||
bar = passOn(base.foo)
|
||||
@@ -0,0 +1,42 @@
|
||||
import sys #$ importTimeFlow="ImportExpr -> GSSA Variable sys"
|
||||
import os #$ importTimeFlow="ImportExpr -> GSSA Variable os"
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
||||
from testlib import *
|
||||
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source" #$ importTimeFlow="'not a source' -> GSSA Variable NONSOURCE"
|
||||
SOURCE = "source" #$ importTimeFlow="'source' -> GSSA Variable SOURCE"
|
||||
|
||||
|
||||
def is_source(x): #$ importTimeFlow="FunctionExpr -> GSSA Variable is_source"
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
|
||||
def SINK(x): #$ importTimeFlow="FunctionExpr -> GSSA Variable SINK"
|
||||
if is_source(x): #$ runtimeFlow="ModuleVariableNode for multiphase.is_source, l:-17 -> is_source"
|
||||
print("OK") #$ runtimeFlow="ModuleVariableNode for multiphase.print, l:-18 -> print"
|
||||
else:
|
||||
print("Unexpected flow", x) #$ runtimeFlow="ModuleVariableNode for multiphase.print, l:-20 -> print"
|
||||
|
||||
|
||||
def SINK_F(x): #$ importTimeFlow="FunctionExpr -> GSSA Variable SINK_F"
|
||||
if is_source(x): #$ runtimeFlow="ModuleVariableNode for multiphase.is_source, l:-24 -> is_source"
|
||||
print("Unexpected flow", x) #$ runtimeFlow="ModuleVariableNode for multiphase.print, l:-25 -> print"
|
||||
else:
|
||||
print("OK") #$ runtimeFlow="ModuleVariableNode for multiphase.print, l:-27 -> print"
|
||||
|
||||
def set_foo(): #$ importTimeFlow="FunctionExpr -> GSSA Variable set_foo"
|
||||
global foo
|
||||
foo = SOURCE #$ runtimeFlow="ModuleVariableNode for multiphase.SOURCE, l:-31 -> SOURCE" # missing final definition of foo
|
||||
|
||||
foo = NONSOURCE #$ importTimeFlow="NONSOURCE -> GSSA Variable foo"
|
||||
set_foo()
|
||||
|
||||
@expects(2)
|
||||
def test_phases(): #$ importTimeFlow="expects(..)(..), l:-1 -> GSSA Variable test_phases"
|
||||
global foo
|
||||
SINK(foo) #$ runtimeFlow="ModuleVariableNode for multiphase.SINK, l:-39 -> SINK" runtimeFlow="ModuleVariableNode for multiphase.foo, l:-39 -> foo"
|
||||
foo = NONSOURCE #$ runtimeFlow="ModuleVariableNode for multiphase.NONSOURCE, l:-40 -> NONSOURCE"
|
||||
set_foo() #$ runtimeFlow="ModuleVariableNode for multiphase.set_foo, l:-41 -> set_foo"
|
||||
SINK(foo) #$ runtimeFlow="ModuleVariableNode for multiphase.SINK, l:-42 -> SINK" runtimeFlow="ModuleVariableNode for multiphase.foo, l:-42 -> foo"
|
||||
@@ -0,0 +1,33 @@
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source"
|
||||
SOURCE = "source"
|
||||
|
||||
|
||||
def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
|
||||
def SINK(x):
|
||||
if is_source(x):
|
||||
print("OK")
|
||||
else:
|
||||
print("Unexpected flow", x)
|
||||
|
||||
|
||||
def SINK_F(x):
|
||||
if is_source(x):
|
||||
print("Unexpected flow", x)
|
||||
else:
|
||||
print("OK")
|
||||
|
||||
import base
|
||||
|
||||
base.foo = 42
|
||||
|
||||
import m1
|
||||
|
||||
def test_const():
|
||||
SINK(m1.foo)
|
||||
|
||||
def test_overwritten():
|
||||
SINK(m1.bar)
|
||||
@@ -0,0 +1,33 @@
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source"
|
||||
SOURCE = "source"
|
||||
|
||||
|
||||
def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
|
||||
def SINK(x):
|
||||
if is_source(x):
|
||||
print("OK")
|
||||
else:
|
||||
print("Unexpected flow", x)
|
||||
|
||||
|
||||
def SINK_F(x):
|
||||
if is_source(x):
|
||||
print("Unexpected flow", x)
|
||||
else:
|
||||
print("OK")
|
||||
|
||||
import m1
|
||||
|
||||
import base
|
||||
|
||||
base.foo = 42
|
||||
|
||||
def test_const():
|
||||
SINK(m1.foo)
|
||||
|
||||
def test_unoverwritten():
|
||||
SINK_F(m1.bar)
|
||||
@@ -2,5 +2,5 @@ os_import
|
||||
| test.py:2:8:2:9 | GSSA Variable os |
|
||||
flowstep
|
||||
jumpStep
|
||||
| test.py:2:8:2:9 | GSSA Variable os | test.py:0:0:0:0 | ModuleVariableNode for Global Variable os in Module test |
|
||||
| test.py:2:8:2:9 | GSSA Variable os | test.py:0:0:0:0 | ModuleVariableNode for test.os |
|
||||
essaFlowStep
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module_tracker
|
||||
| import_as_attr.py:1:6:1:11 | ControlFlowNode for ImportExpr |
|
||||
module_attr_tracker
|
||||
| import_as_attr.py:0:0:0:0 | ModuleVariableNode for Global Variable attr_ref in Module import_as_attr |
|
||||
| import_as_attr.py:0:0:0:0 | ModuleVariableNode for import_as_attr.attr_ref |
|
||||
| import_as_attr.py:1:20:1:35 | ControlFlowNode for ImportMember |
|
||||
| import_as_attr.py:1:28:1:35 | GSSA Variable attr_ref |
|
||||
| import_as_attr.py:3:1:3:1 | GSSA Variable x |
|
||||
|
||||
@@ -56,3 +56,7 @@ if __name__ == "__main__":
|
||||
check_tests_valid("variable-capture.in")
|
||||
check_tests_valid("variable-capture.nonlocal")
|
||||
check_tests_valid("variable-capture.dict")
|
||||
check_tests_valid("module-initialization.multiphase")
|
||||
# The below fails when trying to import modules
|
||||
# check_tests_valid("module-initialization.test")
|
||||
# check_tests_valid("module-initialization.testOnce")
|
||||
|
||||
@@ -96,7 +96,7 @@ class EncodingTest extends InlineExpectationsTest {
|
||||
class LoggingTest extends InlineExpectationsTest {
|
||||
LoggingTest() { this = "LoggingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["loggingInput"] }
|
||||
override string getARelevantTag() { result = "loggingInput" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
@@ -181,7 +181,7 @@ class EscapingTest extends InlineExpectationsTest {
|
||||
class HttpServerRouteSetupTest extends InlineExpectationsTest {
|
||||
HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["routeSetup"] }
|
||||
override string getARelevantTag() { result = "routeSetup" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
edges
|
||||
| django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header |
|
||||
| django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:19:18:19:24 | ControlFlowNode for request | flask_bad.py:19:18:19:29 | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:19:18:19:29 | ControlFlowNode for Attribute | flask_bad.py:19:18:19:43 | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:19:18:19:43 | ControlFlowNode for Subscript | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:27:18:27:24 | ControlFlowNode for request | flask_bad.py:27:18:27:29 | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:27:18:27:29 | ControlFlowNode for Attribute | flask_bad.py:27:18:27:43 | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:27:18:27:43 | ControlFlowNode for Subscript | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:35:18:35:24 | ControlFlowNode for request | flask_bad.py:35:18:35:29 | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:35:18:35:29 | ControlFlowNode for Attribute | flask_bad.py:35:18:35:43 | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:35:18:35:43 | ControlFlowNode for Subscript | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:44:44:44:50 | ControlFlowNode for request | flask_bad.py:44:44:44:55 | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:44:44:44:55 | ControlFlowNode for Attribute | flask_bad.py:44:44:44:69 | ControlFlowNode for Subscript |
|
||||
nodes
|
||||
| django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:19:18:19:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| flask_bad.py:19:18:19:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:19:18:19:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:27:18:27:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| flask_bad.py:27:18:27:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:27:18:27:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:35:18:35:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| flask_bad.py:35:18:35:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:35:18:35:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header |
|
||||
| flask_bad.py:44:44:44:50 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| flask_bad.py:44:44:44:55 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| flask_bad.py:44:44:44:69 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
subpaths
|
||||
#select
|
||||
| django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | This | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | user-provided value |
|
||||
| django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | This | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | user-provided value |
|
||||
| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | This | flask_bad.py:9:18:9:24 | ControlFlowNode for request | user-provided value |
|
||||
| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | flask_bad.py:19:18:19:24 | ControlFlowNode for request | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | This | flask_bad.py:19:18:19:24 | ControlFlowNode for request | user-provided value |
|
||||
| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | flask_bad.py:27:18:27:24 | ControlFlowNode for request | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | This | flask_bad.py:27:18:27:24 | ControlFlowNode for request | user-provided value |
|
||||
| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | flask_bad.py:35:18:35:24 | ControlFlowNode for request | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | This | flask_bad.py:35:18:35:24 | ControlFlowNode for request | user-provided value |
|
||||
| flask_bad.py:44:44:44:69 | ControlFlowNode for Subscript | flask_bad.py:44:44:44:50 | ControlFlowNode for request | flask_bad.py:44:44:44:69 | ControlFlowNode for Subscript | $@ HTTP header is constructed from a $@. | flask_bad.py:44:44:44:69 | ControlFlowNode for Subscript | This | flask_bad.py:44:44:44:50 | ControlFlowNode for request | user-provided value |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE-113/HeaderInjection.ql
|
||||
@@ -0,0 +1,15 @@
|
||||
import django.http
|
||||
|
||||
|
||||
def django_setitem():
|
||||
rfs_header = django.http.request.GET.get("rfs_header")
|
||||
response = django.http.HttpResponse()
|
||||
response.__setitem__('HeaderName', rfs_header)
|
||||
return response
|
||||
|
||||
|
||||
def django_response():
|
||||
rfs_header = django.http.request.GET.get("rfs_header")
|
||||
response = django.http.HttpResponse()
|
||||
response['HeaderName'] = rfs_header
|
||||
return response
|
||||
@@ -0,0 +1,47 @@
|
||||
from flask import Response, request, Flask, make_response
|
||||
from werkzeug.datastructures import Headers
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/werkzeug_headers')
|
||||
def werkzeug_headers():
|
||||
rfs_header = request.args["rfs_header"]
|
||||
response = Response()
|
||||
headers = Headers()
|
||||
headers.add("HeaderName", rfs_header)
|
||||
response.headers = headers
|
||||
return response
|
||||
|
||||
|
||||
@app.route("/flask_Response")
|
||||
def flask_Response():
|
||||
rfs_header = request.args["rfs_header"]
|
||||
response = Response()
|
||||
response.headers['HeaderName'] = rfs_header
|
||||
return response
|
||||
|
||||
|
||||
@app.route("/flask_make_response")
|
||||
def flask_make_response():
|
||||
rfs_header = request.args["rfs_header"]
|
||||
resp = make_response("hello")
|
||||
resp.headers['HeaderName'] = rfs_header
|
||||
return resp
|
||||
|
||||
|
||||
@app.route("/flask_make_response_extend")
|
||||
def flask_make_response_extend():
|
||||
rfs_header = request.args["rfs_header"]
|
||||
resp = make_response("hello")
|
||||
resp.headers.extend(
|
||||
{'HeaderName': rfs_header})
|
||||
return resp
|
||||
|
||||
|
||||
@app.route("/Response_arg")
|
||||
def Response_arg():
|
||||
return Response(headers={'HeaderName': request.args["rfs_header"]})
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# app.run(debug=True)
|
||||
@@ -0,0 +1,28 @@
|
||||
edges
|
||||
| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr |
|
||||
nodes
|
||||
| LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| LogInjectionBad.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| LogInjectionBad.py:23:12:23:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| LogInjectionBad.py:29:12:29:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| LogInjectionBad.py:35:12:35:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
subpaths
|
||||
#select
|
||||
| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | $@ flows to log entry. | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | User-provided value |
|
||||
| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | $@ flows to log entry. | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | User-provided value |
|
||||
| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | $@ flows to log entry. | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | User-provided value |
|
||||
| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | $@ flows to log entry. | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | User-provided value |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE-117/LogInjection.ql
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :Log Injection
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from django.utils.log import request_logger
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/bad1')
|
||||
def bad1():
|
||||
name = request.args.get('name')
|
||||
app.logger.info('User name: ' + name) # Bad
|
||||
return 'bad1'
|
||||
|
||||
@app.route('/bad2')
|
||||
def bad2():
|
||||
name = request.args.get('name')
|
||||
logging.info('User name: ' + name) # Bad
|
||||
return 'bad2'
|
||||
|
||||
@app.route('/bad3')
|
||||
def bad3():
|
||||
name = request.args.get('name')
|
||||
request_logger.warn('User name: ' + name) # Bad
|
||||
return 'bad3'
|
||||
|
||||
@app.route('/bad4')
|
||||
def bad4():
|
||||
name = request.args.get('name')
|
||||
logtest = logging.getLogger('test')
|
||||
logtest.debug('User name: ' + name) # Bad
|
||||
return 'bad4'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
handler = logging.FileHandler('log')
|
||||
app.logger.addHandler(handler)
|
||||
app.run()
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :Log Injection
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/good1')
|
||||
def good1():
|
||||
name = request.args.get('name')
|
||||
name = name.replace('\r\n','').replace('\n','')
|
||||
logging.info('User name: ' + name) # Good
|
||||
return 'good1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
handler = logging.FileHandler('log')
|
||||
app.logger.addHandler(handler)
|
||||
app.run()
|
||||
@@ -0,0 +1,16 @@
|
||||
edges
|
||||
| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip |
|
||||
| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip |
|
||||
| tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip |
|
||||
nodes
|
||||
| flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip |
|
||||
| flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip |
|
||||
| tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | semmle.label | ControlFlowNode for client_ip |
|
||||
subpaths
|
||||
#select
|
||||
| flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | flask_bad.py:14:12:14:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:13:17:13:54 | ControlFlowNode for Attribute() | this user input |
|
||||
| flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | flask_bad.py:21:12:21:20 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | flask_bad.py:20:17:20:54 | ControlFlowNode for Attribute() | this user input |
|
||||
| tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | tornado_bad.py:23:16:23:24 | ControlFlowNode for client_ip | IP address spoofing might include code from $@. | tornado_bad.py:22:25:22:69 | ControlFlowNode for Attribute() | this user input |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :ip address spoofing
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/bad1')
|
||||
def bad1():
|
||||
client_ip = request.headers.get('x-forwarded-for')
|
||||
if not client_ip.startswith('192.168.'):
|
||||
raise Exception('ip illegal')
|
||||
return 'bad1'
|
||||
|
||||
@app.route('/bad2')
|
||||
def bad2():
|
||||
client_ip = request.headers.get('x-forwarded-for')
|
||||
if not client_ip == '127.0.0.1':
|
||||
raise Exception('ip illegal')
|
||||
return 'bad2'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
app.run()
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :ip address spoofing
|
||||
"""
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/good1')
|
||||
def good1():
|
||||
client_ip = request.headers.get('x-forwarded-for')
|
||||
client_ip = client_ip.split(',')[len(client_ip.split(',')) - 1]
|
||||
if not client_ip == '127.0.0.1':
|
||||
raise Exception('ip illegal')
|
||||
return 'good1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.debug = True
|
||||
app.run()
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""
|
||||
@Desc :ip address spoofing
|
||||
"""
|
||||
import tornado.httpserver
|
||||
import tornado.options
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
|
||||
from tornado.options import define, options
|
||||
|
||||
define("port", default=8000, help="run on the given port,default 8000", type=int)
|
||||
|
||||
|
||||
class IndexHandler(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
client_ip = self.request.headers.get('x-forwarded-for')
|
||||
if client_ip:
|
||||
client_ip = client_ip.split(',')[len(client_ip.split(',')) - 1]
|
||||
else:
|
||||
client_ip = self.request.headers.get('REMOTE_ADDR', None)
|
||||
if not client_ip == '127.0.0.1':
|
||||
raise Exception('ip illegal')
|
||||
self.write("hello.")
|
||||
|
||||
handlers = [(r"/", IndexHandler)]
|
||||
|
||||
if __name__ == "__main__":
|
||||
tornado.options.parse_command_line()
|
||||
app = tornado.web.Application(
|
||||
handlers
|
||||
)
|
||||
http_server = tornado.httpserver.HTTPServer(app)
|
||||
http_server.listen(options.port)
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE-730/RegexInjection.ql
|
||||
@@ -3,11 +3,5 @@ import python
|
||||
from Value val, string name
|
||||
where
|
||||
val = Value::named(name) and
|
||||
(
|
||||
name = "bool" or
|
||||
name = "sys" or
|
||||
name = "sys.argv" or
|
||||
name = "ValueError" or
|
||||
name = "slice"
|
||||
)
|
||||
name in ["bool", "sys", "sys.argv", "ValueError", "slice"]
|
||||
select val, name
|
||||
|
||||
@@ -11,7 +11,7 @@ class HasTypeFact extends CustomPointsToOriginFact {
|
||||
exists(FunctionObject func, string name |
|
||||
func.getACall() = this and
|
||||
name = func.getName() and
|
||||
name.prefix("has_type_".length()) = "has_type_"
|
||||
name.matches("has\\_type\\_%")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class HasTypeFact extends CustomPointsToOriginFact {
|
||||
exists(FunctionObject func, string name |
|
||||
func.getACall() = this and
|
||||
name = func.getName() and
|
||||
name.prefix("has_type_".length()) = "has_type_"
|
||||
name.matches("has\\_type\\_%")
|
||||
|
|
||||
cls.getName() = name.suffix("has_type_".length())
|
||||
) and
|
||||
|
||||
@@ -104,7 +104,7 @@ predicate ssa_consistency(string clsname, string problem, string what) {
|
||||
or
|
||||
exists(EssaDefinition def |
|
||||
clsname = def.getAQlClass() and
|
||||
clsname.prefix(4) = "Essa" and
|
||||
clsname.matches("Essa%") and
|
||||
what = " at " + def.getLocation() and
|
||||
problem = "not covered by Python-specific subclass."
|
||||
)
|
||||
|
||||
10
python/ql/test/library-tests/frameworks/crypto/test_sha3.py
Normal file
10
python/ql/test/library-tests/frameworks/crypto/test_sha3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from Crypto.Hash import SHA3_224
|
||||
|
||||
hasher = SHA3_224.new(b"secret message") # $ CryptographicOperation CryptographicOperationInput=b"secret message" CryptographicOperationAlgorithm=SHA3224
|
||||
print(hasher.hexdigest())
|
||||
|
||||
|
||||
hasher = SHA3_224.new() # $ CryptographicOperation CryptographicOperationAlgorithm=SHA3224
|
||||
hasher.update(b"secret") # $ CryptographicOperation CryptographicOperationInput=b"secret" CryptographicOperationAlgorithm=SHA3224
|
||||
hasher.update(b" message") # $ CryptographicOperation CryptographicOperationInput=b" message" CryptographicOperationAlgorithm=SHA3224
|
||||
print(hasher.hexdigest())
|
||||
@@ -0,0 +1,10 @@
|
||||
from Cryptodome.Hash import SHA3_224
|
||||
|
||||
hasher = SHA3_224.new(b"secret message") # $ CryptographicOperation CryptographicOperationInput=b"secret message" CryptographicOperationAlgorithm=SHA3224
|
||||
print(hasher.hexdigest())
|
||||
|
||||
|
||||
hasher = SHA3_224.new() # $ CryptographicOperation CryptographicOperationAlgorithm=SHA3224
|
||||
hasher.update(b"secret") # $ CryptographicOperation CryptographicOperationInput=b"secret" CryptographicOperationAlgorithm=SHA3224
|
||||
hasher.update(b" message") # $ CryptographicOperation CryptographicOperationInput=b" message" CryptographicOperationAlgorithm=SHA3224
|
||||
print(hasher.hexdigest())
|
||||
@@ -1,3 +1,6 @@
|
||||
import dill
|
||||
|
||||
dill.loads(payload) # $decodeInput=payload decodeOutput=dill.loads(..) decodeFormat=dill decodeMayExecuteInput
|
||||
dill.load(file_) # $ decodeInput=file_ decodeOutput=dill.load(..) decodeFormat=dill decodeMayExecuteInput
|
||||
dill.load(file=file_) # $ decodeInput=file_ decodeOutput=dill.load(..) decodeFormat=dill decodeMayExecuteInput
|
||||
dill.loads(payload) # $ decodeInput=payload decodeOutput=dill.loads(..) decodeFormat=dill decodeMayExecuteInput
|
||||
dill.loads(str=payload) # $ decodeInput=payload decodeOutput=dill.loads(..) decodeFormat=dill decodeMayExecuteInput
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,33 @@
|
||||
import ruamel.yaml
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
ruamel.yaml.load(stream=payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
ruamel.yaml.load(payload, ruamel.yaml.Loader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, Loader=ruamel.yaml.SafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, ruamel.yaml.BaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.safe_load(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load(..) decodeFormat=YAML
|
||||
|
||||
################################################################################
|
||||
# load_all variants
|
||||
################################################################################
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.load_all(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.safe_load_all(payload) # $ decodeInput=payload decodeOutput=ruamel.yaml.safe_load_all(..) decodeFormat=YAML
|
||||
|
||||
################################################################################
|
||||
# C-based loaders with `libyaml`
|
||||
################################################################################
|
||||
|
||||
# Unsafe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
# Safe:
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CSafeLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
ruamel.yaml.load(payload, ruamel.yaml.CBaseLoader) # $ decodeInput=payload decodeOutput=ruamel.yaml.load(..) decodeFormat=YAML
|
||||
63
python/ql/test/library-tests/frameworks/ruamel.yaml/PoC
Normal file
63
python/ql/test/library-tests/frameworks/ruamel.yaml/PoC
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
|
||||
# doesn't have to be annotated
|
||||
|
||||
# This file is just a Proof of Concept for how code execution can be triggered.
|
||||
|
||||
import os
|
||||
import ruamel.yaml
|
||||
|
||||
class Exploit(object):
|
||||
def __reduce__(self):
|
||||
return (os.system, ('ls',))
|
||||
|
||||
data = Exploit()
|
||||
serialized_data = ruamel.yaml.dump(data)
|
||||
|
||||
# All these will execute `ls`
|
||||
print("!!! ruamel.yaml.load")
|
||||
ruamel.yaml.load(serialized_data)
|
||||
|
||||
print("!!! ruamel.yaml.load kwarg")
|
||||
ruamel.yaml.load(stream=serialized_data)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.Loader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.Loader)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.UnsafeLoader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.UnsafeLoader)
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CLoader")
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.CLoader)
|
||||
|
||||
# you need to iterate through the result for it to execute... but it still works
|
||||
print("!!! ruamel.yaml.load_all")
|
||||
for _ in ruamel.yaml.load_all(serialized_data):
|
||||
pass
|
||||
|
||||
# check that the safe version is actually safe
|
||||
print("\n" + "-"*80)
|
||||
print("safe versions")
|
||||
print("-" * 80)
|
||||
|
||||
print("!!! ruamel.yaml.safe_load")
|
||||
try:
|
||||
ruamel.yaml.safe_load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.SafeLoader")
|
||||
try:
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.SafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! ruamel.yaml.load with Loader=ruamel.yaml.CSafeLoader")
|
||||
try:
|
||||
ruamel.yaml.load(serialized_data, ruamel.yaml.CSafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except ruamel.yaml.constructor.ConstructorError:
|
||||
pass
|
||||
@@ -1,10 +1,31 @@
|
||||
import pickle
|
||||
import marshal
|
||||
import shelve
|
||||
import base64
|
||||
|
||||
pickle.load(file_) # $ decodeInput=file_ decodeOutput=pickle.load(..) decodeFormat=pickle decodeMayExecuteInput
|
||||
pickle.load(file=file_) # $ decodeInput=file_ decodeOutput=pickle.load(..) decodeFormat=pickle decodeMayExecuteInput
|
||||
pickle.loads(payload) # $ decodeInput=payload decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput
|
||||
# using this keyword argument is disallowed from Python 3.9
|
||||
pickle.loads(data=payload) # $ decodeInput=payload decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput
|
||||
|
||||
# We don't really have a good way to model a decode happening over multiple statements
|
||||
# like this. Since the important bit for `py/unsafe-deserialization` is the input, that
|
||||
# is the main focus. We do a best effort to model the output though (but that will only
|
||||
# work in local scope).
|
||||
unpickler = pickle.Unpickler(file_) # $ decodeInput=file_ decodeFormat=pickle decodeMayExecuteInput
|
||||
unpickler.load() # $ decodeOutput=unpickler.load()
|
||||
unpickler = pickle.Unpickler(file=file_) # $ decodeInput=file_ decodeFormat=pickle decodeMayExecuteInput
|
||||
|
||||
marshal.load(file_) # $ decodeInput=file_ decodeOutput=marshal.load(..) decodeFormat=marshal decodeMayExecuteInput
|
||||
marshal.loads(payload) # $ decodeInput=payload decodeOutput=marshal.loads(..) decodeFormat=marshal decodeMayExecuteInput
|
||||
|
||||
|
||||
# if the file opened has been controlled by an attacker, this can lead to code
|
||||
# execution. (underlying file format is pickle)
|
||||
shelve.open(filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath
|
||||
shelve.open(filename=filepath) # $ decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath
|
||||
|
||||
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
|
||||
base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64
|
||||
base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64
|
||||
|
||||
@@ -27,3 +27,10 @@ def through_function(open_file):
|
||||
open_file.write("foo") # $ fileWriteData="foo" getAPathArgument="path"
|
||||
|
||||
through_function(f)
|
||||
|
||||
from os import path
|
||||
path.exists("filepath") # $ getAPathArgument="filepath"
|
||||
path.isfile("filepath") # $ getAPathArgument="filepath"
|
||||
path.isdir("filepath") # $ getAPathArgument="filepath"
|
||||
path.islink("filepath") # $ getAPathArgument="filepath"
|
||||
path.ismount("filepath") # $ getAPathArgument="filepath"
|
||||
|
||||
@@ -2,6 +2,7 @@ import yaml
|
||||
|
||||
# Unsafe:
|
||||
yaml.load(payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
yaml.load(stream=payload) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
yaml.load(payload, yaml.Loader) # $decodeInput=payload decodeOutput=yaml.load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
yaml.unsafe_load(payload) # $ decodeInput=payload decodeOutput=yaml.unsafe_load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
yaml.full_load(payload) # $ decodeInput=payload decodeOutput=yaml.full_load(..) decodeFormat=YAML decodeMayExecuteInput
|
||||
|
||||
58
python/ql/test/library-tests/frameworks/yaml/PoC
Normal file
58
python/ql/test/library-tests/frameworks/yaml/PoC
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# this file doesn't have a .py extension so the extractor doesn't pick it up, so it
|
||||
# doesn't have to be annotated
|
||||
|
||||
# This file is just a Proof of Concept for how code execution can be triggered.
|
||||
|
||||
|
||||
import os
|
||||
import yaml
|
||||
|
||||
class Exploit(object):
|
||||
def __reduce__(self):
|
||||
return (os.system, ('ls',))
|
||||
|
||||
data = Exploit()
|
||||
serialized_data = yaml.dump(data)
|
||||
|
||||
# All these will execute `ls`
|
||||
print("!!! yaml.unsafe_load")
|
||||
yaml.unsafe_load(serialized_data)
|
||||
|
||||
print("!!! yaml.unsafe_load kwarg")
|
||||
yaml.unsafe_load(stream=serialized_data)
|
||||
|
||||
print("!!! yaml.load with Loader=yaml.UnsafeLoader")
|
||||
yaml.load(serialized_data, yaml.UnsafeLoader)
|
||||
|
||||
# you need to iterate through the result for it to execute... but it still works
|
||||
print("!!! yaml.unsafe_load_all")
|
||||
for _ in yaml.unsafe_load_all(serialized_data):
|
||||
pass
|
||||
|
||||
# check that the safe version is actually safe
|
||||
print("\n" + "-"*80)
|
||||
print("safe versions")
|
||||
print("-" * 80)
|
||||
|
||||
print("!!! yaml.load")
|
||||
try:
|
||||
yaml.load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! yaml.safe_load")
|
||||
try:
|
||||
yaml.safe_load(serialized_data)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
|
||||
print("!!! yaml.load with Loader=yaml.SafeLoader")
|
||||
try:
|
||||
yaml.load(serialized_data, yaml.SafeLoader)
|
||||
raise Exception("should not happen")
|
||||
except yaml.constructor.ConstructorError:
|
||||
pass
|
||||
@@ -3,19 +3,7 @@ import python
|
||||
from Object o, string name
|
||||
where
|
||||
o.hasLongName(name) and
|
||||
(
|
||||
name = "sys.modules"
|
||||
or
|
||||
name = "test.n"
|
||||
or
|
||||
name = "test.l"
|
||||
or
|
||||
name = "test.d"
|
||||
or
|
||||
name = "test.C.meth"
|
||||
or
|
||||
name = "test.C.cmeth"
|
||||
or
|
||||
name = "test.C.smeth"
|
||||
)
|
||||
name in [
|
||||
"sys.modules", "test.n", "test.l", "test.d", "test.C.meth", "test.C.cmeth", "test.C.smeth"
|
||||
]
|
||||
select name, o.toString()
|
||||
|
||||
@@ -28,7 +28,7 @@ class SimpleSource extends TaintSource {
|
||||
|
||||
predicate visit_call(CallNode call, FunctionObject func) {
|
||||
exists(AttrNode attr, ClassObject cls, string name |
|
||||
name.prefix(6) = "visit_" and
|
||||
name.matches("visit\\_%") and
|
||||
func = cls.lookupAttribute(name) and
|
||||
attr.getObject("visit").refersTo(_, cls, _) and
|
||||
attr = call.getFunction()
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Diagnostics/ExtractionErrors.ql
|
||||
@@ -1,2 +1,2 @@
|
||||
| bad_encoding.py:2:11:2:11 | Encoding Error | Extraction failed in bad_encoding.py with error 'utf-8' codec can't decode byte 0x9d in position 87: invalid start byte | 2 |
|
||||
| syntax_error.py:1:31:1:31 | Syntax Error | Extraction failed in syntax_error.py with error Syntax Error | 2 |
|
||||
| bad_encoding.py:2:11:2:11 | Encoding Error | Extraction failed in bad_encoding.py with error 'utf-8' codec can't decode byte 0x9d in position 87: invalid start byte | 1 |
|
||||
| syntax_error.py:1:31:1:31 | Syntax Error | Extraction failed in syntax_error.py with error Syntax Error | 1 |
|
||||
@@ -0,0 +1 @@
|
||||
Diagnostics/ExtractionWarnings.ql
|
||||
@@ -1,24 +1,24 @@
|
||||
edges
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptodome | test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptodome | test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptodome | test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_certificate | test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_password | test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_password | test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password |
|
||||
| test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:2:23:2:34 | GSSA Variable get_password |
|
||||
| test_cryptodome.py:2:23:2:34 | GSSA Variable get_password | test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptodome |
|
||||
| test_cryptodome.py:2:23:2:34 | GSSA Variable get_password | test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_password |
|
||||
| test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | test_cryptodome.py:2:37:2:51 | GSSA Variable get_certificate |
|
||||
| test_cryptodome.py:2:37:2:51 | GSSA Variable get_certificate | test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptodome |
|
||||
| test_cryptodome.py:2:37:2:51 | GSSA Variable get_certificate | test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_certificate |
|
||||
| test_cryptodome.py:6:17:6:31 | ControlFlowNode for get_certificate | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password | test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptodome.py:13:17:13:30 | ControlFlowNode for get_password() | test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password | test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptography | test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptography | test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptography | test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_certificate | test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_password | test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_password | test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password |
|
||||
| test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:3:23:3:34 | GSSA Variable get_password |
|
||||
| test_cryptography.py:3:23:3:34 | GSSA Variable get_password | test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptography |
|
||||
| test_cryptography.py:3:23:3:34 | GSSA Variable get_password | test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_password |
|
||||
| test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | test_cryptography.py:3:37:3:51 | GSSA Variable get_certificate |
|
||||
| test_cryptography.py:3:37:3:51 | GSSA Variable get_certificate | test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptography |
|
||||
| test_cryptography.py:3:37:3:51 | GSSA Variable get_certificate | test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_certificate |
|
||||
| test_cryptography.py:7:17:7:31 | ControlFlowNode for get_certificate | test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptography.py:7:17:7:33 | ControlFlowNode for get_certificate() | test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptography.py:15:17:15:28 | ControlFlowNode for get_password | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous |
|
||||
@@ -26,8 +26,8 @@ edges
|
||||
| test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous |
|
||||
| test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous |
|
||||
nodes
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptodome | semmle.label | ModuleVariableNode for Global Variable get_certificate in Module test_cryptodome |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptodome | semmle.label | ModuleVariableNode for Global Variable get_password in Module test_cryptodome |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_certificate | semmle.label | ModuleVariableNode for test_cryptodome.get_certificate |
|
||||
| test_cryptodome.py:0:0:0:0 | ModuleVariableNode for test_cryptodome.get_password | semmle.label | ModuleVariableNode for test_cryptodome.get_password |
|
||||
| test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
|
||||
| test_cryptodome.py:2:23:2:34 | GSSA Variable get_password | semmle.label | GSSA Variable get_password |
|
||||
| test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
|
||||
@@ -41,8 +41,8 @@ nodes
|
||||
| test_cryptodome.py:20:17:20:28 | ControlFlowNode for get_password | semmle.label | ControlFlowNode for get_password |
|
||||
| test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | semmle.label | ControlFlowNode for dangerous |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_certificate in Module test_cryptography | semmle.label | ModuleVariableNode for Global Variable get_certificate in Module test_cryptography |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for Global Variable get_password in Module test_cryptography | semmle.label | ModuleVariableNode for Global Variable get_password in Module test_cryptography |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_certificate | semmle.label | ModuleVariableNode for test_cryptography.get_certificate |
|
||||
| test_cryptography.py:0:0:0:0 | ModuleVariableNode for test_cryptography.get_password | semmle.label | ModuleVariableNode for test_cryptography.get_password |
|
||||
| test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
|
||||
| test_cryptography.py:3:23:3:34 | GSSA Variable get_password | semmle.label | GSSA Variable get_password |
|
||||
| test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
|
||||
|
||||
@@ -23,6 +23,6 @@ nodes
|
||||
| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | semmle.label | ControlFlowNode for unsafe_pattern |
|
||||
subpaths
|
||||
#select
|
||||
| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This | re_bad.py:13:22:13:28 | ControlFlowNode for request | user-provided value | re_bad.py:14:5:14:13 | Attribute | re.search |
|
||||
| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:24:22:24:28 | ControlFlowNode for request | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This | re_bad.py:24:22:24:28 | ControlFlowNode for request | user-provided value | re_bad.py:26:5:26:27 | Attribute | re.search |
|
||||
| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:36:22:36:28 | ControlFlowNode for request | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This | re_bad.py:36:22:36:28 | ControlFlowNode for request | user-provided value | re_bad.py:37:5:37:37 | Attribute | re.search |
|
||||
| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This | re_bad.py:13:22:13:28 | ControlFlowNode for request | user-provided value | re_bad.py:14:5:14:33 | ControlFlowNode for Attribute() | re.search |
|
||||
| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:24:22:24:28 | ControlFlowNode for request | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This | re_bad.py:24:22:24:28 | ControlFlowNode for request | user-provided value | re_bad.py:26:5:26:31 | ControlFlowNode for Attribute() | re.search |
|
||||
| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:36:22:36:28 | ControlFlowNode for request | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ regular expression is constructed from a $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This | re_bad.py:36:22:36:28 | ControlFlowNode for request | user-provided value | re_bad.py:37:5:37:41 | ControlFlowNode for Attribute() | re.search |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-730/RegexInjection.ql
|
||||
Reference in New Issue
Block a user