diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected new file mode 100644 index 00000000000..79d760d87f4 --- /dev/null +++ b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected @@ -0,0 +1,3 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +failures diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql new file mode 100644 index 00000000000..f7f84cb8479 --- /dev/null +++ b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ql @@ -0,0 +1,3 @@ +import python +private import TestSummaries +import experimental.meta.InlineTaintTest diff --git a/python/ql/test/experimental/dataflow/model-summaries/dataflow/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/dataflow/NormalDataflowTest.expected rename to python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected diff --git a/python/ql/test/experimental/dataflow/model-summaries/dataflow/NormalDataflowTest.ql b/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql similarity index 100% rename from python/ql/test/experimental/dataflow/model-summaries/dataflow/NormalDataflowTest.ql rename to python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ql diff --git a/python/ql/test/experimental/dataflow/model-summaries/TestSummaries.qll b/python/ql/test/experimental/dataflow/model-summaries/TestSummaries.qll new file mode 100644 index 00000000000..5f1e0a1f90b --- /dev/null +++ b/python/ql/test/experimental/dataflow/model-summaries/TestSummaries.qll @@ -0,0 +1,25 @@ +private import python +private import semmle.python.dataflow.new.FlowSummary +private import semmle.python.frameworks.data.ModelsAsData +private import semmle.python.ApiGraphs + +private class StepsFromModel extends ModelInput::SummaryModelCsv { + override predicate row(string row) { + row = + [ + "foo;Member[MS_identity];Argument[0];ReturnValue;value", + "foo;Member[MS_apply_lambda];Argument[1];Argument[0].Parameter[0];value", + "foo;Member[MS_apply_lambda];Argument[0].ReturnValue;ReturnValue;value", + "foo;Member[MS_reversed];Argument[0].ListElement;ReturnValue.ListElement;value", + "foo;Member[MS_reversed];Argument[0];ReturnValue;taint", + "foo;Member[MS_list_map];Argument[1].ListElement;Argument[0].Parameter[0];value", + "foo;Member[MS_list_map];Argument[0].ReturnValue;ReturnValue.ListElement;value", + "foo;Member[MS_list_map];Argument[1];ReturnValue;taint", + "foo;Member[MS_append_to_list];Argument[0].ListElement;ReturnValue.ListElement;value", + "foo;Member[MS_append_to_list];Argument[1];ReturnValue.ListElement;value", + "foo;Member[MS_append_to_list];Argument[0];ReturnValue;taint", + "foo;Member[MS_append_to_list];Argument[1];ReturnValue;taint", + "json;Member[MS_loads];Argument[0];ReturnValue;taint" + ] + } +} diff --git a/python/ql/test/experimental/dataflow/model-summaries/dataflow/TestSummaries.qll b/python/ql/test/experimental/dataflow/model-summaries/dataflow/TestSummaries.qll deleted file mode 100644 index d97702eec41..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/dataflow/TestSummaries.qll +++ /dev/null @@ -1,20 +0,0 @@ -private import python -private import semmle.python.dataflow.new.FlowSummary -private import semmle.python.frameworks.data.ModelsAsData -private import semmle.python.ApiGraphs - -private class StepsFromModel extends ModelInput::SummaryModelCsv { - override predicate row(string row) { - row = - [ - "Foo;Member[MS_identity];Argument[0];ReturnValue;value", - "Foo;Member[MS_apply_lambda];Argument[1];Argument[0].Parameter[0];value", - "Foo;Member[MS_apply_lambda];Argument[0].ReturnValue;ReturnValue;value", - "Foo;Member[MS_reversed];Argument[0].ListElement;ReturnValue.ListElement;value", - "Foo;Member[MS_list_map];Argument[1].ListElement;Argument[0].Parameter[0];value", - "Foo;Member[MS_list_map];Argument[0].ReturnValue;ReturnValue.ListElement;value", - "Foo;Member[MS_append_to_list];Argument[0].ListElement;ReturnValue.ListElement;value", - "Foo;Member[MS_append_to_list];Argument[1];ReturnValue.ListElement;value" - ] - } -} diff --git a/python/ql/test/experimental/dataflow/model-summaries/dataflow/model_summaries.py b/python/ql/test/experimental/dataflow/model-summaries/dataflow/model_summaries.py deleted file mode 100644 index c81fddf44ec..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/dataflow/model_summaries.py +++ /dev/null @@ -1,69 +0,0 @@ - -import sys -import os - -sys.path.append(os.path.dirname(os.path.dirname((__file__)))) -from testlib import expects - -# 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") - - -from Foo import MS_identity, MS_apply_lambda, MS_reversed, MS_list_map, MS_append_to_list - -# Simple summary -tainted = MS_identity(SOURCE) -SINK(tainted) # $ flow="SOURCE, l:-1 -> tainted" - -# Lambda summary -tainted_lambda = MS_apply_lambda(lambda x: [x], SOURCE) -SINK(tainted_lambda[0]) # $ flow="SOURCE, l:-1 -> tainted_lambda[0]" - -# A lambda that breaks the flow -untainted_lambda = MS_apply_lambda(lambda x: 1, SOURCE) -SINK_F(untainted_lambda) - -# Collection summaries -tainted_list = MS_reversed([SOURCE]) -SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" - -# Complex summaries -def box(x): - return [x] - -tainted_mapped = MS_list_map(box, [SOURCE]) -SINK(tainted_mapped[0][0]) # $ flow="SOURCE, l:-1 -> tainted_mapped[0][0]" - -def explicit_identity(x): - return x - -tainted_mapped_explicit = MS_list_map(explicit_identity, [SOURCE]) -SINK(tainted_mapped_explicit[0]) # $ flow="SOURCE, l:-1 -> tainted_mapped_explicit[0]" - -tainted_mapped_summary = MS_list_map(MS_identity, [SOURCE]) -SINK(tainted_mapped_summary[0]) # $ flow="SOURCE, l:-1 -> tainted_mapped_summary[0]" - -tainted_list = MS_append_to_list([], SOURCE) -SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" - -tainted_list = MS_append_to_list([SOURCE], NONSOURCE) -SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" diff --git a/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py b/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py new file mode 100644 index 00000000000..3a98e04ceb7 --- /dev/null +++ b/python/ql/test/experimental/dataflow/model-summaries/model_summaries.py @@ -0,0 +1,128 @@ + +import sys +import os + +sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from testlib import expects + +# 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") + +ensure_tainted = ensure_not_tainted = print +TAINTED_STRING = "TAINTED_STRING" + +from foo import MS_identity, MS_apply_lambda, MS_reversed, MS_list_map, MS_append_to_list + +# Simple summary +via_identity = MS_identity(SOURCE) +SINK(via_identity) # $ flow="SOURCE, l:-1 -> via_identity" + +tainted = MS_identity(TAINTED_STRING) +ensure_tainted(tainted) # $ tainted + + +# Lambda summary +via_lambda = MS_apply_lambda(lambda x: [x], SOURCE) +SINK(via_lambda[0]) # $ flow="SOURCE, l:-1 -> via_lambda[0]" + +tainted_lambda = MS_apply_lambda(lambda x: [x], TAINTED_STRING) +ensure_tainted(tainted_lambda) # $ tainted + + +# A lambda that breaks the flow +not_via_lambda = MS_apply_lambda(lambda x: 1, SOURCE) +SINK_F(not_via_lambda) + +untainted_lambda = MS_apply_lambda(lambda x: 1, TAINTED_STRING) +ensure_not_tainted(untainted_lambda) + +# Collection summaries +via_reversed = MS_reversed([SOURCE]) +SINK(via_reversed[0]) # $ flow="SOURCE, l:-1 -> via_reversed[0]" + +tainted_list = MS_reversed([TAINTED_STRING]) +ensure_tainted(tainted_list[0]) # $ tainted + +# Complex summaries +def box(x): + return [x] + +via_map = MS_list_map(box, [SOURCE]) +SINK(via_map[0][0]) # $ flow="SOURCE, l:-1 -> via_map[0][0]" + +tainted_mapped = MS_list_map(box, [TAINTED_STRING]) +ensure_tainted(tainted_mapped[0][0]) # $ tainted + +def explicit_identity(x): + return x + +via_map_explicit = MS_list_map(explicit_identity, [SOURCE]) +SINK(via_map_explicit[0]) # $ flow="SOURCE, l:-1 -> via_map_explicit[0]" + +tainted_mapped_explicit = MS_list_map(explicit_identity, [TAINTED_STRING]) +tainted_mapped_explicit_implicit = MS_list_map(explicit_identity, TAINTED_LIST) +ensure_tainted( + tainted_mapped_explicit, # $ tainted + tainted_mapped_explicit[0], # $ tainted + tainted_mapped_explicit_implicit, # $ tainted + tainted_mapped_explicit_implicit[0] # $ tainted + ) + +via_map_summary = MS_list_map(MS_identity, [SOURCE]) +SINK(via_map_summary[0]) # $ flow="SOURCE, l:-1 -> via_map_summary[0]" + +tainted_mapped_summary = MS_list_map(MS_identity, [TAINTED_STRING]) +tainted_mapped_summary_implicit = MS_list_map(MS_identity, TAINTED_LIST) +ensure_tainted( + tainted_mapped_summary, # $ tainted + tainted_mapped_summary[0], # $ tainted + tainted_mapped_summary_implicit, # $ tainted + tainted_mapped_summary_implicit[0] # $ tainted + ) + +via_append_el = MS_append_to_list([], SOURCE) +SINK(via_append_el[0]) # $ flow="SOURCE, l:-1 -> via_append_el[0]" + +tainted_list_el = MS_append_to_list([], TAINTED_STRING) +ensure_tainted( + tainted_list_el, # $ tainted + tainted_list_el[0] # $ tainted + ) + +via_append = MS_append_to_list([SOURCE], NONSOURCE) +SINK(via_append[0]) # $ flow="SOURCE, l:-1 -> via_append[0]" + +tainted_list = MS_append_to_list([TAINTED_STRING], NONSOURCE) +tainted_list_implicit = MS_append_to_list(TAINTED_LIST, NONSOURCE) +ensure_tainted( + tainted_list, # $ tainted + tainted_list[0], # $ tainted + tainted_list_implicit, # $ tainted + tainted_list_implicit[0] # $ tainted + ) + +from json import MS_loads as json_loads +tainted_resultlist = json_loads(TAINTED_STRING) +ensure_tainted( + tainted_resultlist, # $ tainted + tainted_resultlist[0] # $ tainted + ) diff --git a/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.expected b/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.expected deleted file mode 100644 index 3875da4e143..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.expected +++ /dev/null @@ -1,2 +0,0 @@ -missingAnnotationOnSink -failures diff --git a/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.ql b/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.ql deleted file mode 100644 index afb44b6b2ed..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/taint/NormalTaintTrackingTest.ql +++ /dev/null @@ -1,3 +0,0 @@ -import python -private import TestSummaries -import experimental.dataflow.TestUtil.NormalTaintTrackingTest diff --git a/python/ql/test/experimental/dataflow/model-summaries/taint/TestSummaries.qll b/python/ql/test/experimental/dataflow/model-summaries/taint/TestSummaries.qll deleted file mode 100644 index 57861d3c022..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/taint/TestSummaries.qll +++ /dev/null @@ -1,19 +0,0 @@ -private import python -private import semmle.python.dataflow.new.FlowSummary -private import semmle.python.frameworks.data.ModelsAsData -private import semmle.python.ApiGraphs - -private class StepsFromModel extends ModelInput::SummaryModelCsv { - override predicate row(string row) { - row = - [ - "Foo;Member[MS_identity];Argument[0];ReturnValue;value", - "Foo;Member[MS_apply_lambda];Argument[1];Argument[0].Parameter[0];value", - "Foo;Member[MS_apply_lambda];Argument[0].ReturnValue;ReturnValue;value", - "Foo;Member[MS_reversed];Argument[0];ReturnValue;taint", - "Foo;Member[MS_list_map];Argument[1];ReturnValue;taint", - "Foo;Member[MS_append_to_list];Argument[0];ReturnValue;taint", - "json;Member[MS_loads];Argument[0];ReturnValue;taint" - ] - } -} diff --git a/python/ql/test/experimental/dataflow/model-summaries/taint/model_summaries_taint.py b/python/ql/test/experimental/dataflow/model-summaries/taint/model_summaries_taint.py deleted file mode 100644 index 44ca79c116e..00000000000 --- a/python/ql/test/experimental/dataflow/model-summaries/taint/model_summaries_taint.py +++ /dev/null @@ -1,70 +0,0 @@ - -import sys -import os - -sys.path.append(os.path.dirname(os.path.dirname((__file__)))) -from testlib import expects - -# 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") - - -from Foo import MS_identity, MS_apply_lambda, MS_reversed, MS_list_map, MS_append_to_list - -# Simple summary -tainted = MS_identity(SOURCE) -SINK(tainted) # $ flow="SOURCE, l:-1 -> tainted" - -# Lambda summary -tainted_lambda = MS_apply_lambda(lambda x: x + 1, SOURCE) -SINK(tainted_lambda) # $ flow="SOURCE, l:-1 -> tainted_lambda" - -# A lambda that breaks the flow -untainted_lambda = MS_apply_lambda(lambda x: 1, SOURCE) -SINK_F(untainted_lambda) - -# Collection summaries -tainted_list = MS_reversed([SOURCE]) -SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" - -# Complex summaries -def add_colon(x): - return x + ":" - -tainted_mapped = MS_list_map(add_colon, [SOURCE]) -SINK(tainted_mapped[0]) # $ flow="SOURCE, l:-1 -> tainted_mapped[0]" - -def explicit_identity(x): - return x - -tainted_mapped_explicit = MS_list_map(explicit_identity, [SOURCE]) -SINK(tainted_mapped_explicit[0]) # $ flow="SOURCE, l:-1 -> tainted_mapped_explicit[0]" - -tainted_mapped_summary = MS_list_map(MS_identity, [SOURCE]) -SINK(tainted_mapped_summary[0]) # $ flow="SOURCE, l:-1 -> tainted_mapped_summary[0]" - -tainted_list = MS_append_to_list([SOURCE], NONSOURCE) -SINK(tainted_list[0]) # $ flow="SOURCE, l:-1 -> tainted_list[0]" - -from json import MS_loads as json_loads -tainted_resultlist = json_loads(SOURCE) -SINK(tainted_resultlist[0]) # $ flow="SOURCE, l:-1 -> tainted_resultlist[0]"