diff --git a/python/ql/test/2/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref b/python/ql/test/2/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref index f43176f3d7a8..e2e9a180ab1c 100644 --- a/python/ql/test/2/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref +++ b/python/ql/test/2/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref @@ -1 +1,2 @@ -Classes/InconsistentMRO.ql \ No newline at end of file +query: Classes/InconsistentMRO.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Classes/inconsistent-mro/inconsistent_mro.py b/python/ql/test/2/query-tests/Classes/inconsistent-mro/inconsistent_mro.py index 346778648349..a8e76c6bfb11 100644 --- a/python/ql/test/2/query-tests/Classes/inconsistent-mro/inconsistent_mro.py +++ b/python/ql/test/2/query-tests/Classes/inconsistent-mro/inconsistent_mro.py @@ -6,7 +6,7 @@ class X(object): class Y(X): pass -class Z(X, Y): +class Z(X, Y): # $ Alert pass class O: diff --git a/python/ql/test/2/query-tests/Classes/new-style/PropertyInOldStyleClass.qlref b/python/ql/test/2/query-tests/Classes/new-style/PropertyInOldStyleClass.qlref index 297295c006e6..fa1947665113 100644 --- a/python/ql/test/2/query-tests/Classes/new-style/PropertyInOldStyleClass.qlref +++ b/python/ql/test/2/query-tests/Classes/new-style/PropertyInOldStyleClass.qlref @@ -1 +1,2 @@ -Classes/PropertyInOldStyleClass.ql +query: Classes/PropertyInOldStyleClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Classes/new-style/SlotsInOldStyleClass.qlref b/python/ql/test/2/query-tests/Classes/new-style/SlotsInOldStyleClass.qlref index 62fb3202a16f..688f31402ad0 100644 --- a/python/ql/test/2/query-tests/Classes/new-style/SlotsInOldStyleClass.qlref +++ b/python/ql/test/2/query-tests/Classes/new-style/SlotsInOldStyleClass.qlref @@ -1 +1,2 @@ -Classes/SlotsInOldStyleClass.ql \ No newline at end of file +query: Classes/SlotsInOldStyleClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Classes/new-style/SuperInOldStyleClass.qlref b/python/ql/test/2/query-tests/Classes/new-style/SuperInOldStyleClass.qlref index 08f737893eff..293fc72d86ca 100644 --- a/python/ql/test/2/query-tests/Classes/new-style/SuperInOldStyleClass.qlref +++ b/python/ql/test/2/query-tests/Classes/new-style/SuperInOldStyleClass.qlref @@ -1 +1,2 @@ -Classes/SuperInOldStyleClass.ql \ No newline at end of file +query: Classes/SuperInOldStyleClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Classes/new-style/newstyle_test.py b/python/ql/test/2/query-tests/Classes/new-style/newstyle_test.py index f1e3ea8e42c8..44dce333ef90 100644 --- a/python/ql/test/2/query-tests/Classes/new-style/newstyle_test.py +++ b/python/ql/test/2/query-tests/Classes/new-style/newstyle_test.py @@ -1,7 +1,7 @@ #Only works for Python2 -class OldStyle1: +class OldStyle1: # $ Alert[py/slots-in-old-style-class] __slots__ = [ 'a', 'b' ] @@ -12,7 +12,7 @@ def __init__(self, a, b): class OldStyle2: def __init__(self, x): - super().__init__(x) + super().__init__(x) # $ Alert[py/super-in-old-style] class NewStyle1(object): diff --git a/python/ql/test/2/query-tests/Classes/new-style/property_old_style.py b/python/ql/test/2/query-tests/Classes/new-style/property_old_style.py index 8291feab26c1..0b529d9edb7e 100644 --- a/python/ql/test/2/query-tests/Classes/new-style/property_old_style.py +++ b/python/ql/test/2/query-tests/Classes/new-style/property_old_style.py @@ -5,6 +5,6 @@ class OldStyle: def __init__(self, x): self._x = x - @property + @property # $ Alert[py/property-in-old-style-class] def piosc(self): return self._x \ No newline at end of file diff --git a/python/ql/test/2/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref b/python/ql/test/2/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref index d4986ffc84ce..35f6da7add55 100644 --- a/python/ql/test/2/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref +++ b/python/ql/test/2/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/MaybeUndefinedClassAttribute.ql +query: Classes/MaybeUndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref b/python/ql/test/2/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref index 7ac0a3b18b77..f0e8fb722784 100644 --- a/python/ql/test/2/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref +++ b/python/ql/test/2/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/UndefinedClassAttribute.ql +query: Classes/UndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/CatchingBaseException.qlref b/python/ql/test/2/query-tests/Exceptions/general/CatchingBaseException.qlref index 5588dbf2c7b4..33b4697e7ef7 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/CatchingBaseException.qlref +++ b/python/ql/test/2/query-tests/Exceptions/general/CatchingBaseException.qlref @@ -1 +1,2 @@ -Exceptions/CatchingBaseException.ql \ No newline at end of file +query: Exceptions/CatchingBaseException.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/EmptyExcept.qlref b/python/ql/test/2/query-tests/Exceptions/general/EmptyExcept.qlref index 3f4987046b12..7a046d008cd2 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/EmptyExcept.qlref +++ b/python/ql/test/2/query-tests/Exceptions/general/EmptyExcept.qlref @@ -1 +1,2 @@ -Exceptions/EmptyExcept.ql \ No newline at end of file +query: Exceptions/EmptyExcept.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref b/python/ql/test/2/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref index 6d49710a7599..7a7911ca4403 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref +++ b/python/ql/test/2/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref @@ -1 +1,2 @@ -Exceptions/IllegalExceptionHandlerType.ql \ No newline at end of file +query: Exceptions/IllegalExceptionHandlerType.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/IllegalRaise.qlref b/python/ql/test/2/query-tests/Exceptions/general/IllegalRaise.qlref index 5a515d5656d3..2bee772260a9 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/IllegalRaise.qlref +++ b/python/ql/test/2/query-tests/Exceptions/general/IllegalRaise.qlref @@ -1 +1,2 @@ -Exceptions/IllegalRaise.ql \ No newline at end of file +query: Exceptions/IllegalRaise.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/IncorrectExceptOrder.qlref b/python/ql/test/2/query-tests/Exceptions/general/IncorrectExceptOrder.qlref index bc4c3a070813..f4278558baae 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/IncorrectExceptOrder.qlref +++ b/python/ql/test/2/query-tests/Exceptions/general/IncorrectExceptOrder.qlref @@ -1 +1,2 @@ -Exceptions/IncorrectExceptOrder.ql +query: Exceptions/IncorrectExceptOrder.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/general/exceptions_test.py b/python/ql/test/2/query-tests/Exceptions/general/exceptions_test.py index 6e82bc028906..023b490eaaea 100644 --- a/python/ql/test/2/query-tests/Exceptions/general/exceptions_test.py +++ b/python/ql/test/2/query-tests/Exceptions/general/exceptions_test.py @@ -14,4 +14,4 @@ def raise_tuple(cond): raise (Exception, "bananas", 17) else: #This is an error - raise (17, "bananas", Exception) + raise (17, "bananas", Exception) # $ Alert[py/illegal-raise] diff --git a/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref b/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref index 7fe5d609705b..f174a4a96f57 100644 --- a/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref +++ b/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref @@ -1 +1,2 @@ -Exceptions/UnguardedNextInGenerator.ql \ No newline at end of file +query: Exceptions/UnguardedNextInGenerator.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/generators/test.py b/python/ql/test/2/query-tests/Exceptions/generators/test.py index e8b3f0b2b344..0c5ca29f798a 100644 --- a/python/ql/test/2/query-tests/Exceptions/generators/test.py +++ b/python/ql/test/2/query-tests/Exceptions/generators/test.py @@ -2,12 +2,12 @@ def bad1(it): while True: - yield next(it) + yield next(it) # $ Alert def bad2(seq): it = iter(seq) #Not OK as seq may be empty - raise KeyError(next(it)) + raise KeyError(next(it)) # $ Alert yield 0 def ok1(seq): diff --git a/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.qlref b/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.qlref index 55d1f5e1d4f9..1cefef85d8a5 100644 --- a/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.qlref +++ b/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.qlref @@ -1 +1,2 @@ -Exceptions/RaisingTuple.ql +query: Exceptions/RaisingTuple.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Exceptions/raising/test.py b/python/ql/test/2/query-tests/Exceptions/raising/test.py index ff991f642e2f..1e5f3cb35fca 100644 --- a/python/ql/test/2/query-tests/Exceptions/raising/test.py +++ b/python/ql/test/2/query-tests/Exceptions/raising/test.py @@ -5,11 +5,11 @@ def ok(): def bad1(): ex = Exception, "message" - raise ex + raise ex # $ Alert def bad2(): - raise (Exception, "message") + raise (Exception, "message") # $ Alert def bad3(): ex = Exception, - raise ex, "message" + raise ex, "message" # $ Alert diff --git a/python/ql/test/2/query-tests/Expressions/TruncatedDivision.qlref b/python/ql/test/2/query-tests/Expressions/TruncatedDivision.qlref index fa2c2cbf006c..17d539c32260 100644 --- a/python/ql/test/2/query-tests/Expressions/TruncatedDivision.qlref +++ b/python/ql/test/2/query-tests/Expressions/TruncatedDivision.qlref @@ -1 +1,2 @@ -Expressions/TruncatedDivision.ql +query: Expressions/TruncatedDivision.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Expressions/TruncatedDivision_test.py b/python/ql/test/2/query-tests/Expressions/TruncatedDivision_test.py index 6f265b824fb7..64ef262edb81 100644 --- a/python/ql/test/2/query-tests/Expressions/TruncatedDivision_test.py +++ b/python/ql/test/2/query-tests/Expressions/TruncatedDivision_test.py @@ -62,14 +62,14 @@ def halve(x): # This case is bad, and is a minimal obvious case that should be bad. It # SHOULD be found by the query. -print(3 / 2) +print(3 / 2) # $ Alert[py/truncated-division] # This case is bad. It uses indirect returns of integers through function calls # to produce the problem. I -print(return_three() / return_two()) +print(return_three() / return_two()) # $ Alert[py/truncated-division] diff --git a/python/ql/test/2/query-tests/Expressions/UseofApply.py b/python/ql/test/2/query-tests/Expressions/UseofApply.py index 9109636f99ec..6c2255012e6c 100644 --- a/python/ql/test/2/query-tests/Expressions/UseofApply.py +++ b/python/ql/test/2/query-tests/Expressions/UseofApply.py @@ -16,7 +16,7 @@ def foo(): # This use of `apply` is a reference to the builtin function and so SHOULD be # caught by the query. - apply(foo, [1]) + apply(foo, [1]) # $ Alert[py/use-of-apply] diff --git a/python/ql/test/2/query-tests/Expressions/UseofApply.qlref b/python/ql/test/2/query-tests/Expressions/UseofApply.qlref index abf684e3918a..4add79acdb3c 100644 --- a/python/ql/test/2/query-tests/Expressions/UseofApply.qlref +++ b/python/ql/test/2/query-tests/Expressions/UseofApply.qlref @@ -1 +1,2 @@ -Expressions/UseofApply.ql +query: Expressions/UseofApply.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Expressions/UseofInput.qlref b/python/ql/test/2/query-tests/Expressions/UseofInput.qlref index 3f9590f48b2c..2684126de5ee 100644 --- a/python/ql/test/2/query-tests/Expressions/UseofInput.qlref +++ b/python/ql/test/2/query-tests/Expressions/UseofInput.qlref @@ -1 +1,2 @@ -Expressions/UseofInput.ql \ No newline at end of file +query: Expressions/UseofInput.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Expressions/expressions_test.py b/python/ql/test/2/query-tests/Expressions/expressions_test.py index c31681e35353..6889822b7914 100644 --- a/python/ql/test/2/query-tests/Expressions/expressions_test.py +++ b/python/ql/test/2/query-tests/Expressions/expressions_test.py @@ -1,9 +1,9 @@ def use_of_apply(func, args): - apply(func, args) + apply(func, args) # $ Alert[py/use-of-apply] def use_of_input(): - return input() # NOT OK + return input() # $ Alert[py/use-of-input] # NOT OK def not_use_of_input(): diff --git a/python/ql/test/2/query-tests/Functions/DeprecatedSliceMethod.qlref b/python/ql/test/2/query-tests/Functions/DeprecatedSliceMethod.qlref index c38b8d1f7619..3043411c1ce4 100644 --- a/python/ql/test/2/query-tests/Functions/DeprecatedSliceMethod.qlref +++ b/python/ql/test/2/query-tests/Functions/DeprecatedSliceMethod.qlref @@ -1 +1,2 @@ -Functions/DeprecatedSliceMethod.ql \ No newline at end of file +query: Functions/DeprecatedSliceMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Imports/encoding_error/EncodingError.qlref b/python/ql/test/2/query-tests/Imports/encoding_error/EncodingError.qlref index a7e91769ded1..bc78d28db329 100644 --- a/python/ql/test/2/query-tests/Imports/encoding_error/EncodingError.qlref +++ b/python/ql/test/2/query-tests/Imports/encoding_error/EncodingError.qlref @@ -1 +1,2 @@ -Imports/EncodingError.ql +query: Imports/EncodingError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Imports/syntax_error/EncodingError.qlref b/python/ql/test/2/query-tests/Imports/syntax_error/EncodingError.qlref index e742356f8658..bc78d28db329 100644 --- a/python/ql/test/2/query-tests/Imports/syntax_error/EncodingError.qlref +++ b/python/ql/test/2/query-tests/Imports/syntax_error/EncodingError.qlref @@ -1 +1,2 @@ -Imports/EncodingError.ql \ No newline at end of file +query: Imports/EncodingError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.qlref b/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.qlref index c143a01fe8b3..5d0698be3de5 100644 --- a/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.qlref +++ b/python/ql/test/2/query-tests/Imports/syntax_error/SyntaxError.qlref @@ -1 +1,2 @@ -Imports/SyntaxError.ql \ No newline at end of file +query: Imports/SyntaxError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Imports/syntax_error/bad_encoding.py b/python/ql/test/2/query-tests/Imports/syntax_error/bad_encoding.py index 9c61b1e1b114..5e3308df0f57 100644 --- a/python/ql/test/2/query-tests/Imports/syntax_error/bad_encoding.py +++ b/python/ql/test/2/query-tests/Imports/syntax_error/bad_encoding.py @@ -8,5 +8,5 @@ # encoding:shift-jis def f(): - print "Python の開発は、1990 年ごろから開始されています" + print "Python の開発は、1990 年ごろから開始されています" # $ Alert[py/encoding-error] """ diff --git a/python/ql/test/2/query-tests/Imports/syntax_error/nonsense.py b/python/ql/test/2/query-tests/Imports/syntax_error/nonsense.py index e413967af412..f5cd27b313b6 100644 --- a/python/ql/test/2/query-tests/Imports/syntax_error/nonsense.py +++ b/python/ql/test/2/query-tests/Imports/syntax_error/nonsense.py @@ -1,4 +1,4 @@ -`Twas brillig, and the slithy toves +`Twas brillig, and the slithy toves # $ Alert[py/syntax-error] Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. diff --git a/python/ql/test/2/query-tests/Lexical/OldOctalLiteral.qlref b/python/ql/test/2/query-tests/Lexical/OldOctalLiteral.qlref index 40040c873d63..e5b4fdfec578 100644 --- a/python/ql/test/2/query-tests/Lexical/OldOctalLiteral.qlref +++ b/python/ql/test/2/query-tests/Lexical/OldOctalLiteral.qlref @@ -1 +1,2 @@ -Lexical/OldOctalLiteral.ql \ No newline at end of file +query: Lexical/OldOctalLiteral.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Lexical/lexical_test.py b/python/ql/test/2/query-tests/Lexical/lexical_test.py index 4b82b17cc65f..412c24683d19 100644 --- a/python/ql/test/2/query-tests/Lexical/lexical_test.py +++ b/python/ql/test/2/query-tests/Lexical/lexical_test.py @@ -1,6 +1,6 @@ #Bad Octal literal -017 +017 # $ Alert #Good Octal literal 0o17 #Special case file permissions diff --git a/python/ql/test/2/query-tests/Statements/ExecUsed.qlref b/python/ql/test/2/query-tests/Statements/ExecUsed.qlref index ccff89d6815f..286996305ed1 100644 --- a/python/ql/test/2/query-tests/Statements/ExecUsed.qlref +++ b/python/ql/test/2/query-tests/Statements/ExecUsed.qlref @@ -1 +1,2 @@ -Statements/ExecUsed.ql \ No newline at end of file +query: Statements/ExecUsed.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Statements/IterableStringOrSequence.qlref b/python/ql/test/2/query-tests/Statements/IterableStringOrSequence.qlref index e8f1ce1b79ef..c24806ccf305 100644 --- a/python/ql/test/2/query-tests/Statements/IterableStringOrSequence.qlref +++ b/python/ql/test/2/query-tests/Statements/IterableStringOrSequence.qlref @@ -1 +1,2 @@ -Statements/IterableStringOrSequence.ql \ No newline at end of file +query: Statements/IterableStringOrSequence.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Statements/TopLevelPrint.qlref b/python/ql/test/2/query-tests/Statements/TopLevelPrint.qlref index 8271065261d0..e91717901f3d 100644 --- a/python/ql/test/2/query-tests/Statements/TopLevelPrint.qlref +++ b/python/ql/test/2/query-tests/Statements/TopLevelPrint.qlref @@ -1 +1,2 @@ -Statements/TopLevelPrint.ql \ No newline at end of file +query: Statements/TopLevelPrint.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Statements/module.py b/python/ql/test/2/query-tests/Statements/module.py index 0b1f4d26546b..af34eedf0dc3 100644 --- a/python/ql/test/2/query-tests/Statements/module.py +++ b/python/ql/test/2/query-tests/Statements/module.py @@ -1,2 +1,2 @@ #Top level prints in modules are bad -print ("Side effect on import") \ No newline at end of file +print ("Side effect on import") # $ Alert[py/print-during-import] \ No newline at end of file diff --git a/python/ql/test/2/query-tests/Statements/statements_test.py b/python/ql/test/2/query-tests/Statements/statements_test.py index e540608964d2..729b1fd7616e 100644 --- a/python/ql/test/2/query-tests/Statements/statements_test.py +++ b/python/ql/test/2/query-tests/Statements/statements_test.py @@ -2,7 +2,7 @@ def exec_used(val): - exec (val) + exec (val) # $ Alert[py/use-of-exec] #Top level print import module @@ -18,7 +18,7 @@ def f(x): s = u"Hello World" else: s = [ u'Hello', u'World'] - for thing in s: + for thing in s: # $ Alert[py/iteration-string-and-sequence] print (thing) import fake_six diff --git a/python/ql/test/2/query-tests/Summary/LinesOfCode.qlref b/python/ql/test/2/query-tests/Summary/LinesOfCode.qlref index b60eb7917224..d22b10044239 100644 --- a/python/ql/test/2/query-tests/Summary/LinesOfCode.qlref +++ b/python/ql/test/2/query-tests/Summary/LinesOfCode.qlref @@ -1 +1 @@ -Summary/LinesOfCode.ql +query: Summary/LinesOfCode.ql diff --git a/python/ql/test/2/query-tests/Summary/LinesOfUserCode.qlref b/python/ql/test/2/query-tests/Summary/LinesOfUserCode.qlref index baaa947e6afa..99a6d1324943 100644 --- a/python/ql/test/2/query-tests/Summary/LinesOfUserCode.qlref +++ b/python/ql/test/2/query-tests/Summary/LinesOfUserCode.qlref @@ -1 +1 @@ -Summary/LinesOfUserCode.ql +query: Summary/LinesOfUserCode.ql diff --git a/python/ql/test/2/query-tests/Variables/LeakyComp/LeakyComp.qlref b/python/ql/test/2/query-tests/Variables/LeakyComp/LeakyComp.qlref index 0f6dd50a2814..6b4ece7f1273 100644 --- a/python/ql/test/2/query-tests/Variables/LeakyComp/LeakyComp.qlref +++ b/python/ql/test/2/query-tests/Variables/LeakyComp/LeakyComp.qlref @@ -1 +1,2 @@ -Variables/LeakingListComprehension.ql \ No newline at end of file +query: Variables/LeakingListComprehension.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Variables/LeakyComp/test.py b/python/ql/test/2/query-tests/Variables/LeakyComp/test.py index 0cd6a0d25202..bbb5d33328f8 100644 --- a/python/ql/test/2/query-tests/Variables/LeakyComp/test.py +++ b/python/ql/test/2/query-tests/Variables/LeakyComp/test.py @@ -2,12 +2,12 @@ def undefined_in_3(): [x for x in range(3)] - print(x) + print(x) # $ Alert def different_in_3(): y = 10 [y for y in range(3)] - print(y) + print(y) # $ Alert def ok(): [z for z in range(4)] diff --git a/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.py b/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.py index d7ec86a22560..847d0ce4f8ef 100644 --- a/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.py +++ b/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.py @@ -1,6 +1,6 @@ -__all__ = [ "x", "y", "z", "module" ] +__all__ = [ "x", "y", "z", "module" ] # $ Alert[py/undefined-export] x = 1 if 0: diff --git a/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.qlref b/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.qlref index 3e5d31e47488..d964148077e5 100644 --- a/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.qlref +++ b/python/ql/test/2/query-tests/Variables/undefined/UndefinedExport.qlref @@ -1 +1,2 @@ -Variables/UndefinedExport.ql +query: Variables/UndefinedExport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Variables/undefined/UndefinedGlobal.qlref b/python/ql/test/2/query-tests/Variables/undefined/UndefinedGlobal.qlref index ea9f5a038426..e69631e746b9 100644 --- a/python/ql/test/2/query-tests/Variables/undefined/UndefinedGlobal.qlref +++ b/python/ql/test/2/query-tests/Variables/undefined/UndefinedGlobal.qlref @@ -1 +1,2 @@ -Variables/UndefinedGlobal.ql +query: Variables/UndefinedGlobal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Variables/undefined/UninitializedLocal.qlref b/python/ql/test/2/query-tests/Variables/undefined/UninitializedLocal.qlref index f2d0e603554a..90233ce61888 100644 --- a/python/ql/test/2/query-tests/Variables/undefined/UninitializedLocal.qlref +++ b/python/ql/test/2/query-tests/Variables/undefined/UninitializedLocal.qlref @@ -1 +1,2 @@ -Variables/UninitializedLocal.ql +query: Variables/UninitializedLocal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/2/query-tests/Variables/undefined/package/__init__.py b/python/ql/test/2/query-tests/Variables/undefined/package/__init__.py index 85f1f2ac24f4..d0f80d5e8909 100644 --- a/python/ql/test/2/query-tests/Variables/undefined/package/__init__.py +++ b/python/ql/test/2/query-tests/Variables/undefined/package/__init__.py @@ -1 +1 @@ -__all__ = [ "module", "not_exists" ] \ No newline at end of file +__all__ = [ "module", "not_exists" ] # $ Alert[py/undefined-export] \ No newline at end of file diff --git a/python/ql/test/3/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref b/python/ql/test/3/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref index e542a6176ad4..f3385f506bf2 100644 --- a/python/ql/test/3/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref +++ b/python/ql/test/3/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref @@ -1 +1,2 @@ -Classes/DefineEqualsWhenAddingAttributes.ql \ No newline at end of file +query: Classes/DefineEqualsWhenAddingAttributes.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Classes/equals-attr/test.py b/python/ql/test/3/query-tests/Classes/equals-attr/test.py index 0ab18d0ad434..b6f3e0eb3be3 100644 --- a/python/ql/test/3/query-tests/Classes/equals-attr/test.py +++ b/python/ql/test/3/query-tests/Classes/equals-attr/test.py @@ -9,7 +9,7 @@ class RedefineEquals: def __eq__(self, other): return other is "Tuesday" -class C(RedefineEquals): +class C(RedefineEquals): # $ Alert def __init__(self, args): self.a, self.b = args diff --git a/python/ql/test/3/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref b/python/ql/test/3/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref index f43176f3d7a8..e2e9a180ab1c 100644 --- a/python/ql/test/3/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref +++ b/python/ql/test/3/query-tests/Classes/inconsistent-mro/InconsistentMRO.qlref @@ -1 +1,2 @@ -Classes/InconsistentMRO.ql \ No newline at end of file +query: Classes/InconsistentMRO.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Classes/inconsistent-mro/inconsistent_mro.py b/python/ql/test/3/query-tests/Classes/inconsistent-mro/inconsistent_mro.py index 346778648349..9cb04f1df97c 100644 --- a/python/ql/test/3/query-tests/Classes/inconsistent-mro/inconsistent_mro.py +++ b/python/ql/test/3/query-tests/Classes/inconsistent-mro/inconsistent_mro.py @@ -6,12 +6,12 @@ class X(object): class Y(X): pass -class Z(X, Y): +class Z(X, Y): # $ Alert pass class O: pass #This is OK in Python 2 -class N(object, O): +class N(object, O): # $ Alert pass \ No newline at end of file diff --git a/python/ql/test/3/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref b/python/ql/test/3/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref index d4986ffc84ce..35f6da7add55 100644 --- a/python/ql/test/3/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref +++ b/python/ql/test/3/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/MaybeUndefinedClassAttribute.ql +query: Classes/MaybeUndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref b/python/ql/test/3/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref index 7ac0a3b18b77..f0e8fb722784 100644 --- a/python/ql/test/3/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref +++ b/python/ql/test/3/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/UndefinedClassAttribute.ql +query: Classes/UndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref b/python/ql/test/3/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref index 3599f204f55e..c6b6ca3d30fa 100644 --- a/python/ql/test/3/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref +++ b/python/ql/test/3/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNameForArgumentInCall.ql \ No newline at end of file +query: Expressions/WrongNameForArgumentInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref b/python/ql/test/3/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref index 1bffe8f1cad4..68dc510d5c6e 100644 --- a/python/ql/test/3/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref +++ b/python/ql/test/3/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNumberArgumentsInCall.ql \ No newline at end of file +query: Expressions/WrongNumberArgumentsInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Expressions/Arguments/wrong_arguments.py b/python/ql/test/3/query-tests/Expressions/Arguments/wrong_arguments.py index 729177ea0b43..1242af144b61 100644 --- a/python/ql/test/3/query-tests/Expressions/Arguments/wrong_arguments.py +++ b/python/ql/test/3/query-tests/Expressions/Arguments/wrong_arguments.py @@ -9,8 +9,8 @@ def f(a, *varargs, kw1, kw2="has-default"): f(1, 2, kw1=1, kw2=2) #Not OK -f(1, 2, 3, kw1=1, kw3=3) -f(1, 2, 3, kw3=3) +f(1, 2, 3, kw1=1, kw3=3) # $ Alert[py/call/wrong-named-argument] +f(1, 2, 3, kw3=3) # $ Alert[py/call/wrong-named-argument] #ODASA-5897 @@ -21,4 +21,4 @@ def ok(): return analyze_member_access(msg, original=original, chk=chk) def bad(): - return analyze_member_access(msg, original, chk=chk) + return analyze_member_access(msg, original, chk=chk) # $ Alert[py/call/wrong-arguments] diff --git a/python/ql/test/3/query-tests/Expressions/Formatting/WrongNumberArgumentsForFormat.qlref b/python/ql/test/3/query-tests/Expressions/Formatting/WrongNumberArgumentsForFormat.qlref index 0d127e1b618b..744334a6aeb1 100644 --- a/python/ql/test/3/query-tests/Expressions/Formatting/WrongNumberArgumentsForFormat.qlref +++ b/python/ql/test/3/query-tests/Expressions/Formatting/WrongNumberArgumentsForFormat.qlref @@ -1 +1,2 @@ -Expressions/WrongNumberArgumentsForFormat.ql \ No newline at end of file +query: Expressions/WrongNumberArgumentsForFormat.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Expressions/TruncatedDivision/TruncatedDivision.qlref b/python/ql/test/3/query-tests/Expressions/TruncatedDivision/TruncatedDivision.qlref index fa2c2cbf006c..17d539c32260 100644 --- a/python/ql/test/3/query-tests/Expressions/TruncatedDivision/TruncatedDivision.qlref +++ b/python/ql/test/3/query-tests/Expressions/TruncatedDivision/TruncatedDivision.qlref @@ -1 +1,2 @@ -Expressions/TruncatedDivision.ql +query: Expressions/TruncatedDivision.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Expressions/UseofApply/UseofApply.qlref b/python/ql/test/3/query-tests/Expressions/UseofApply/UseofApply.qlref index abf684e3918a..4add79acdb3c 100644 --- a/python/ql/test/3/query-tests/Expressions/UseofApply/UseofApply.qlref +++ b/python/ql/test/3/query-tests/Expressions/UseofApply/UseofApply.qlref @@ -1 +1,2 @@ -Expressions/UseofApply.ql +query: Expressions/UseofApply.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Imports/encoding_error/EncodingError.qlref b/python/ql/test/3/query-tests/Imports/encoding_error/EncodingError.qlref index a7e91769ded1..bc78d28db329 100644 --- a/python/ql/test/3/query-tests/Imports/encoding_error/EncodingError.qlref +++ b/python/ql/test/3/query-tests/Imports/encoding_error/EncodingError.qlref @@ -1 +1,2 @@ -Imports/EncodingError.ql +query: Imports/EncodingError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Imports/syntax_error/EncodingError.qlref b/python/ql/test/3/query-tests/Imports/syntax_error/EncodingError.qlref index e742356f8658..bc78d28db329 100644 --- a/python/ql/test/3/query-tests/Imports/syntax_error/EncodingError.qlref +++ b/python/ql/test/3/query-tests/Imports/syntax_error/EncodingError.qlref @@ -1 +1,2 @@ -Imports/EncodingError.ql \ No newline at end of file +query: Imports/EncodingError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.qlref b/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.qlref index c143a01fe8b3..5d0698be3de5 100644 --- a/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.qlref +++ b/python/ql/test/3/query-tests/Imports/syntax_error/SyntaxError.qlref @@ -1 +1,2 @@ -Imports/SyntaxError.ql \ No newline at end of file +query: Imports/SyntaxError.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Imports/syntax_error/bad_encoding.py b/python/ql/test/3/query-tests/Imports/syntax_error/bad_encoding.py index 9c61b1e1b114..5e3308df0f57 100644 --- a/python/ql/test/3/query-tests/Imports/syntax_error/bad_encoding.py +++ b/python/ql/test/3/query-tests/Imports/syntax_error/bad_encoding.py @@ -8,5 +8,5 @@ # encoding:shift-jis def f(): - print "Python の開発は、1990 年ごろから開始されています" + print "Python の開発は、1990 年ごろから開始されています" # $ Alert[py/encoding-error] """ diff --git a/python/ql/test/3/query-tests/Imports/syntax_error/nonsense.py b/python/ql/test/3/query-tests/Imports/syntax_error/nonsense.py index 66cdd526fbab..e0819afbc5ee 100644 --- a/python/ql/test/3/query-tests/Imports/syntax_error/nonsense.py +++ b/python/ql/test/3/query-tests/Imports/syntax_error/nonsense.py @@ -1,4 +1,4 @@ - `Twas brillig, and the slithy toves + `Twas brillig, and the slithy toves # $ Alert[py/syntax-error] Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. diff --git a/python/ql/test/3/query-tests/Statements/general/ExecUsed.qlref b/python/ql/test/3/query-tests/Statements/general/ExecUsed.qlref index ccff89d6815f..286996305ed1 100644 --- a/python/ql/test/3/query-tests/Statements/general/ExecUsed.qlref +++ b/python/ql/test/3/query-tests/Statements/general/ExecUsed.qlref @@ -1 +1,2 @@ -Statements/ExecUsed.ql \ No newline at end of file +query: Statements/ExecUsed.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Statements/general/TopLevelPrint.qlref b/python/ql/test/3/query-tests/Statements/general/TopLevelPrint.qlref index 8271065261d0..e91717901f3d 100644 --- a/python/ql/test/3/query-tests/Statements/general/TopLevelPrint.qlref +++ b/python/ql/test/3/query-tests/Statements/general/TopLevelPrint.qlref @@ -1 +1,2 @@ -Statements/TopLevelPrint.ql \ No newline at end of file +query: Statements/TopLevelPrint.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Statements/general/module.py b/python/ql/test/3/query-tests/Statements/general/module.py index 0b1f4d26546b..af34eedf0dc3 100644 --- a/python/ql/test/3/query-tests/Statements/general/module.py +++ b/python/ql/test/3/query-tests/Statements/general/module.py @@ -1,2 +1,2 @@ #Top level prints in modules are bad -print ("Side effect on import") \ No newline at end of file +print ("Side effect on import") # $ Alert[py/print-during-import] \ No newline at end of file diff --git a/python/ql/test/3/query-tests/Statements/general/statements_test.py b/python/ql/test/3/query-tests/Statements/general/statements_test.py index 2baee458c04c..a4414a40f80c 100644 --- a/python/ql/test/3/query-tests/Statements/general/statements_test.py +++ b/python/ql/test/3/query-tests/Statements/general/statements_test.py @@ -2,7 +2,7 @@ def exec_used(val): - exec(val) + exec(val) # $ Alert[py/use-of-exec] #Top level print import module diff --git a/python/ql/test/3/query-tests/Statements/iter/IterableStringOrSequence.qlref b/python/ql/test/3/query-tests/Statements/iter/IterableStringOrSequence.qlref index e8f1ce1b79ef..c24806ccf305 100644 --- a/python/ql/test/3/query-tests/Statements/iter/IterableStringOrSequence.qlref +++ b/python/ql/test/3/query-tests/Statements/iter/IterableStringOrSequence.qlref @@ -1 +1,2 @@ -Statements/IterableStringOrSequence.ql \ No newline at end of file +query: Statements/IterableStringOrSequence.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.qlref b/python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.qlref index fb09cace29a8..b7697d64d8fa 100644 --- a/python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.qlref +++ b/python/ql/test/3/query-tests/Statements/iter/NonIteratorInForLoop.qlref @@ -1 +1,2 @@ -Statements/NonIteratorInForLoop.ql \ No newline at end of file +query: Statements/NonIteratorInForLoop.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Statements/iter/async_iterator.py b/python/ql/test/3/query-tests/Statements/iter/async_iterator.py index fdde931eace9..76972058a02a 100644 --- a/python/ql/test/3/query-tests/Statements/iter/async_iterator.py +++ b/python/ql/test/3/query-tests/Statements/iter/async_iterator.py @@ -23,5 +23,5 @@ async def good(): yield x async def bad(): - async for x in MissingAiter(): + async for x in MissingAiter(): # $ Alert[py/non-iterable-in-for-loop] yield x diff --git a/python/ql/test/3/query-tests/Statements/iter/statements_test.py b/python/ql/test/3/query-tests/Statements/iter/statements_test.py index 33b3f4aae5c5..daf811f3f83d 100644 --- a/python/ql/test/3/query-tests/Statements/iter/statements_test.py +++ b/python/ql/test/3/query-tests/Statements/iter/statements_test.py @@ -18,7 +18,7 @@ def f(x): s = u"Hello World" else: s = [ u'Hello', u'World'] - for thing in s: + for thing in s: # $ Alert[py/iteration-string-and-sequence] print (thing) @@ -31,7 +31,7 @@ class Color(Enum): def colors(): for color in Color: print(color) - for color in 1: + for color in 1: # $ Alert[py/non-iterable-in-for-loop] print(color) colors() diff --git a/python/ql/test/3/query-tests/Statements/unreachable/UnreachableCode.qlref b/python/ql/test/3/query-tests/Statements/unreachable/UnreachableCode.qlref index 5b7891f0026a..b95a67d24949 100644 --- a/python/ql/test/3/query-tests/Statements/unreachable/UnreachableCode.qlref +++ b/python/ql/test/3/query-tests/Statements/unreachable/UnreachableCode.qlref @@ -1 +1,2 @@ -Statements/UnreachableCode.ql +query: Statements/UnreachableCode.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Statements/unreachable_suppressed/UnreachableCode.qlref b/python/ql/test/3/query-tests/Statements/unreachable_suppressed/UnreachableCode.qlref index 5b7891f0026a..b95a67d24949 100644 --- a/python/ql/test/3/query-tests/Statements/unreachable_suppressed/UnreachableCode.qlref +++ b/python/ql/test/3/query-tests/Statements/unreachable_suppressed/UnreachableCode.qlref @@ -1 +1,2 @@ -Statements/UnreachableCode.ql +query: Statements/UnreachableCode.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Summary/LinesOfCode.qlref b/python/ql/test/3/query-tests/Summary/LinesOfCode.qlref index b60eb7917224..d22b10044239 100644 --- a/python/ql/test/3/query-tests/Summary/LinesOfCode.qlref +++ b/python/ql/test/3/query-tests/Summary/LinesOfCode.qlref @@ -1 +1 @@ -Summary/LinesOfCode.ql +query: Summary/LinesOfCode.ql diff --git a/python/ql/test/3/query-tests/Summary/LinesOfUserCode.qlref b/python/ql/test/3/query-tests/Summary/LinesOfUserCode.qlref index baaa947e6afa..99a6d1324943 100644 --- a/python/ql/test/3/query-tests/Summary/LinesOfUserCode.qlref +++ b/python/ql/test/3/query-tests/Summary/LinesOfUserCode.qlref @@ -1 +1 @@ -Summary/LinesOfUserCode.ql +query: Summary/LinesOfUserCode.ql diff --git a/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.py b/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.py index fc1a03f6e1c9..84a717c03143 100644 --- a/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.py +++ b/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.py @@ -1,6 +1,6 @@ -__all__ = [ "x", "y", "z", "module", "w" ] +__all__ = [ "x", "y", "z", "module", "w" ] # $ Alert[py/undefined-export] x = 1 if 0: diff --git a/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.qlref b/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.qlref index 3e5d31e47488..d964148077e5 100644 --- a/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.qlref +++ b/python/ql/test/3/query-tests/Variables/undefined/UndefinedExport.qlref @@ -1 +1,2 @@ -Variables/UndefinedExport.ql +query: Variables/UndefinedExport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Variables/undefined/UninitializedLocal.qlref b/python/ql/test/3/query-tests/Variables/undefined/UninitializedLocal.qlref index f2d0e603554a..90233ce61888 100644 --- a/python/ql/test/3/query-tests/Variables/undefined/UninitializedLocal.qlref +++ b/python/ql/test/3/query-tests/Variables/undefined/UninitializedLocal.qlref @@ -1 +1,2 @@ -Variables/UninitializedLocal.ql +query: Variables/UninitializedLocal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/3/query-tests/Variables/undefined/enum_convert.py b/python/ql/test/3/query-tests/Variables/undefined/enum_convert.py index 58979d0b4c9c..db6b89b8f7f4 100644 --- a/python/ql/test/3/query-tests/Variables/undefined/enum_convert.py +++ b/python/ql/test/3/query-tests/Variables/undefined/enum_convert.py @@ -5,4 +5,4 @@ __name__, lambda C: C.isupper() and C.startswith('AF_')) -__all__ = [ "Maybe", "Maybe_not" ] +__all__ = [ "Maybe", "Maybe_not" ] # $ Alert[py/undefined-export] diff --git a/python/ql/test/3/query-tests/Variables/undefined/package/__init__.py b/python/ql/test/3/query-tests/Variables/undefined/package/__init__.py index 85f1f2ac24f4..d0f80d5e8909 100644 --- a/python/ql/test/3/query-tests/Variables/undefined/package/__init__.py +++ b/python/ql/test/3/query-tests/Variables/undefined/package/__init__.py @@ -1 +1 @@ -__all__ = [ "module", "not_exists" ] \ No newline at end of file +__all__ = [ "module", "not_exists" ] # $ Alert[py/undefined-export] \ No newline at end of file diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref index 25117a4582bd..e7b837c89003 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref +++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.qlref @@ -1 +1 @@ -../CallGraph/InlineCallGraphTest.ql +query: ../CallGraph/InlineCallGraphTest.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.qlref b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.qlref index 25117a4582bd..e7b837c89003 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.qlref +++ b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.qlref @@ -1 +1 @@ -../CallGraph/InlineCallGraphTest.ql +query: ../CallGraph/InlineCallGraphTest.ql diff --git a/python/ql/test/experimental/library-tests/CallGraph-type-annotations/InlineCallGraphTest.qlref b/python/ql/test/experimental/library-tests/CallGraph-type-annotations/InlineCallGraphTest.qlref index 25117a4582bd..e7b837c89003 100644 --- a/python/ql/test/experimental/library-tests/CallGraph-type-annotations/InlineCallGraphTest.qlref +++ b/python/ql/test/experimental/library-tests/CallGraph-type-annotations/InlineCallGraphTest.qlref @@ -1 +1 @@ -../CallGraph/InlineCallGraphTest.ql +query: ../CallGraph/InlineCallGraphTest.ql diff --git a/python/ql/test/experimental/library-tests/FindSubclass/Find.qlref b/python/ql/test/experimental/library-tests/FindSubclass/Find.qlref index f8bd638be1ab..59bdb1462def 100644 --- a/python/ql/test/experimental/library-tests/FindSubclass/Find.qlref +++ b/python/ql/test/experimental/library-tests/FindSubclass/Find.qlref @@ -1 +1 @@ -meta/ClassHierarchy/Find.ql +query: meta/ClassHierarchy/Find.ql diff --git a/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.py b/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.py index c07bdb57234a..46633a009f72 100644 --- a/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.py +++ b/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.py @@ -1,5 +1,5 @@ # BAD, do not start class or interface name with lowercase letter -class badName: +class badName: # $ Alert def hello(self): print("hello") diff --git a/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.qlref b/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.qlref index 7ed945d782c4..b5b73c19bf81 100644 --- a/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.qlref +++ b/python/ql/test/experimental/query-tests/Classes/Naming/NamingConventionsClasses.qlref @@ -1 +1,2 @@ -experimental/Classes/NamingConventionsClasses.ql \ No newline at end of file +query: experimental/Classes/NamingConventionsClasses.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.py b/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.py index fb3e89ab8e92..5923ce5919f3 100644 --- a/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.py +++ b/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.py @@ -1,7 +1,7 @@ class Test: # BAD, do not start function name with uppercase letter - def HelloWorld(self): + def HelloWorld(self): # $ Alert print("hello world") # GOOD, function name starts with lowercase letter diff --git a/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.qlref b/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.qlref index 0204694de0a3..21d3e5fe1358 100644 --- a/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.qlref +++ b/python/ql/test/experimental/query-tests/Functions/general/NamingConventionsFunctions.qlref @@ -1 +1,2 @@ -experimental/Functions/NamingConventionsFunctions.ql \ No newline at end of file +query: experimental/Functions/NamingConventionsFunctions.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref index a518196b6982..2842a87d0803 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-022bis/TarSlipImprov.ql +query: experimental/Security/CWE-022bis/TarSlipImprov.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlipImprov.py b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlipImprov.py index 15bc66b4aea5..3b59f24e4026 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlipImprov.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/TarSlipImprov.py @@ -12,14 +12,14 @@ unsafe_filename_tar = sys.argv[2] safe_filename_tar = "safe_path.tar" -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] result = [] for member in tar: if ".." in member.name: raise ValueError("Path in member name !!!") result.append(member) path = unsafe_filename_tar -tar.extractall(path=path, members=result) +tar.extractall(path=path, members=result) # $ Alert[py/tarslip-extended] tar.close() @@ -35,27 +35,27 @@ def members_filter1(tarfile): result.append(member) return result -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(path=tempfile.mkdtemp(), members=members_filter1(tar)) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] +tar.extractall(path=tempfile.mkdtemp(), members=members_filter1(tar)) # $ Alert[py/tarslip-extended] tar.close() -with tarfile.open(unsafe_filename_tar) as tar: +with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] for entry in tar: if ".." in entry.name: raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] def _validate_archive_name(name, target): if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): raise ValueError(f"Provided language pack contains invalid name {name}") -with tarfile.open(unsafe_filename_tar) as tar: +with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] target = "/tmp/unpack" for entry in tar: _validate_archive_name(entry.name, target) - tar.extract(entry, target) + tar.extract(entry, target) # $ Alert[py/tarslip-extended] def members_filter2(tarfile): @@ -85,10 +85,10 @@ def _validate_archive_name(name, target): raise ValueError(f"Provided language pack contains invalid name {name}") target = "/tmp/unpack" -with tarfile.open(unsafe_filename_tar, "r") as tar: +with tarfile.open(unsafe_filename_tar, "r") as tar: # $ Source[py/tarslip-extended] for info in tar.getmembers(): _validate_tar_info(info, target) - tar.extractall(target) + tar.extractall(target) # $ Alert[py/tarslip-extended] def members_filter3(tarfile): @@ -108,11 +108,11 @@ def members_filter3(tarfile): tar.close() -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tarf = tar.getmembers() for f in tarf: if not f.issym(): - tar.extractall(path=tempfile.mkdtemp(), members=[f]) + tar.extractall(path=tempfile.mkdtemp(), members=[f]) # $ Alert[py/tarslip-extended] tar.close() @@ -120,27 +120,27 @@ class MKTar(TarFile): pass tarball = unsafe_filename_tar -with MKTar.open(name=tarball) as tar: +with MKTar.open(name=tarball) as tar: # $ Source[py/tarslip-extended] for entry in tar: - tar._extract_member(entry, entry.name) + tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -with tarfile.open(tarball) as tar: - tar.extractall() +with tarfile.open(tarball) as tar: # $ Source[py/tarslip-extended] + tar.extractall() # $ Alert[py/tarslip-extended] -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(path=tempfile.mkdtemp(), members=None) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] +tar.extractall(path=tempfile.mkdtemp(), members=None) # $ Alert[py/tarslip-extended] class MKTar(tarfile.TarFile): pass tarball = unsafe_filename_tar -with MKTar.open(name=tarball) as tar: +with MKTar.open(name=tarball) as tar: # $ Source[py/tarslip-extended] for entry in tar: - tar._extract_member(entry, entry.name) + tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] @contextmanager @@ -148,7 +148,7 @@ def py2_tarxz(filename): with tempfile.TemporaryFile() as tmp: subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno()) tmp.seek(0) - with closing(tarfile.TarFile(fileobj=tmp)) as tf: + with closing(tarfile.TarFile(fileobj=tmp)) as tf: # $ Source[py/tarslip-extended] yield tf def unpack_tarball(tar_filename, dest): @@ -156,7 +156,7 @@ def unpack_tarball(tar_filename, dest): # Py 2.7 lacks lzma support tar_cm = py2_tarxz(tar_filename) else: - tar_cm = closing(tarfile.open(tar_filename)) + tar_cm = closing(tarfile.open(tar_filename)) # $ Source[py/tarslip-extended] base_dir = None with tar_cm as tarc: @@ -166,32 +166,32 @@ def unpack_tarball(tar_filename, dest): base_dir = base_name elif base_dir != base_name: print('Unexpected path in %s: %s' % (tar_filename, base_name)) - tarc.extractall(dest) + tarc.extractall(dest) # $ Alert[py/tarslip-extended] return os.path.join(dest, base_dir) unpack_tarball(unsafe_filename_tar, "/tmp/unpack") tarball = unsafe_filename_tar -with tarfile.open(name=tarball) as tar: +with tarfile.open(name=tarball) as tar: # $ Source[py/tarslip-extended] for entry in tar: - tar._extract_member(entry, entry.name) + tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -with tarfile.open(name=tarball) as tar: +with tarfile.open(name=tarball) as tar: # $ Source[py/tarslip-extended] for entry in tar: - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -tar = tarfile.open(tarball) -tar.extractall("/tmp/unpack/") +tar = tarfile.open(tarball) # $ Source[py/tarslip-extended] +tar.extractall("/tmp/unpack/") # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -with tarfile.open(tarball, "r") as tar: - tar.extractall(path="/tmp/unpack/", members=tar) +with tarfile.open(tarball, "r") as tar: # $ Source[py/tarslip-extended] + tar.extractall(path="/tmp/unpack/", members=tar) # $ Alert[py/tarslip-extended] def members_filter4(tarfile): @@ -207,8 +207,8 @@ def members_filter4(tarfile): tar.close() -with tarfile.open(unsafe_filename_tar, "r") as tar: - tar.extractall(path="/tmp/unpack") +with tarfile.open(unsafe_filename_tar, "r") as tar: # $ Source[py/tarslip-extended] + tar.extractall(path="/tmp/unpack") # $ Alert[py/tarslip-extended] def members_filter5(tarfile): @@ -228,12 +228,12 @@ def members_filter5(tarfile): tmp_dir = "/tmp/" read_type = "r:gz" if filename.endswith("tgz") else "r" -with tarfile.open(filename, read_type) as corpus_tar: +with tarfile.open(filename, read_type) as corpus_tar: # $ Source[py/tarslip-extended] members = [] for f in corpus_tar: if not os.path.isfile(os.path.join(tmp_dir, f.name)): members.append(f) - corpus_tar.extractall(tmp_dir, members=members) + corpus_tar.extractall(tmp_dir, members=members) # $ Alert[py/tarslip-extended] def members_filter6(tarfile): @@ -251,66 +251,66 @@ def members_filter6(tarfile): archive_path = unsafe_filename_tar target_dir = "/tmp/unpack" -tarfile.open(archive_path, "r").extractall(path=target_dir) +tarfile.open(archive_path, "r").extractall(path=target_dir) # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -with tarfile.open(tarball) as tar: +with tarfile.open(tarball) as tar: # $ Source[py/tarslip-extended] for entry in tar: if entry.isfile(): - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] -with tarfile.open(unsafe_filename_tar) as tar: +with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] for entry in tar: if entry.name.startswith("/"): raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tarball = unsafe_filename_tar -with tarfile.TarFile(tarball, mode="r") as tar: +with tarfile.TarFile(tarball, mode="r") as tar: # $ Source[py/tarslip-extended] for entry in tar: if entry.isfile(): - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] -with tarfile.open(unsafe_filename_tar) as tar: +with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] for entry in tar: if os.path.isabs(entry.name): raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] -with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: - tar.extractall(path="/tmp/unpack") +with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: # $ Source[py/tarslip-extended] + tar.extractall(path="/tmp/unpack") # $ Alert[py/tarslip-extended] -tar = tarfile.open(filename) -tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) +tar = tarfile.open(filename) # $ Source[py/tarslip-extended] +tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) # $ Alert[py/tarslip-extended] tar.close() -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(path=tempfile.mkdtemp(), members=None) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] +tar.extractall(path=tempfile.mkdtemp(), members=None) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar)) tar.close() -with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: - tar.extractall(path="/tmp/unpack/", members=tar) +with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: # $ Source[py/tarslip-extended] + tar.extractall(path="/tmp/unpack/", members=tar) # $ Alert[py/tarslip-extended] -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] result = [] for member in tar: if member.issym(): raise ValueError("But it is a symlink") result.append(member) -tar.extractall(path=tempfile.mkdtemp(), members=result) +tar.extractall(path=tempfile.mkdtemp(), members=result) # $ Alert[py/tarslip-extended] tar.close() archive_path = unsafe_filename_tar target_dir = "/tmp/unpack" -tarfile.TarFile(unsafe_filename_tar, mode="r").extractall(path=target_dir) \ No newline at end of file +tarfile.TarFile(unsafe_filename_tar, mode="r").extractall(path=target_dir) # $ Alert[py/tarslip-extended] \ No newline at end of file diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/ZipSlip.qlref b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/ZipSlip.qlref index 717dc9d0f105..177a74d6bd74 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/ZipSlip.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/ZipSlip.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-022/ZipSlip.ql +query: experimental/Security/CWE-022/ZipSlip.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/zipslip_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/zipslip_bad.py index c622ead874cb..4e7195cf856d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/zipslip_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-022-TarSlip/zipslip_bad.py @@ -5,35 +5,35 @@ import zipfile def unzip(filename): - with tarfile.open(filename) as zipf: + with tarfile.open(filename) as zipf: # $ Alert[py/zipslip] #BAD : This could write any file on the filesystem. for entry in zipf: - shutil.move(entry, "/tmp/unpack/") + shutil.move(entry, "/tmp/unpack/") # $ Sink[py/zipslip] def unzip1(filename): - with gzip.open(filename) as zipf: + with gzip.open(filename) as zipf: # $ Alert[py/zipslip] #BAD : This could write any file on the filesystem. for entry in zipf: - shutil.copy2(entry, "/tmp/unpack/") + shutil.copy2(entry, "/tmp/unpack/") # $ Sink[py/zipslip] def unzip2(filename): - with bz2.open(filename) as zipf: + with bz2.open(filename) as zipf: # $ Alert[py/zipslip] #BAD : This could write any file on the filesystem. for entry in zipf: - shutil.copyfile(entry, "/tmp/unpack/") + shutil.copyfile(entry, "/tmp/unpack/") # $ Sink[py/zipslip] def unzip3(filename): zf = zipfile.ZipFile(filename) - with zf.namelist() as filelist: + with zf.namelist() as filelist: # $ Alert[py/zipslip] #BAD : This could write any file on the filesystem. for x in filelist: - shutil.copy(x, "/tmp/unpack/") + shutil.copy(x, "/tmp/unpack/") # $ Sink[py/zipslip] def unzip4(filename): zf = zipfile.ZipFile(filename) - filelist = zf.namelist() + filelist = zf.namelist() # $ Alert[py/zipslip] for x in filelist: with zf.open(x) as srcf: - shutil.copyfileobj(x, "/tmp/unpack/") + shutil.copyfileobj(x, "/tmp/unpack/") # $ Sink[py/zipslip] import tty # to set the import root so we can identify the standard library diff --git a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.qlref b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.qlref index dc5c7028f329..96e8c4e0d443 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-074-RemoteCommandExecution/RemoteCommandExecution.qlref @@ -1 +1 @@ -experimental/Security/CWE-074/remoteCommandExecution/RemoteCommandExecution.ql \ No newline at end of file +query: experimental/Security/CWE-074/remoteCommandExecution/RemoteCommandExecution.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref b/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref index fcc132dd66c5..c141aa6746b3 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/EmailXss.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-079/EmailXss.ql +query: experimental/Security/CWE-079/EmailXss.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py index 178e8decc798..fb42c22f02ed 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py @@ -11,7 +11,7 @@ def django_response(request): https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64 """ send_mail("Subject", "plain-text body", "from@example.com", - ["to@example.com"], html_message=django.http.request.GET.get("html")) + ["to@example.com"], html_message=django.http.request.GET.get("html")) # $ Alert def django_response(request): @@ -20,6 +20,6 @@ def django_response(request): https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L90-L121 """ mail_admins("Subject", "plain-text body", - html_message=django.http.request.GET.get("html")) + html_message=django.http.request.GET.get("html")) # $ Alert mail_managers("Subject", "plain-text body", - html_message=django.http.request.GET.get("html")) + html_message=django.http.request.GET.get("html")) # $ Alert diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py index e8bdcc93634c..6978ad741f6a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py @@ -1,4 +1,4 @@ -from flask import request, Flask +from flask import request, Flask # $ Source from flask_mail import Mail, Message app = Flask(__name__) @@ -10,12 +10,12 @@ def send(): sender="from@example.com", recipients=["to@example.com"], body="plain-text body", - html=request.args["html"]) + html=request.args["html"]) # $ Alert # The message can contain a body and/or HTML: msg.body = "plain-text body" # The email's HTML can be set via msg.html or as an initialize argument when creating a Message object. - msg.html = request.args["html"] + msg.html = request.args["html"] # $ Alert mail.send(msg) @@ -28,5 +28,5 @@ def connect(): msg = Message(subject="Subject", sender="from@example.com", recipients=["to@example.com"], - html=request.args["html"]) + html=request.args["html"]) # $ Alert conn.send(msg) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py index e10e8a030a81..4d89056f3fed 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py @@ -1,4 +1,4 @@ -from flask import request, Flask +from flask import request, Flask # $ Source from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail, Email, To, Content, MimeType, HtmlContent @@ -11,7 +11,7 @@ def send(): from_email='from_email@example.com', to_emails='to@example.com', subject='Sending with Twilio SendGrid is Fun', - html_content=request.args["html_content"]) + html_content=request.args["html_content"]) # $ Alert sg = SendGridAPIClient('SENDGRID_API_KEY') sg.send(message) @@ -23,7 +23,7 @@ def send(): from_email='from_email@example.com', to_emails='to@example.com', subject='Sending with Twilio SendGrid is Fun', - html_content=HtmlContent(request.args["html_content"])) + html_content=HtmlContent(request.args["html_content"])) # $ Alert sg = SendGridAPIClient('SENDGRID_API_KEY') sg.send(message) @@ -34,7 +34,7 @@ def send_post(): from_email = Email("test@example.com") to_email = To("test@example.com") subject = "Sending with SendGrid is Fun" - html_content = Content("text/html", request.args["html_content"]) + html_content = Content("text/html", request.args["html_content"]) # $ Alert plain_content = Content("text/plain", request.args["plain_content"]) mail = Mail(from_email, to_email, subject, plain_content, html_content) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py index fca641057da6..30a67213b487 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py @@ -1,6 +1,6 @@ import sendgrid import os -from flask import request, Flask +from flask import request, Flask # $ Source app = Flask(__name__) @@ -13,7 +13,7 @@ def send(): "content": [ { "type": "text/html", - "value": "{}".format(request.args["html_content"]) + "value": "{}".format(request.args["html_content"]) # $ Alert } ], "from": { @@ -24,7 +24,7 @@ def send(): "mail_settings": { "footer": { "enable": True, - "html": "{}".format(request.args["html_footer"]), + "html": "{}".format(request.args["html_footer"]), # $ Alert "text": "Thanks,/n The SendGrid Team" }, }, @@ -38,7 +38,7 @@ def send(): "tracking_settings": { "subscription_tracking": { "enable": True, - "html": "{}".format(request.args["html_tracking"]), + "html": "{}".format(request.args["html_tracking"]), # $ Alert "substitution_tag": "<%click here%>", "text": "If you would like to unsubscribe and stop receiving these emails <% click here %>." } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py index 209bd889393f..20c8e3466aef 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py @@ -1,5 +1,5 @@ # This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart initializer via the subparts parameter. -from flask import Flask, request +from flask import Flask, request # $ Source import json import smtplib import ssl @@ -21,7 +21,7 @@ def email_person(): # Turn these into plain/html MIMEText objects part1 = MIMEText(text, "plain") - part2 = MIMEText(html, "html") + part2 = MIMEText(html, "html") # $ Alert message = MIMEMultipart(_subparts=(part1, part2)) message["Subject"] = "multipart test" diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py index 48a228b0bc6e..d50ab028087f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py @@ -1,5 +1,5 @@ # This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart message. -from flask import Flask, request +from flask import Flask, request # $ Source import json import smtplib, ssl from email.mime.text import MIMEText @@ -24,7 +24,7 @@ def email_person(): # Turn these into plain/html MIMEText objects part1 = MIMEText(text, "plain") - part2 = MIMEText(html, "html") + part2 = MIMEText(html, "html") # $ Alert # Add HTML/plain-text parts to MIMEMultipart message # The email client will try to render the last part first diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected index 8d960a22dfde..53e1d19112e9 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.expected @@ -1,3 +1,10 @@ +#select +| xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +| xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | edges | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | xslt.py:3:26:3:32 | ControlFlowNode for request | provenance | | | xslt.py:3:26:3:32 | ControlFlowNode for request | xslt.py:10:17:10:23 | ControlFlowNode for request | provenance | | @@ -122,10 +129,10 @@ nodes | xsltInjection.py:46:38:46:48 | ControlFlowNode for xsltStrings [List element] | semmle.label | ControlFlowNode for xsltStrings [List element] | | xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | semmle.label | ControlFlowNode for xslt_root | subpaths -#select -| xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xslt.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | -| xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | This XSLT query depends on $@. | xsltInjection.py:3:26:3:32 | ControlFlowNode for ImportMember | user-provided value | +testFailures +| xslt.py:14:29:14:37 | ControlFlowNode for xslt_root | Unexpected result: Alert | +| xsltInjection.py:12:28:12:36 | ControlFlowNode for xslt_root | Unexpected result: Alert | +| xsltInjection.py:21:29:21:37 | ControlFlowNode for xslt_root | Unexpected result: Alert | +| xsltInjection.py:31:24:31:32 | ControlFlowNode for xslt_root | Unexpected result: Alert | +| xsltInjection.py:40:24:40:32 | ControlFlowNode for xslt_root | Unexpected result: Alert | +| xsltInjection.py:50:24:50:32 | ControlFlowNode for xslt_root | Unexpected result: Alert | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.qlref index 4d432d461cab..5bde608133c6 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/XsltInjection.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-091/XsltInjection.ql +query: experimental/Security/CWE-091/XsltInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xslt.py b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xslt.py index 1655916c7e06..6464d35811bb 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xslt.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xslt.py @@ -1,6 +1,6 @@ from lxml import etree from io import StringIO -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @@ -11,4 +11,4 @@ def bad(): xslt_root = etree.XML(xsltQuery) f = StringIO('') tree = etree.parse(f) - result_tree = tree.xslt(xslt_root) # Not OK + result_tree = tree.xslt(xslt_root) # Not OK # $ Alert diff --git a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xsltInjection.py b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xsltInjection.py index ddab954bbff8..9f8a25f2e616 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xsltInjection.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-091-XsltInjection/xsltInjection.py @@ -1,6 +1,6 @@ from lxml import etree from io import StringIO -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @@ -9,7 +9,7 @@ def a(): xsltQuery = request.args.get('xml', '') xslt_root = etree.XML(xsltQuery) - transform = etree.XSLT(xslt_root) # Not OK + transform = etree.XSLT(xslt_root) # Not OK # $ Alert @app.route("/xslt2") @@ -18,7 +18,7 @@ def b(): xslt_root = etree.XML(xsltQuery) f = StringIO('') tree = etree.parse(f) - result_tree = tree.xslt(xslt_root) # Not OK + result_tree = tree.xslt(xslt_root) # Not OK # $ Alert @app.route("/xslt3") @@ -28,7 +28,7 @@ def c(): f = StringIO('') tree = etree.parse(f) - result = tree.xslt(xslt_root, a="'A'") # Not OK + result = tree.xslt(xslt_root, a="'A'") # Not OK # $ Alert @app.route("/xslt4") def d(): @@ -37,7 +37,7 @@ def d(): f = StringIO('') tree = etree.parse(f) - result = tree.xslt(xslt_root, a="'A'") # Not OK + result = tree.xslt(xslt_root, a="'A'") # Not OK # $ Alert @app.route("/xslt5") def e(): @@ -47,7 +47,7 @@ def e(): f = StringIO('') tree = etree.parse(f) - result = tree.xslt(xslt_root, a="'A'") # Not OK + result = tree.xslt(xslt_root, a="'A'") # Not OK # $ Alert @app.route("/xslt6") diff --git a/python/ql/test/experimental/query-tests/Security/CWE-094/Js2Py.qlref b/python/ql/test/experimental/query-tests/Security/CWE-094/Js2Py.qlref index 457bfe2aacca..b88e9d7f392b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-094/Js2Py.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-094/Js2Py.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-094/Js2Py.ql +query: experimental/Security/CWE-094/Js2Py.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-094/Js2PyTest.py b/python/ql/test/experimental/query-tests/Security/CWE-094/Js2PyTest.py index f7aae16a9eed..d62cabef965c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-094/Js2PyTest.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-094/Js2PyTest.py @@ -6,5 +6,5 @@ @bp.route("/bad") def bad(): - jk = flask.request.form["jk"] - jk = eval_js(f"{jk} f()") \ No newline at end of file + jk = flask.request.form["jk"] # $ Source + jk = eval_js(f"{jk} f()") # $ Alert \ No newline at end of file diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected index 5152f7353f25..aa90dfaeea0d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.expected @@ -1,3 +1,7 @@ +#select +| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | edges | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:9:19:9:25 | ControlFlowNode for request | provenance | | | csv_bad.py:9:19:9:25 | ControlFlowNode for request | csv_bad.py:16:16:16:22 | ControlFlowNode for request | provenance | | @@ -26,7 +30,3 @@ nodes | csv_bad.py:24:16:24:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | subpaths -#select -| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | -| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | -| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.qlref index d9cd7e9ca51c..6fe779d1b362 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-1236/CsvInjection.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-1236/CsvInjection.ql \ No newline at end of file +query: experimental/Security/CWE-1236/CsvInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-1236/csv_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-1236/csv_bad.py index 6e204d1f3c54..199f96912b59 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-1236/csv_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-1236/csv_bad.py @@ -6,7 +6,7 @@ import copy import csv from flask import Flask -from flask import request +from flask import request # $ Source from typing import List app = Flask(__name__) @@ -15,17 +15,17 @@ def bad1(): csv_data = request.args.get('csv') csvWriter = csv.writer(open("test.csv", "wt")) - csvWriter.writerow(csv_data) # bad - csvWriter.writerows(csv_data) # bad + csvWriter.writerow(csv_data) # $ Alert # bad + csvWriter.writerows(csv_data) # $ Alert # bad return "bad1" @app.route('/bad2') def bad2(): csv_data = request.args.get('csv') - csvWriter = csv.DictWriter(f, fieldnames=csv_data) # bad + csvWriter = csv.DictWriter(f, fieldnames=csv_data) # $ Alert # bad csvWriter.writeheader() return "bad2" if __name__ == '__main__': app.debug = True - app.run() \ No newline at end of file + app.run() diff --git a/python/ql/test/experimental/query-tests/Security/CWE-176/UnicodeBypassValidation.qlref b/python/ql/test/experimental/query-tests/Security/CWE-176/UnicodeBypassValidation.qlref index ee372b368404..710cbf1f46a5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-176/UnicodeBypassValidation.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-176/UnicodeBypassValidation.qlref @@ -1 +1 @@ -experimental/Security/CWE-176/UnicodeBypassValidation.ql +query: experimental/Security/CWE-176/UnicodeBypassValidation.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected index 1577182b2dcd..bd32259294e0 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected @@ -1,3 +1,6 @@ +#select +| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | signature message | +| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | MAC message | edges | TimingAttackAgainstHash.py:26:5:26:13 | ControlFlowNode for signature | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | provenance | | | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:26:5:26:13 | ControlFlowNode for signature | provenance | | @@ -9,6 +12,3 @@ nodes | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | subpaths -#select -| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | signature message | -| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | MAC message | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref index 73a8e6960ef8..5ac00932072c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +query: experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py index 1d312f028eba..e9b5be0eb36b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py @@ -16,25 +16,25 @@ def UnsafeCmacCheck(actualCmac): expected = cmac.CMAC(algorithms.AES(key)) expected.update(b"message to authenticate") expected.finalize() - return actualCmac == expected + return actualCmac == expected def UnsafeCheckSignature(expected): message = b'To be signed' key = RSA.import_key(open('private_key.der').read()) h = SHA256.new(message) - signature = pkcs1_15.new(key).sign(h) - return expected == signature + signature = pkcs1_15.new(key).sign(h) # $ Source[py/possible-timing-attack-against-hash] + return expected == signature # $ Alert[py/possible-timing-attack-against-hash] def sign(pre_key, msg, alg): - return hmac.new(pre_key, msg, alg).digest() + return hmac.new(pre_key, msg, alg).digest() # $ Source[py/possible-timing-attack-against-hash] def verifyGood(msg, sig): return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good - + def verifyBad(msg, sig): key = "e179017a-62b0-4996-8a38-e91aa9f1" - return sig == sign(key, msg, hashlib.sha256) #bad + return sig == sign(key, msg, hashlib.sha256) # $ Alert[py/possible-timing-attack-against-hash] #bad def constant_time_string_compare(a, b): if len(a) != len(b): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qlref index 50c9d84b1f96..2829d76e85d2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +query: experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py index 211c36274d74..591764ed4f89 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py @@ -11,7 +11,7 @@ @app.route('/bad') def bad(): - if not request.headers.get('X-Auth-Token') == "token": + if not request.headers.get('X-Auth-Token') == "token": # $ Alert raise Exception('bad token') return 'bad' diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref index 9da35da9d6d2..0d31d85dc3f2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +query: experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref index acfe13f6aad2..bd9d8272f981 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +query: experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py index a34b3b7c5ae5..4619821174ea 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py @@ -12,8 +12,8 @@ @app.route('/bad', methods = ['POST', 'GET']) def bad(): if request.method == 'POST': - password = request.form['pwd'] - return password == "1234" + password = request.form['pwd'] # $ Source + return password == "1234" # $ Alert @app.route('/good', methods = ['POST', 'GET']) def good(): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/ConstantSecretKey.qlref b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/ConstantSecretKey.qlref index e77b304f62c4..535dfacbac40 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/ConstantSecretKey.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/ConstantSecretKey.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql +query: experimental/Security/CWE-287-ConstantSecretKey/WebAppConstantSecretKey.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_safe.py b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_safe.py index 442a23e2c3a1..3fcb38acbf93 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_safe.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_safe.py @@ -2,7 +2,7 @@ from flask_session import Session app = Flask(__name__) -app.config['SECRET_KEY'] = 'CHANGEME' +app.config['SECRET_KEY'] = 'CHANGEME' # $ Alert Session(app) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_unsafe.py b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_unsafe.py index 5aeeb6f7003b..c108dfd45611 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_unsafe.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/app_unsafe.py @@ -1,11 +1,11 @@ from flask import Flask, session app = Flask(__name__) -aConstant = 'CHANGEME1' -app.config['SECRET_KEY'] = aConstant -app.secret_key = aConstant -app.config.update(SECRET_KEY=aConstant) -app.config.from_mapping(SECRET_KEY=aConstant) +aConstant = 'CHANGEME1' # $ Source +app.config['SECRET_KEY'] = aConstant # $ Alert +app.secret_key = aConstant # $ Alert +app.config.update(SECRET_KEY=aConstant) # $ Alert +app.config.from_mapping(SECRET_KEY=aConstant) # $ Alert app.config.from_pyfile("config.py") app.config.from_object('config.Config') diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config.py b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config.py index 1a512c0d9f08..12dacb516e62 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config.py @@ -4,16 +4,16 @@ import random FLASK_DEBUG = True -aConstant = 'CHANGEME2' +aConstant = 'CHANGEME2' # $ Source class Config: SECRET_KEY = environ.get("envKey") - SECRET_KEY = aConstant + SECRET_KEY = aConstant # $ Alert SECRET_KEY = os.getenv('envKey') SECRET_KEY = os.environ.get('envKey') SECRET_KEY = os.environ.get('envKey', random.randint) SECRET_KEY = os.getenv('envKey', random.randint) - SECRET_KEY = os.getenv('envKey', aConstant) - SECRET_KEY = os.environ.get('envKey', aConstant) + SECRET_KEY = os.getenv('envKey', aConstant) # $ Alert + SECRET_KEY = os.environ.get('envKey', aConstant) # $ Alert SECRET_KEY = os.environ['envKey'] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config2.py b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config2.py index dc3508783e22..96b08fead125 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config2.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287-ConstantSecretKey/config2.py @@ -2,4 +2,4 @@ # General Config FLASK_DEBUG = True -SECRET_KEY = "CHANGEME5" +SECRET_KEY = "CHANGEME5" # $ Alert diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287/ImproperLdapAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-287/ImproperLdapAuth.qlref index 9f5c6e4c43f4..edd5c17e2b18 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287/ImproperLdapAuth.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-287/ImproperLdapAuth.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-287/ImproperLdapAuth.ql +query: experimental/Security/CWE-287/ImproperLdapAuth.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_2.py b/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_2.py index d37cc09cfd06..ef274090f91a 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_2.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_2.py @@ -16,7 +16,7 @@ def simple_bind_example(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.simple_bind('cn=root') + ldap_connection.simple_bind('cn=root') # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) @@ -30,7 +30,7 @@ def simple_bind_s_example(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.simple_bind_s('cn=root') + ldap_connection.simple_bind_s('cn=root') # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) @@ -44,7 +44,7 @@ def bind_s_example(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.bind_s('cn=root', None) + ldap_connection.bind_s('cn=root', None) # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) @app.route("/bind_s_example") @@ -57,7 +57,7 @@ def bind_s_example_kwargs(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.bind_s(who='cn=root', cred=None) + ldap_connection.bind_s(who='cn=root', cred=None) # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) @app.route("/bind_example") @@ -70,7 +70,7 @@ def bind_example(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.bind('cn=root', "") + ldap_connection.bind('cn=root', "") # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) @@ -84,7 +84,7 @@ def bind_example(): search_filter = "(user={})".format(ldap.filter.escape_filter_chars(request.args['search'])) ldap_connection = ldap.initialize("ldap://127.0.0.1:1337") - ldap_connection.bind(who='cn=root', cred="") + ldap_connection.bind(who='cn=root', cred="") # $ Alert user = ldap_connection.search_s(dn, ldap.SCOPE_SUBTREE, search_filter) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_3.py b/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_3.py index 2500b4cadb6b..3b99754ec401 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_3.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-287/auth_bad_3.py @@ -16,7 +16,7 @@ def passwordNone(): search_filter = "(user={})".format(escape_filter_chars(request.args['search'])) srv = Server('servername', get_info=ALL) - conn = Connection(srv, 'user_dn', None) + conn = Connection(srv, 'user_dn', None) # $ Alert status, result, response, _ = conn.search(dn, search_filter) @@ -30,7 +30,7 @@ def passwordNoneKwargs(): search_filter = "(user={})".format(escape_filter_chars(request.args['search'])) srv = Server('servername', get_info=ALL) - conn = Connection(srv, user='user_dn', password=None) + conn = Connection(srv, user='user_dn', password=None) # $ Alert status, result, response, _ = conn.search(dn, search_filter) @app.route("/passwordEmpty") @@ -43,7 +43,7 @@ def passwordEmpty(): search_filter = "(user={})".format(escape_filter_chars(request.args['search'])) srv = Server('servername', get_info=ALL) - conn = Connection(srv, user='user_dn', password="") + conn = Connection(srv, user='user_dn', password="") # $ Alert status, result, response, _ = conn.search(dn, search_filter) @@ -57,7 +57,7 @@ def notPassword(): search_filter = "(user={})".format(escape_filter_chars(request.args['search'])) srv = Server('servername', get_info=ALL) - conn = Connection(srv, user='user_dn') + conn = Connection(srv, user='user_dn') # $ Alert status, result, response, _ = conn.search(dn, search_filter) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index 097e3580fb1d..8ffc7ac31d9b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -1,3 +1,9 @@ +#select +| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | edges | test.py:3:1:3:3 | ControlFlowNode for BSC | test.py:7:19:7:21 | ControlFlowNode for BSC | provenance | | | test.py:3:1:3:3 | ControlFlowNode for BSC | test.py:35:19:35:21 | ControlFlowNode for BSC | provenance | | @@ -86,9 +92,3 @@ nodes | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | | test.py:75:9:75:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | subpaths -#select -| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref index b737b32c8159..b5ed8a0d6364 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +query: experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py index 32fa60c61930..de1d6a3f5c60 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py @@ -1,6 +1,6 @@ from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient -BSC = BlobServiceClient.from_connection_string(...) +BSC = BlobServiceClient.from_connection_string(...) # $ Source def unsafe(): # does not set encryption_version to 2.0, default is unsafe @@ -8,27 +8,27 @@ def unsafe(): blob_client.require_encryption = True blob_client.key_encryption_key = ... with open("decryptedcontentfile.txt", "rb") as stream: - blob_client.upload_blob(stream) # BAD + blob_client.upload_blob(stream) # $ Alert # BAD def unsafe_setting_on_blob_service_client(): - blob_service_client = BlobServiceClient.from_connection_string(...) + blob_service_client = BlobServiceClient.from_connection_string(...) # $ Source blob_service_client.require_encryption = True blob_service_client.key_encryption_key = ... blob_client = blob_service_client.get_blob_client(...) with open("decryptedcontentfile.txt", "rb") as stream: - blob_client.upload_blob(stream) + blob_client.upload_blob(stream) # $ Alert def unsafe_setting_on_container_client(): - container_client = ContainerClient.from_connection_string(...) + container_client = ContainerClient.from_connection_string(...) # $ Source container_client.require_encryption = True container_client.key_encryption_key = ... blob_client = container_client.get_blob_client(...) with open("decryptedcontentfile.txt", "rb") as stream: - blob_client.upload_blob(stream) + blob_client.upload_blob(stream) # $ Alert def potentially_unsafe(use_new_version=False): @@ -40,7 +40,7 @@ def potentially_unsafe(use_new_version=False): blob_client.encryption_version = '2.0' with open("decryptedcontentfile.txt", "rb") as stream: - blob_client.upload_blob(stream) # BAD + blob_client.upload_blob(stream) # $ Alert # BAD def safe(): @@ -72,7 +72,7 @@ def get_unsafe_blob_client(): def unsafe_with_calls(): bc = get_unsafe_blob_client() with open("decryptedcontentfile.txt", "rb") as stream: - bc.upload_blob(stream) # BAD + bc.upload_blob(stream) # $ Alert # BAD def get_safe_blob_client(): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.py b/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.py index 9f0439549672..ee94baf9eee1 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.py @@ -2,4 +2,4 @@ def generatePassword(): # BAD: the random is not cryptographically secure - return random.random() + return random.random() # $ Alert diff --git a/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.qlref b/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.qlref index 447fc2cf6b25..84cbc2412d91 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-338/InsecureRandomness.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-338/InsecureRandomness.ql \ No newline at end of file +query: experimental/Security/CWE-338/InsecureRandomness.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-346/Cors.py b/python/ql/test/experimental/query-tests/Security/CWE-346/Cors.py index cc12e1273fbb..e01d99bde754 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-346/Cors.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-346/Cors.py @@ -4,8 +4,8 @@ def bad(): request = cherrypy.request validCors = "domain.com" if request.method in ['POST', 'PUT', 'PATCH', 'DELETE']: - origin = request.headers.get('Origin', None) - if origin.startswith(validCors): + origin = request.headers.get('Origin', None) # $ Source + if origin.startswith(validCors): # $ Alert print("Origin Valid") def good(): diff --git a/python/ql/test/experimental/query-tests/Security/CWE-346/CorsBypass.qlref b/python/ql/test/experimental/query-tests/Security/CWE-346/CorsBypass.qlref index b652fd93088b..35c42c39e854 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-346/CorsBypass.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-346/CorsBypass.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-346/CorsBypass.ql \ No newline at end of file +query: experimental/Security/CWE-346/CorsBypass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/JWTEmptyKeyOrAlgorithm.qlref b/python/ql/test/experimental/query-tests/Security/CWE-347/JWTEmptyKeyOrAlgorithm.qlref index fe0d2ea00043..d225e37a0d38 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/JWTEmptyKeyOrAlgorithm.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/JWTEmptyKeyOrAlgorithm.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-347/JWTEmptyKeyOrAlgorithm.ql +query: experimental/Security/CWE-347/JWTEmptyKeyOrAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.qlref b/python/ql/test/experimental/query-tests/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.qlref index d289ff151f42..38402ddd457b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.ql +query: experimental/Security/CWE-347/JWTMissingSecretOrPublicKeyVerification.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/authlib.py b/python/ql/test/experimental/query-tests/Security/CWE-347/authlib.py index 2f7367897033..94eb4a38c875 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/authlib.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/authlib.py @@ -8,8 +8,8 @@ JsonWebToken().encode({"alg": "HS256"}, token, "key") # bad - empty key -jwt.encode({"alg": "HS256"}, token, "") -JsonWebToken().encode({"alg": "HS256"}, token, "") +jwt.encode({"alg": "HS256"}, token, "") # $ Alert[py/jwt-empty-secret-or-algorithm] +JsonWebToken().encode({"alg": "HS256"}, token, "") # $ Alert[py/jwt-empty-secret-or-algorithm] # Decoding diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/pyjwt.py b/python/ql/test/experimental/query-tests/Security/CWE-347/pyjwt.py index 39892b33dcb9..c08375ef9f4f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/pyjwt.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/pyjwt.py @@ -7,11 +7,11 @@ jwt.encode(token, key="key", algorithm="HS256") # bad - both key and algorithm set to None -jwt.encode(token, None, None) +jwt.encode(token, None, None) # $ Alert[py/jwt-empty-secret-or-algorithm] # bad - empty key -jwt.encode(token, "", algorithm="HS256") -jwt.encode(token, key="", algorithm="HS256") +jwt.encode(token, "", algorithm="HS256") # $ Alert[py/jwt-empty-secret-or-algorithm] +jwt.encode(token, key="", algorithm="HS256") # $ Alert[py/jwt-empty-secret-or-algorithm] # Decoding @@ -19,8 +19,8 @@ jwt.decode(token, "key", "HS256") # bad - unverified decoding -jwt.decode(token, verify=False) -jwt.decode(token, key, options={"verify_signature": False}) +jwt.decode(token, verify=False) # $ Alert[py/jwt-missing-verification] +jwt.decode(token, key, options={"verify_signature": False}) # $ Alert[py/jwt-missing-verification] # good - verified decoding jwt.decode(token, verify=True) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/python_jose.py b/python/ql/test/experimental/query-tests/Security/CWE-347/python_jose.py index eeb050184d85..8c2bfe90879b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/python_jose.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/python_jose.py @@ -7,8 +7,8 @@ jwt.encode(token, key="key", algorithm="HS256") # bad - empty key -jwt.encode(token, "", algorithm="HS256") -jwt.encode(token, key="", algorithm="HS256") +jwt.encode(token, "", algorithm="HS256") # $ Alert[py/jwt-empty-secret-or-algorithm] +jwt.encode(token, key="", algorithm="HS256") # $ Alert[py/jwt-empty-secret-or-algorithm] # Decoding @@ -16,7 +16,7 @@ jwt.decode(token, "key", "HS256") # bad - unverified decoding -jwt.decode(token, key, options={"verify_signature": False}) +jwt.decode(token, key, options={"verify_signature": False}) # $ Alert[py/jwt-missing-verification] # good - verified decoding jwt.decode(token, key, options={"verify_signature": True}) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-347/python_jwt.py b/python/ql/test/experimental/query-tests/Security/CWE-347/python_jwt.py index 42a3fc35f075..77e67b2dd904 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-347/python_jwt.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-347/python_jwt.py @@ -11,4 +11,4 @@ def good(token): def bad(token): - python_jwt.process_jwt(token) + python_jwt.process_jwt(token) # $ Alert[py/jwt-missing-verification] diff --git a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.qlref b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.qlref index 2a1775fe06aa..51f11c6dfcdd 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql \ No newline at end of file +query: experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-348/flask_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-348/flask_bad.py index b357a9316fd0..491a13399706 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-348/flask_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-348/flask_bad.py @@ -10,15 +10,15 @@ @app.route('/bad1') def bad1(): - client_ip = request.headers.get('x-forwarded-for') - if not client_ip.startswith('192.168.'): + client_ip = request.headers.get('x-forwarded-for') # $ Source + if not client_ip.startswith('192.168.'): # $ Alert 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': + client_ip = request.headers.get('x-forwarded-for') # $ Source + if not client_ip == '127.0.0.1': # $ Alert raise Exception('ip illegal') return 'bad2' diff --git a/python/ql/test/experimental/query-tests/Security/CWE-348/tornado_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-348/tornado_bad.py index 23ad29d8b09a..9899922d019b 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-348/tornado_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-348/tornado_bad.py @@ -19,8 +19,8 @@ def get(self): 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': + client_ip = self.request.headers.get('REMOTE_ADDR', None) # $ Source + if not client_ip == '127.0.0.1': # $ Alert raise Exception('ip illegal') self.write("hello.") diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref index 7b867cb31867..cd63387a1a70 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-522-global-option/LdapInsecureAuth.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-522/LdapInsecureAuth.ql +query: experimental/Security/CWE-522/LdapInsecureAuth.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref index 7b867cb31867..cd63387a1a70 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/LdapInsecureAuth.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-522/LdapInsecureAuth.ql +query: experimental/Security/CWE-522/LdapInsecureAuth.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/ldap2_remote.py b/python/ql/test/experimental/query-tests/Security/CWE-522/ldap2_remote.py index 3119ca2d28a7..75f5b0b0ea34 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/ldap2_remote.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/ldap2_remote.py @@ -42,7 +42,7 @@ def two(): @app.route("/one_bad") def one_bad(): - ldap_connection_7 = ldap.initialize(schema + remote_host) + ldap_connection_7 = ldap.initialize(schema + remote_host) # $ Alert ldap_connection_7.set_option(ldap.OPT_X_TLS_DEMAND, False) ldap_connection_7.simple_bind_s('', '') user = ldap_connection_7.search_s( @@ -53,7 +53,7 @@ def one_bad(): @app.route("/one_bad_2") def one_bad_2(): - ldap_connection_8 = ldap.initialize(schema + remote_host) + ldap_connection_8 = ldap.initialize(schema + remote_host) # $ Alert ldap_connection_8.set_option(ldap.OPT_X_TLS_NEVER, True) ldap_connection_8.simple_bind_s('', '') user = ldap_connection_8.search_s( diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/ldap3_remote.py b/python/ql/test/experimental/query-tests/Security/CWE-522/ldap3_remote.py index 269e03e41fef..ff5c5998ec23 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/ldap3_remote.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/ldap3_remote.py @@ -1,5 +1,5 @@ from ldap3 import Server, Connection, ALL -from flask import request, Flask +from flask import request, Flask # $ Source app = Flask(__name__) @@ -98,8 +98,8 @@ def seven(): @app.route("/eight") def eight(): - host = schema + "somethingon.theinternet.com" - srv = Server(host, port=1337) + host = schema + "somethingon.theinternet.com" # $ Source + srv = Server(host, port=1337) # $ Alert conn = Connection(srv, "dn", "password") conn.start_tls() conn.search("dn", "search_filter") @@ -111,8 +111,8 @@ def eight(): @app.route("/nine") def nine(): - host = schema + "somethingon.theinternet.com" - srv = Server(host, 1337, False) + host = schema + "somethingon.theinternet.com" # $ Source + srv = Server(host, 1337, False) # $ Alert conn = Connection(srv, "dn", "password") conn.search("dn", "search_filter") return conn.response @@ -123,8 +123,8 @@ def nine(): @app.route("/ten") def ten(): - host = schema + remote_host - srv = Server(host, port=1337, use_ssl=False) + host = schema + remote_host # $ Source + srv = Server(host, port=1337, use_ssl=False) # $ Alert conn = Connection(srv, "dn", "password") conn.search("dn", "search_filter") return conn.response @@ -136,7 +136,7 @@ def ten(): @app.route("/eleven") def eleven(): host = schema + request.args['host'] - srv = Server(host, port=1337) + srv = Server(host, port=1337) # $ Alert conn = Connection(srv, "dn", "password") conn.search("dn", "search_filter") return conn.response diff --git a/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/SimpleXmlRpcServer.qlref b/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/SimpleXmlRpcServer.qlref index a0b30e6d69b8..f9b2ebd03909 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/SimpleXmlRpcServer.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/SimpleXmlRpcServer.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-611/SimpleXmlRpcServer.ql +query: experimental/Security/CWE-611/SimpleXmlRpcServer.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/xmlrpc_server.py b/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/xmlrpc_server.py index 83c18b549b3d..f2463a752bcb 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/xmlrpc_server.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-611-SimpleXmlRpcServer/xmlrpc_server.py @@ -4,7 +4,7 @@ def foo(n: str): print("foo called with arg:", n, type(n)) return "ok" -server = SimpleXMLRPCServer(("127.0.0.1", 8000)) +server = SimpleXMLRPCServer(("127.0.0.1", 8000)) # $ Alert server.register_function(foo, "foo") server.serve_forever() diff --git a/python/ql/test/experimental/query-tests/Security/CWE-770/UnicodeDoS.qlref b/python/ql/test/experimental/query-tests/Security/CWE-770/UnicodeDoS.qlref index aff380880ea0..1124c1683447 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-770/UnicodeDoS.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-770/UnicodeDoS.qlref @@ -1 +1,2 @@ -experimental/Security/CWE-770/UnicodeDoS.ql \ No newline at end of file +query: experimental/Security/CWE-770/UnicodeDoS.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-770/tests.py b/python/ql/test/experimental/query-tests/Security/CWE-770/tests.py index 1007bcc89858..f359cdaca1c9 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-770/tests.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-770/tests.py @@ -1,4 +1,4 @@ -from flask import Flask, jsonify, request +from flask import Flask, jsonify, request # $ Source import unicodedata app = Flask(__name__) @@ -13,7 +13,7 @@ def bad_1(): # Normalize the file path using NFKC Unicode normalization return ( - unicodedata.normalize("NFKC", file_path), + unicodedata.normalize("NFKC", file_path), # $ Alert 200, {"Content-Type": "application/octet-stream"}, ) @@ -25,7 +25,7 @@ def bad_2(): if len(r) >= 10: # Normalize the r using NFKD Unicode normalization - r = unicodedata.normalize("NFKD", r) + r = unicodedata.normalize("NFKD", r) # $ Alert return r, 200, {"Content-Type": "application/octet-stream"} else: return jsonify({"error": "File not found"}), 404 @@ -37,7 +37,7 @@ def bad_3(): length = len(r) if length >= 1_000: # Normalize the r using NFKD Unicode normalization - r = unicodedata.normalize("NFKD", r) + r = unicodedata.normalize("NFKD", r) # $ Alert return r, 200, {"Content-Type": "application/octet-stream"} else: return jsonify({"error": "File not found"}), 404 @@ -49,7 +49,7 @@ def bad_4(): length = len(r) if 1_000 <= length: # Normalize the r using NFKD Unicode normalization - r = unicodedata.normalize("NFKD", r) + r = unicodedata.normalize("NFKD", r) # $ Alert return r, 200, {"Content-Type": "application/octet-stream"} else: return jsonify({"error": "File not found"}), 404 @@ -61,7 +61,7 @@ def bad_5(): length = len(r) if not length < 1_000: # Normalize the r using NFKD Unicode normalization - r = unicodedata.normalize("NFKD", r) + r = unicodedata.normalize("NFKD", r) # $ Alert return r, 200, {"Content-Type": "application/octet-stream"} else: return jsonify({"error": "File not found"}), 404 @@ -73,7 +73,7 @@ def bad_6(): length = len(r) if not 1_000 > length: # Normalize the r using NFKD Unicode normalization - r = unicodedata.normalize("NFKD", r) + r = unicodedata.normalize("NFKD", r) # $ Alert return r, 200, {"Content-Type": "application/octet-stream"} else: return jsonify({"error": "File not found"}), 404 diff --git a/python/ql/test/extractor-tests/overlay/basic-overlay-eval/test.qlref b/python/ql/test/extractor-tests/overlay/basic-overlay-eval/test.qlref index 961494fbda1e..7b04068222b4 100644 --- a/python/ql/test/extractor-tests/overlay/basic-overlay-eval/test.qlref +++ b/python/ql/test/extractor-tests/overlay/basic-overlay-eval/test.qlref @@ -1 +1 @@ -../basic-full-eval/test.ql +query: ../basic-full-eval/test.ql diff --git a/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref index 58bedc4c88cf..e555b1a31260 100644 --- a/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref +++ b/python/ql/test/library-tests/dataflow/coverage-py2/argumentRoutingTest.qlref @@ -1 +1 @@ -../coverage/argumentRoutingTest.ql +query: ../coverage/argumentRoutingTest.ql diff --git a/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref index 58bedc4c88cf..e555b1a31260 100644 --- a/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref +++ b/python/ql/test/library-tests/dataflow/coverage-py3/argumentRoutingTest.qlref @@ -1 +1 @@ -../coverage/argumentRoutingTest.ql +query: ../coverage/argumentRoutingTest.ql diff --git a/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref index 2c005903470f..30e4cf2cc46a 100644 --- a/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref +++ b/python/ql/test/library-tests/dataflow/typetracking_imports/tracked.qlref @@ -1 +1 @@ -../typetracking/tracked.ql +query: ../typetracking/tracked.ql diff --git a/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.qlref b/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.qlref index e0efe1024162..52f5dddc6c6d 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.qlref +++ b/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.qlref @@ -1 +1 @@ -Security/CWE-079/ReflectedXss.ql +query: Security/CWE-079/ReflectedXss.ql diff --git a/python/ql/test/library-tests/frameworks/gradio/taint_step_test.qlref b/python/ql/test/library-tests/frameworks/gradio/taint_step_test.qlref index d43482cc509e..ee6206aa2325 100644 --- a/python/ql/test/library-tests/frameworks/gradio/taint_step_test.qlref +++ b/python/ql/test/library-tests/frameworks/gradio/taint_step_test.qlref @@ -1 +1 @@ -Security/CWE-022/PathInjection.ql +query: Security/CWE-022/PathInjection.ql diff --git a/python/ql/test/modelling/FrameworkModeEndpoints.qlref b/python/ql/test/modelling/FrameworkModeEndpoints.qlref index 5ae87455edd6..ec216021687b 100644 --- a/python/ql/test/modelling/FrameworkModeEndpoints.qlref +++ b/python/ql/test/modelling/FrameworkModeEndpoints.qlref @@ -1 +1 @@ -utils/modeleditor/FrameworkModeEndpoints.ql \ No newline at end of file +query: utils/modeleditor/FrameworkModeEndpoints.ql diff --git a/python/ql/test/query-tests/Classes/Arguments/WrongNameForArgumentInClassInstantiation.qlref b/python/ql/test/query-tests/Classes/Arguments/WrongNameForArgumentInClassInstantiation.qlref index 408766dcbf4d..e093d3ebd685 100644 --- a/python/ql/test/query-tests/Classes/Arguments/WrongNameForArgumentInClassInstantiation.qlref +++ b/python/ql/test/query-tests/Classes/Arguments/WrongNameForArgumentInClassInstantiation.qlref @@ -1 +1,2 @@ -Classes/WrongNameForArgumentInClassInstantiation.ql \ No newline at end of file +query: Classes/WrongNameForArgumentInClassInstantiation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/Arguments/WrongNumberArgumentsInClassInstantiation.qlref b/python/ql/test/query-tests/Classes/Arguments/WrongNumberArgumentsInClassInstantiation.qlref index 4fdda20e1636..cbf14318e592 100644 --- a/python/ql/test/query-tests/Classes/Arguments/WrongNumberArgumentsInClassInstantiation.qlref +++ b/python/ql/test/query-tests/Classes/Arguments/WrongNumberArgumentsInClassInstantiation.qlref @@ -1 +1,2 @@ -Classes/WrongNumberArgumentsInClassInstantiation.ql \ No newline at end of file +query: Classes/WrongNumberArgumentsInClassInstantiation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/Arguments/wrong_arguments.py b/python/ql/test/query-tests/Classes/Arguments/wrong_arguments.py index 7363fdebef4e..5c03d0b08496 100644 --- a/python/ql/test/query-tests/Classes/Arguments/wrong_arguments.py +++ b/python/ql/test/query-tests/Classes/Arguments/wrong_arguments.py @@ -34,22 +34,22 @@ def __init__(self, x, y, z): # Too few arguments -F0() -F1() -F2() -F3() -F4() -F5() -F6(1) -F7(1,2) +F0() # $ Alert[py/call/wrong-number-class-arguments] +F1() # $ Alert[py/call/wrong-number-class-arguments] +F2() # $ Alert[py/call/wrong-number-class-arguments] +F3() # $ Alert[py/call/wrong-number-class-arguments] +F4() # $ Alert[py/call/wrong-number-class-arguments] +F5() # $ Alert[py/call/wrong-number-class-arguments] +F6(1) # $ Alert[py/call/wrong-number-class-arguments] +F7(1,2) # $ Alert[py/call/wrong-number-class-arguments] #Too many arguments -F0(1,2) -F1(1,2,3) -F5(1,2,3) -F6(1,2,3) -F6(1,2,3,4) +F0(1,2) # $ Alert[py/call/wrong-number-class-arguments] +F1(1,2,3) # $ Alert[py/call/wrong-number-class-arguments] +F5(1,2,3) # $ Alert[py/call/wrong-number-class-arguments] +F6(1,2,3) # $ Alert[py/call/wrong-number-class-arguments] +F6(1,2,3,4) # $ Alert[py/call/wrong-number-class-arguments] #OK @@ -62,9 +62,9 @@ def __init__(self, x, y, z): #Illegal name -F0(y=1) -F1(z=1) -F2(x=0, y=1) +F0(y=1) # $ Alert[py/call/wrong-named-class-argument] +F1(z=1) # $ Alert[py/call/wrong-named-class-argument] +F2(x=0, y=1) # $ Alert[py/call/wrong-named-class-argument] #Ok name @@ -82,12 +82,12 @@ def __init__(self, x, y, z): f(*t2) #Too many -F6(*(1,2,3)) -F6(*t3) +F6(*(1,2,3)) # $ Alert[py/call/wrong-number-class-arguments] +F6(*t3) # $ Alert[py/call/wrong-number-class-arguments] #Ok F6(**{'x':1, 'y':2}) #Illegal name -F6(**{'x':1, 'y':2, 'z':3}) +F6(**{'x':1, 'y':2, 'z':3}) # $ Alert[py/call/wrong-named-class-argument] diff --git a/python/ql/test/query-tests/Classes/conflicting/ConflictingAttributesInBaseClasses.qlref b/python/ql/test/query-tests/Classes/conflicting/ConflictingAttributesInBaseClasses.qlref index 3d6fa6534c5c..efd0250ca2eb 100644 --- a/python/ql/test/query-tests/Classes/conflicting/ConflictingAttributesInBaseClasses.qlref +++ b/python/ql/test/query-tests/Classes/conflicting/ConflictingAttributesInBaseClasses.qlref @@ -1 +1,2 @@ -Classes/ConflictingAttributesInBaseClasses.ql \ No newline at end of file +query: Classes/ConflictingAttributesInBaseClasses.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/conflicting/test.py b/python/ql/test/query-tests/Classes/conflicting/test.py index 624cea77ce5b..4bb75114034f 100644 --- a/python/ql/test/query-tests/Classes/conflicting/test.py +++ b/python/ql/test/query-tests/Classes/conflicting/test.py @@ -23,7 +23,7 @@ def meth(self): return 0 -class Conflict(CB1, CB2): +class Conflict(CB1, CB2): # $ Alert pass class Override1(Common): diff --git a/python/ql/test/query-tests/Classes/descriptors/MutatingDescriptor.qlref b/python/ql/test/query-tests/Classes/descriptors/MutatingDescriptor.qlref index 08449405ad61..17ec44acc881 100644 --- a/python/ql/test/query-tests/Classes/descriptors/MutatingDescriptor.qlref +++ b/python/ql/test/query-tests/Classes/descriptors/MutatingDescriptor.qlref @@ -1 +1,2 @@ -Classes/MutatingDescriptor.ql +query: Classes/MutatingDescriptor.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/descriptors/test.py b/python/ql/test/query-tests/Classes/descriptors/test.py index 180ade50e366..b33ae25440f2 100644 --- a/python/ql/test/query-tests/Classes/descriptors/test.py +++ b/python/ql/test/query-tests/Classes/descriptors/test.py @@ -7,7 +7,7 @@ def __init__(self, func): def __get__(self, obj, obj_type): #Modified state is visible to all instances. - self.my_obj = obj + self.my_obj = obj # $ Alert return self def __call__(self, *args): @@ -22,4 +22,4 @@ def __set__(self, obj, value): def not_ok(self, value): #Modified state is visible to all instances. - self.my_obj = value + self.my_obj = value # $ Alert diff --git a/python/ql/test/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref b/python/ql/test/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref index e542a6176ad4..f3385f506bf2 100644 --- a/python/ql/test/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref +++ b/python/ql/test/query-tests/Classes/equals-attr/DefineEqualsWhenAddingAttributes.qlref @@ -1 +1,2 @@ -Classes/DefineEqualsWhenAddingAttributes.ql \ No newline at end of file +query: Classes/DefineEqualsWhenAddingAttributes.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/equals-attr/attr_eq_test.py b/python/ql/test/query-tests/Classes/equals-attr/attr_eq_test.py index e1e545fe9ef5..a5b1857f878f 100644 --- a/python/ql/test/query-tests/Classes/equals-attr/attr_eq_test.py +++ b/python/ql/test/query-tests/Classes/equals-attr/attr_eq_test.py @@ -18,7 +18,7 @@ def __ne__(self, other): def __hash__(self): return hash((self._x, self._y)) -class BadColorPoint(Point): +class BadColorPoint(Point): # $ Alert def __init__(self, x, y, color): Point.__init__(self, x, y) diff --git a/python/ql/test/query-tests/Classes/init-calls-subclass-method/InitCallsSubclassMethod.qlref b/python/ql/test/query-tests/Classes/init-calls-subclass-method/InitCallsSubclassMethod.qlref index 6530409f90ac..c396a4dbc3d7 100644 --- a/python/ql/test/query-tests/Classes/init-calls-subclass-method/InitCallsSubclassMethod.qlref +++ b/python/ql/test/query-tests/Classes/init-calls-subclass-method/InitCallsSubclassMethod.qlref @@ -1 +1,2 @@ -Classes/InitCallsSubclass/InitCallsSubclassMethod.ql +query: Classes/InitCallsSubclass/InitCallsSubclassMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/init-calls-subclass-method/init_calls_subclass.py b/python/ql/test/query-tests/Classes/init-calls-subclass-method/init_calls_subclass.py index ef944a9c7ef5..626f11b1f226 100644 --- a/python/ql/test/query-tests/Classes/init-calls-subclass-method/init_calls_subclass.py +++ b/python/ql/test/query-tests/Classes/init-calls-subclass-method/init_calls_subclass.py @@ -5,7 +5,7 @@ class Super: def __init__(self, arg): self._state = "Not OK" - self.set_up(arg) # BAD: set_up is overriden. + self.set_up(arg) # $ Alert # BAD: set_up is overriden. self._state = "OK" def set_up(self, arg): @@ -29,7 +29,7 @@ def __init__(self, arg): self.a = arg # BAD: postproc is called after initialization. This is still an issue # since it may still occur before all initialization on a subclass is complete. - self.postproc() + self.postproc() # $ Alert def postproc(self): if self.a == 1: @@ -72,4 +72,4 @@ def _set_b(self): class Sub(Super): def _set_b(self): - self.b = self.a+1 \ No newline at end of file + self.b = self.a+1 diff --git a/python/ql/test/query-tests/Classes/overwriting-attribute/OverwritingAttributeInSuperClass.qlref b/python/ql/test/query-tests/Classes/overwriting-attribute/OverwritingAttributeInSuperClass.qlref index b29c4d250250..dcea036ee608 100644 --- a/python/ql/test/query-tests/Classes/overwriting-attribute/OverwritingAttributeInSuperClass.qlref +++ b/python/ql/test/query-tests/Classes/overwriting-attribute/OverwritingAttributeInSuperClass.qlref @@ -1 +1,2 @@ -Classes/OverwritingAttributeInSuperClass.ql +query: Classes/OverwritingAttributeInSuperClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/overwriting-attribute/overwriting_attribute.py b/python/ql/test/query-tests/Classes/overwriting-attribute/overwriting_attribute.py index 0372db0b2159..a17bfd662d8c 100644 --- a/python/ql/test/query-tests/Classes/overwriting-attribute/overwriting_attribute.py +++ b/python/ql/test/query-tests/Classes/overwriting-attribute/overwriting_attribute.py @@ -2,7 +2,7 @@ class C(object): def __init__(self): - self.var = 0 + self.var = 0 # $ Alert class D(C): @@ -20,4 +20,4 @@ class F(E): def __init__(self): E.__init__(self) - self.var = 1 + self.var = 1 # $ Alert diff --git a/python/ql/test/query-tests/Classes/should-be-context-manager/ShouldBeContextManager.qlref b/python/ql/test/query-tests/Classes/should-be-context-manager/ShouldBeContextManager.qlref index f555b0af07a3..b13b7d8b7b9a 100644 --- a/python/ql/test/query-tests/Classes/should-be-context-manager/ShouldBeContextManager.qlref +++ b/python/ql/test/query-tests/Classes/should-be-context-manager/ShouldBeContextManager.qlref @@ -1 +1,2 @@ -Classes/ShouldBeContextManager.ql \ No newline at end of file +query: Classes/ShouldBeContextManager.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/should-be-context-manager/should_be_context_manager.py b/python/ql/test/query-tests/Classes/should-be-context-manager/should_be_context_manager.py index 68fc81206a37..869d19f3d862 100644 --- a/python/ql/test/query-tests/Classes/should-be-context-manager/should_be_context_manager.py +++ b/python/ql/test/query-tests/Classes/should-be-context-manager/should_be_context_manager.py @@ -1,6 +1,6 @@ #Should be context manager -class MegaDel(object): +class MegaDel(object): # $ Alert def __del__(self): a = self.x + self.y @@ -13,7 +13,7 @@ def __del__(self): sum += a print(sum) -class MiniDel(object): +class MiniDel(object): # $ Alert def close(self): pass diff --git a/python/ql/test/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref b/python/ql/test/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref index d4986ffc84ce..35f6da7add55 100644 --- a/python/ql/test/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref +++ b/python/ql/test/query-tests/Classes/undefined-attribute/MaybeUndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/MaybeUndefinedClassAttribute.ql +query: Classes/MaybeUndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref b/python/ql/test/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref index 7ac0a3b18b77..f0e8fb722784 100644 --- a/python/ql/test/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref +++ b/python/ql/test/query-tests/Classes/undefined-attribute/UndefinedClassAttribute.qlref @@ -1 +1,2 @@ -Classes/UndefinedClassAttribute.ql +query: Classes/UndefinedClassAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/undefined-attribute/undefined_attribute.py b/python/ql/test/query-tests/Classes/undefined-attribute/undefined_attribute.py index 0eec9974ef15..207e8f837d65 100644 --- a/python/ql/test/query-tests/Classes/undefined-attribute/undefined_attribute.py +++ b/python/ql/test/query-tests/Classes/undefined-attribute/undefined_attribute.py @@ -21,10 +21,10 @@ def ok3(self): print (self.local_exists) def neca1(self): - print (self.not_exists) + print (self.not_exists) # $ Alert[py/undefined-attribute] def neca2(self): - print (self.may_exist) + print (self.may_exist) # $ Alert[py/maybe-undefined-attribute] #This is OK class SetViaDict(object): @@ -106,7 +106,7 @@ def use(self): class NoInit(object): def use_y(self): - return self.y + return self.y # $ Alert[py/undefined-attribute] #This is also OK class SetLocally2(object): @@ -181,7 +181,7 @@ def queue_declared(frame): # called in callback self.return_queue = frame.method.queue def use_it(self): - return self.return_queue + return self.return_queue # $ Alert[py/maybe-undefined-attribute] #Check for FPs when overriding builtin methods @@ -247,15 +247,15 @@ def x(self): class Odasa4619a(object): def call(self): - host = self.glance_host - port = self.glance_port + host = self.glance_host # $ Alert[py/undefined-attribute] + port = self.glance_port # $ Alert[py/undefined-attribute] class Odasa4619b(object): def call(self): - host = self.glance_host - port = self.glance_port + host = self.glance_host # $ Alert[py/maybe-undefined-attribute] + port = self.glance_port # $ Alert[py/maybe-undefined-attribute] @decorator def foo(self): diff --git a/python/ql/test/query-tests/Classes/useless/UselessClass.qlref b/python/ql/test/query-tests/Classes/useless/UselessClass.qlref index 9c8e87e962cd..6dac346e62bb 100644 --- a/python/ql/test/query-tests/Classes/useless/UselessClass.qlref +++ b/python/ql/test/query-tests/Classes/useless/UselessClass.qlref @@ -1 +1,2 @@ -Classes/UselessClass.ql +query: Classes/UselessClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Classes/useless/test.py b/python/ql/test/query-tests/Classes/useless/test.py index 40c9e56e117e..063da81c1727 100644 --- a/python/ql/test/query-tests/Classes/useless/test.py +++ b/python/ql/test/query-tests/Classes/useless/test.py @@ -25,7 +25,7 @@ def do_something_else(self): pass -class Useless1(object): +class Useless1(object): # $ Alert def __init__(self): pass @@ -34,7 +34,7 @@ def do_something(self): pass -class Useless2(object): +class Useless2(object): # $ Alert def do_something(self): pass diff --git a/python/ql/test/query-tests/Diagnostics/ExtractedFiles.qlref b/python/ql/test/query-tests/Diagnostics/ExtractedFiles.qlref index e900e9c5314b..58bc903a431d 100644 --- a/python/ql/test/query-tests/Diagnostics/ExtractedFiles.qlref +++ b/python/ql/test/query-tests/Diagnostics/ExtractedFiles.qlref @@ -1 +1 @@ -Diagnostics/ExtractedFiles.ql +query: Diagnostics/ExtractedFiles.ql diff --git a/python/ql/test/query-tests/Diagnostics/ExtractionWarnings.qlref b/python/ql/test/query-tests/Diagnostics/ExtractionWarnings.qlref index 2df3d933e8ae..68969e9bbf1c 100644 --- a/python/ql/test/query-tests/Diagnostics/ExtractionWarnings.qlref +++ b/python/ql/test/query-tests/Diagnostics/ExtractionWarnings.qlref @@ -1 +1 @@ -Diagnostics/ExtractionWarnings.ql +query: Diagnostics/ExtractionWarnings.ql diff --git a/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.qlref b/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.qlref index 5588dbf2c7b4..bd98ca75af11 100644 --- a/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.qlref +++ b/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.qlref @@ -1 +1 @@ -Exceptions/CatchingBaseException.ql \ No newline at end of file +query: Exceptions/CatchingBaseException.ql diff --git a/python/ql/test/query-tests/Exceptions/general/EmptyExcept.qlref b/python/ql/test/query-tests/Exceptions/general/EmptyExcept.qlref index 3f4987046b12..16e16f16ba5a 100644 --- a/python/ql/test/query-tests/Exceptions/general/EmptyExcept.qlref +++ b/python/ql/test/query-tests/Exceptions/general/EmptyExcept.qlref @@ -1 +1 @@ -Exceptions/EmptyExcept.ql \ No newline at end of file +query: Exceptions/EmptyExcept.ql diff --git a/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref b/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref index 6d49710a7599..7a7911ca4403 100644 --- a/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref +++ b/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.qlref @@ -1 +1,2 @@ -Exceptions/IllegalExceptionHandlerType.ql \ No newline at end of file +query: Exceptions/IllegalExceptionHandlerType.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Exceptions/general/IllegalRaise.qlref b/python/ql/test/query-tests/Exceptions/general/IllegalRaise.qlref index 5a515d5656d3..2bee772260a9 100644 --- a/python/ql/test/query-tests/Exceptions/general/IllegalRaise.qlref +++ b/python/ql/test/query-tests/Exceptions/general/IllegalRaise.qlref @@ -1 +1,2 @@ -Exceptions/IllegalRaise.ql \ No newline at end of file +query: Exceptions/IllegalRaise.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.qlref b/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.qlref index 61ac527ffb99..a5e0761210e7 100644 --- a/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.qlref +++ b/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.qlref @@ -1 +1,2 @@ -Exceptions/NotImplementedIsNotAnException.ql \ No newline at end of file +query: Exceptions/NotImplementedIsNotAnException.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py index e5e9ea67a6e0..2b2c2accf6e4 100644 --- a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py +++ b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py @@ -37,21 +37,21 @@ class NotException2(object): pass def illegal_raise_type(): - raise NotException1 + raise NotException1 # $ Alert[py/illegal-raise] def illegal_raise_value1(): - raise "Exception" + raise "Exception" # $ Alert[py/illegal-raise] def illegal_raise_value2(): - raise NotException2() + raise NotException2() # $ Alert[py/illegal-raise] def illegal_handler(): try: illegal_raise() - except NotException1: + except NotException1: # $ Alert[py/useless-except] #Must do something print("NotException1") - except NotException2: + except NotException2: # $ Alert[py/useless-except] #Must do something print("NotException2") @@ -135,7 +135,7 @@ def a_number(): def illegal_handler2(): try: illegal_raise() - except a_number(): + except a_number(): # $ Alert[py/useless-except] print ("Caught exception") def stop_iter_ok(seq): @@ -193,7 +193,7 @@ def ee8(x): #These are so common, we give warnings not errors. def foo(): - raise NotImplemented + raise NotImplemented # $ Alert[py/raise-not-implemented] def bar(): - raise NotImplemented() + raise NotImplemented() # $ Alert[py/raise-not-implemented] diff --git a/python/ql/test/query-tests/Exceptions/general/pypy_test.py b/python/ql/test/query-tests/Exceptions/general/pypy_test.py index 857e78d6d942..12d373e428e6 100644 --- a/python/ql/test/query-tests/Exceptions/general/pypy_test.py +++ b/python/ql/test/query-tests/Exceptions/general/pypy_test.py @@ -11,10 +11,9 @@ def __getattribute__(self, name): try: a = A() raise a - except 42: + except 42: # $ Alert[py/useless-except] #Some comment pass except A: #Another comment pass - diff --git a/python/ql/test/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref b/python/ql/test/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref index 3599f204f55e..c6b6ca3d30fa 100644 --- a/python/ql/test/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref +++ b/python/ql/test/query-tests/Expressions/Arguments/WrongNameForArgumentInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNameForArgumentInCall.ql \ No newline at end of file +query: Expressions/WrongNameForArgumentInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref b/python/ql/test/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref index 1bffe8f1cad4..68dc510d5c6e 100644 --- a/python/ql/test/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref +++ b/python/ql/test/query-tests/Expressions/Arguments/WrongNumberArgumentsInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNumberArgumentsInCall.ql \ No newline at end of file +query: Expressions/WrongNumberArgumentsInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Arguments/use_mox.py b/python/ql/test/query-tests/Expressions/Arguments/use_mox.py index 35d35574895a..0af38ad3798c 100644 --- a/python/ql/test/query-tests/Expressions/Arguments/use_mox.py +++ b/python/ql/test/query-tests/Expressions/Arguments/use_mox.py @@ -25,9 +25,9 @@ def m1(self, x, y): #But normal functions are treated normally -f0() -f1(1) +f0() # $ Alert[py/call/wrong-arguments] +f1(1) # $ Alert[py/call/wrong-arguments] #As are normal methods -C().m0() -C().m1(1) +C().m0() # $ Alert[py/call/wrong-arguments] +C().m1(1) # $ Alert[py/call/wrong-arguments] diff --git a/python/ql/test/query-tests/Expressions/Arguments/wrong_arguments.py b/python/ql/test/query-tests/Expressions/Arguments/wrong_arguments.py index 284d1d19bc36..dffafbeee764 100644 --- a/python/ql/test/query-tests/Expressions/Arguments/wrong_arguments.py +++ b/python/ql/test/query-tests/Expressions/Arguments/wrong_arguments.py @@ -26,22 +26,22 @@ def f7(x, y, z): # Too few arguments -f0() -f1() -f2() -f3() -f4() -f5() -f6(1) -f7(1,2) +f0() # $ Alert[py/call/wrong-arguments] +f1() # $ Alert[py/call/wrong-arguments] +f2() # $ Alert[py/call/wrong-arguments] +f3() # $ Alert[py/call/wrong-arguments] +f4() # $ Alert[py/call/wrong-arguments] +f5() # $ Alert[py/call/wrong-arguments] +f6(1) # $ Alert[py/call/wrong-arguments] +f7(1,2) # $ Alert[py/call/wrong-arguments] #Too many arguments -f0(1,2) -f1(1,2,3) -f5(1,2,3) -f6(1,2,3) -f6(1,2,3,4) +f0(1,2) # $ Alert[py/call/wrong-arguments] +f1(1,2,3) # $ Alert[py/call/wrong-arguments] +f5(1,2,3) # $ Alert[py/call/wrong-arguments] +f6(1,2,3) # $ Alert[py/call/wrong-arguments] +f6(1,2,3,4) # $ Alert[py/call/wrong-arguments] #OK @@ -54,9 +54,9 @@ def f7(x, y, z): #Illegal name -f0(y=1) -f1(z=1) -f2(x=0, y=1) +f0(y=1) # $ Alert[py/call/wrong-named-argument] +f1(z=1) # $ Alert[py/call/wrong-named-argument] +f2(x=0, y=1) # $ Alert[py/call/wrong-named-argument] #Ok name @@ -78,12 +78,12 @@ def f7(x, y, z): l1d(1) #Too many -l0(1) -l1(1,2) -l1d(1,2) +l0(1) # $ Alert[py/call/wrong-arguments] +l1(1,2) # $ Alert[py/call/wrong-arguments] +l1d(1,2) # $ Alert[py/call/wrong-arguments] #Too few -l1() +l1() # $ Alert[py/call/wrong-arguments] t2 = (1,2) @@ -93,14 +93,14 @@ def f7(x, y, z): f(*t2) #Too many -f6(*(1,2,3)) -f6(*t3) +f6(*(1,2,3)) # $ Alert[py/call/wrong-arguments] +f6(*t3) # $ Alert[py/call/wrong-arguments] #Ok f6(**{'x':1, 'y':2}) #Illegal name -f6(**{'x':1, 'y':2, 'z':3}) +f6(**{'x':1, 'y':2, 'z':3}) # $ Alert[py/call/wrong-named-argument] #Theoretically -1 arguments required. Don't report class C(object): @@ -112,7 +112,7 @@ def f(): #Too many and wrong name -- check only wrong name is flagged. -f1(x, y, z=1) +f1(x, y, z=1) # $ Alert[py/call/wrong-named-argument] #Overriding and call is wrong. @@ -127,5 +127,5 @@ def spam(self, arg0, arg1): pass e = Eggs1() if cond else Eggs2() -e.spam(0) +e.spam(0) # $ Alert[py/call/wrong-arguments] diff --git a/python/ql/test/query-tests/Expressions/Formatting/MixedExplicitImplicitIn3101Format.qlref b/python/ql/test/query-tests/Expressions/Formatting/MixedExplicitImplicitIn3101Format.qlref index 3b9a8dc0ccf9..044e500615f5 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/MixedExplicitImplicitIn3101Format.qlref +++ b/python/ql/test/query-tests/Expressions/Formatting/MixedExplicitImplicitIn3101Format.qlref @@ -1 +1,2 @@ -Expressions/Formatting/MixedExplicitImplicitIn3101Format.ql \ No newline at end of file +query: Expressions/Formatting/MixedExplicitImplicitIn3101Format.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Formatting/UnusedArgumentIn3101Format.qlref b/python/ql/test/query-tests/Expressions/Formatting/UnusedArgumentIn3101Format.qlref index b3e654ad0526..8de137448b61 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/UnusedArgumentIn3101Format.qlref +++ b/python/ql/test/query-tests/Expressions/Formatting/UnusedArgumentIn3101Format.qlref @@ -1 +1,2 @@ -Expressions/Formatting/UnusedArgumentIn3101Format.ql \ No newline at end of file +query: Expressions/Formatting/UnusedArgumentIn3101Format.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Formatting/UnusedNamedArgumentIn3101Format.qlref b/python/ql/test/query-tests/Expressions/Formatting/UnusedNamedArgumentIn3101Format.qlref index 6a77d8910797..a1e71b6cd8b9 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/UnusedNamedArgumentIn3101Format.qlref +++ b/python/ql/test/query-tests/Expressions/Formatting/UnusedNamedArgumentIn3101Format.qlref @@ -1 +1,2 @@ -Expressions/Formatting/UnusedNamedArgumentIn3101Format.ql \ No newline at end of file +query: Expressions/Formatting/UnusedNamedArgumentIn3101Format.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Formatting/WrongNameInArgumentsFor3101Format.qlref b/python/ql/test/query-tests/Expressions/Formatting/WrongNameInArgumentsFor3101Format.qlref index e0b308870342..6bd5b9c75dad 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/WrongNameInArgumentsFor3101Format.qlref +++ b/python/ql/test/query-tests/Expressions/Formatting/WrongNameInArgumentsFor3101Format.qlref @@ -1 +1,2 @@ -Expressions/Formatting/WrongNameInArgumentsFor3101Format.ql \ No newline at end of file +query: Expressions/Formatting/WrongNameInArgumentsFor3101Format.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Formatting/WrongNumberArgumentsFor3101Format.qlref b/python/ql/test/query-tests/Expressions/Formatting/WrongNumberArgumentsFor3101Format.qlref index 130a6525a901..02168e01c644 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/WrongNumberArgumentsFor3101Format.qlref +++ b/python/ql/test/query-tests/Expressions/Formatting/WrongNumberArgumentsFor3101Format.qlref @@ -1 +1,2 @@ -Expressions/Formatting/WrongNumberArgumentsFor3101Format.ql \ No newline at end of file +query: Expressions/Formatting/WrongNumberArgumentsFor3101Format.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Formatting/test.py b/python/ql/test/query-tests/Expressions/Formatting/test.py index e9fd23c8aad6..3117a9de2a48 100755 --- a/python/ql/test/query-tests/Expressions/Formatting/test.py +++ b/python/ql/test/query-tests/Expressions/Formatting/test.py @@ -1,11 +1,11 @@ from __future__ import unicode_literals -mixed_format1 = "{}{1}" +mixed_format1 = "{}{1}" # $ Alert[py/str-format/mixed-fields] named_format1 = "{name!r}, {0}" explicit_format1 = "{0}, {1}" implicit_format1 = "{}, {}" -mixed_format2 = "{}{1}" +mixed_format2 = "{}{1}" # $ Alert[py/str-format/mixed-fields] named_format2 = "{name!r}, {0}" explicit_format2 = "{0}, {1}" implicit_format2 = "{}, {}" @@ -14,23 +14,23 @@ mixed_format1.format("Hello", "World") format(mixed_format2, "Hello", "World") -named_format1.format("Hello", world="World") -format(named_format2, "Hello", world="World") +named_format1.format("Hello", world="World") # $ Alert[py/str-format/missing-named-argument] Alert[py/str-format/surplus-named-argument] +format(named_format2, "Hello", world="World") # $ Alert[py/str-format/missing-named-argument] Alert[py/str-format/surplus-named-argument] -named_format1.format(name="Hello", world="World") -format(named_format2, name="Hello", world="World") +named_format1.format(name="Hello", world="World") # $ Alert[py/str-format/missing-argument] Alert[py/str-format/surplus-named-argument] +format(named_format2, name="Hello", world="World") # $ Alert[py/str-format/missing-argument] Alert[py/str-format/surplus-named-argument] -explicit_format1.format("Hello") -format(explicit_format2, "Hello") +explicit_format1.format("Hello") # $ Alert[py/str-format/missing-argument] +format(explicit_format2, "Hello") # $ Alert[py/str-format/missing-argument] -implicit_format1.format("Hello") -format(implicit_format2, "Hello") +implicit_format1.format("Hello") # $ Alert[py/str-format/missing-argument] +format(implicit_format2, "Hello") # $ Alert[py/str-format/missing-argument] -explicit_format1.format("Hello", "World", "Extra") -format(explicit_format2, "Hello", "World", "Extra") +explicit_format1.format("Hello", "World", "Extra") # $ Alert[py/str-format/surplus-argument] +format(explicit_format2, "Hello", "World", "Extra") # $ Alert[py/str-format/surplus-argument] -implicit_format1.format("Hello", "World", "Extra") -format(implicit_format2, "Hello", "World", "Extra") +implicit_format1.format("Hello", "World", "Extra") # $ Alert[py/str-format/surplus-argument] +format(implicit_format2, "Hello", "World", "Extra") # $ Alert[py/str-format/surplus-argument] #OK ODASA-3197 if cond: @@ -42,8 +42,8 @@ x_or_y.format(x="x", y="y") #Still fail for multiple formats -format(x_or_y, x="x", y="y", z="z") -x_or_y.format(x="x", y="y", z="z") +format(x_or_y, x="x", y="y", z="z") # $ Alert[py/str-format/surplus-named-argument] +x_or_y.format(x="x", y="y", z="z") # $ Alert[py/str-format/surplus-named-argument] #False positive reported by customer. -- Verify fix. "{{}}>".format(html_class) diff --git a/python/ql/test/query-tests/Expressions/Formatting/unknown_format_string.py b/python/ql/test/query-tests/Expressions/Formatting/unknown_format_string.py index a3b32a504db3..690716e20b2d 100644 --- a/python/ql/test/query-tests/Expressions/Formatting/unknown_format_string.py +++ b/python/ql/test/query-tests/Expressions/Formatting/unknown_format_string.py @@ -6,7 +6,7 @@ def possibly_unknown_format_string1(x): fmt = user_specified else: fmt = "{a}" - return fmt.format(a=1,b=2) + return fmt.format(a=1,b=2) # $ Alert[py/str-format/surplus-named-argument] def possibly_unknown_format_string2(x): user_specified = input() @@ -14,7 +14,7 @@ def possibly_unknown_format_string2(x): fmt = user_specified else: fmt = "{a}" - return fmt.format(a=1,b=2) + return fmt.format(a=1,b=2) # $ Alert[py/str-format/surplus-named-argument] def possibly_unknown_format_string3(x): @@ -22,4 +22,4 @@ def possibly_unknown_format_string3(x): fmt = input() else: fmt = "{a}" - return fmt.format(a=1,b=2) + return fmt.format(a=1,b=2) # $ Alert[py/str-format/surplus-named-argument] diff --git a/python/ql/test/query-tests/Expressions/Regex/BackspaceEscape.qlref b/python/ql/test/query-tests/Expressions/Regex/BackspaceEscape.qlref index 2bf85f8a45aa..25a46ec7b29b 100644 --- a/python/ql/test/query-tests/Expressions/Regex/BackspaceEscape.qlref +++ b/python/ql/test/query-tests/Expressions/Regex/BackspaceEscape.qlref @@ -1 +1,2 @@ -Expressions/Regex/BackspaceEscape.ql +query: Expressions/Regex/BackspaceEscape.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Regex/DuplicateCharacterInSet.qlref b/python/ql/test/query-tests/Expressions/Regex/DuplicateCharacterInSet.qlref index f0fc83c214eb..358d546ce8ad 100644 --- a/python/ql/test/query-tests/Expressions/Regex/DuplicateCharacterInSet.qlref +++ b/python/ql/test/query-tests/Expressions/Regex/DuplicateCharacterInSet.qlref @@ -1 +1,2 @@ -Expressions/Regex/DuplicateCharacterInSet.ql +query: Expressions/Regex/DuplicateCharacterInSet.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Regex/MissingPartSpecialGroup.qlref b/python/ql/test/query-tests/Expressions/Regex/MissingPartSpecialGroup.qlref index faf8f31ad4d6..215e7874972d 100644 --- a/python/ql/test/query-tests/Expressions/Regex/MissingPartSpecialGroup.qlref +++ b/python/ql/test/query-tests/Expressions/Regex/MissingPartSpecialGroup.qlref @@ -1 +1,2 @@ -Expressions/Regex/MissingPartSpecialGroup.ql +query: Expressions/Regex/MissingPartSpecialGroup.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Regex/UnmatchableCaret.qlref b/python/ql/test/query-tests/Expressions/Regex/UnmatchableCaret.qlref index 161fd59f7f28..218dcb021982 100644 --- a/python/ql/test/query-tests/Expressions/Regex/UnmatchableCaret.qlref +++ b/python/ql/test/query-tests/Expressions/Regex/UnmatchableCaret.qlref @@ -1 +1,2 @@ -Expressions/Regex/UnmatchableCaret.ql +query: Expressions/Regex/UnmatchableCaret.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Regex/UnmatchableDollar.qlref b/python/ql/test/query-tests/Expressions/Regex/UnmatchableDollar.qlref index b162342922c5..cabb436241ce 100644 --- a/python/ql/test/query-tests/Expressions/Regex/UnmatchableDollar.qlref +++ b/python/ql/test/query-tests/Expressions/Regex/UnmatchableDollar.qlref @@ -1 +1,2 @@ -Expressions/Regex/UnmatchableDollar.ql +query: Expressions/Regex/UnmatchableDollar.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/Regex/test.py b/python/ql/test/query-tests/Expressions/Regex/test.py index 717663e335c5..ebc1ae1368b0 100644 --- a/python/ql/test/query-tests/Expressions/Regex/test.py +++ b/python/ql/test/query-tests/Expressions/Regex/test.py @@ -1,9 +1,9 @@ import re #Unmatchable caret -re.compile(b' ^abc') -re.compile(b"(?s) ^abc") -re.compile(b"\[^123]") +re.compile(b' ^abc') # $ Alert[py/regex/unmatchable-caret] +re.compile(b"(?s) ^abc") # $ Alert[py/regex/unmatchable-caret] +re.compile(b"\[^123]") # $ Alert[py/regex/unmatchable-caret] #Likely false positives for unmatchable caret re.compile(b"[^123]") @@ -14,21 +14,21 @@ re.compile(b"^diff (?:-r [0-9a-f]+ ){1,2}(.*)$") #Backspace escape -re.compile(br"[\b\t ]") # Should warn +re.compile(br"[\b\t ]") # $ Alert[py/regex/backspace-escape] # Should warn re.compile(br"E\d+\b.*") # Fine -re.compile(br"E\d+\b[ \b\t]") #Both +re.compile(br"E\d+\b[ \b\t]") # $ Alert[py/regex/backspace-escape] #Both #Missing part in named group -re.compile(br'(P[\w]+)') -re.compile(br'(_(P[\w]+)|)') +re.compile(br'(P[\w]+)') # $ Alert[py/regex/incomplete-special-group] +re.compile(br'(_(P[\w]+)|)') # $ Alert[py/regex/incomplete-special-group] #This is OK... re.compile(br'(?P\w+)') #Unmatchable dollar -re.compile(b"abc$ ") -re.compile(b"abc$ (?s)") -re.compile(b"\[$] ") +re.compile(b"abc$ ") # $ Alert[py/regex/unmatchable-dollar] +re.compile(b"abc$ (?s)") # $ Alert[py/regex/unmatchable-dollar] +re.compile(b"\[$] ") # $ Alert[py/regex/unmatchable-dollar] #Not unmatchable dollar re.match(b"[$] ", b"$ ") @@ -43,9 +43,9 @@ re.match(b"(a){00}b", b"b") #Duplicate character in set -re.compile(b"[AA]") -re.compile(b"[000]") -re.compile(b"[-0-9-]") +re.compile(b"[AA]") # $ Alert[py/regex/duplicate-in-character-class] +re.compile(b"[000]") # $ Alert[py/regex/duplicate-in-character-class] +re.compile(b"[-0-9-]") # $ Alert[py/regex/duplicate-in-character-class] #Possible false positives re.compile(b"[S\S]") @@ -76,8 +76,8 @@ #Not OK -re.compile(br'(?<=foo)^\w+') -re.compile(br'\w+$(?=foo)') +re.compile(br'(?<=foo)^\w+') # $ Alert[py/regex/unmatchable-caret] +re.compile(br'\w+$(?=foo)') # $ Alert[py/regex/unmatchable-dollar] #OK -- ODASA-ODASA-3968 @@ -134,7 +134,7 @@ \[ # [ (?P
[^]]+) # very permissive! \] # ] - """ + """ # $ Alert[py/regex/duplicate-in-character-class] # Compiled regular expression marking it as verbose ODASA_6786 = re.compile(VERBOSE_REGEX, re.VERBOSE) diff --git a/python/ql/test/query-tests/Expressions/callable/NonCallableCalled.qlref b/python/ql/test/query-tests/Expressions/callable/NonCallableCalled.qlref index ea8577e6f9fb..e26b890fde89 100644 --- a/python/ql/test/query-tests/Expressions/callable/NonCallableCalled.qlref +++ b/python/ql/test/query-tests/Expressions/callable/NonCallableCalled.qlref @@ -1 +1,2 @@ -Expressions/NonCallableCalled.ql \ No newline at end of file +query: Expressions/NonCallableCalled.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/callable/test.py b/python/ql/test/query-tests/Expressions/callable/test.py index 5498fba72926..3ccb238db3fa 100644 --- a/python/ql/test/query-tests/Expressions/callable/test.py +++ b/python/ql/test/query-tests/Expressions/callable/test.py @@ -13,9 +13,9 @@ def __call__(self): def call_non_callable(arg): non = NonCallable() - non(arg) - ()() - []() + non(arg) # $ Alert + ()() # $ Alert + []() # $ Alert dont_know = MaybeCallable() dont_know() # Not a violation ok = IsCallable() @@ -23,7 +23,7 @@ def call_non_callable(arg): if hasattr(non, "__call__"): non(arg) # OK due to guard if hasattr(non, "__init__"): - non(arg) # Not OK due to wrong guard + non(arg) # $ Alert # Not OK due to wrong guard import six @@ -44,7 +44,7 @@ def foo(): raise NotImplemented() def bar(): - return NotImplemented() + return NotImplemented() # $ Alert # FP due to decorator @@ -60,7 +60,7 @@ def __init__(self, arg): @some_decorator @classmethod def new_instance(cls, new_arg): - return cls(new_arg) # TODO: FP + return cls(new_arg) # $ SPURIOUS: Alert # TODO: FP f1 = Foo(1) f2 = f1.new_instance(2) diff --git a/python/ql/test/query-tests/Expressions/comparisons/UselessComparisonTest.qlref b/python/ql/test/query-tests/Expressions/comparisons/UselessComparisonTest.qlref index fb7f75f9f615..e022932acda4 100644 --- a/python/ql/test/query-tests/Expressions/comparisons/UselessComparisonTest.qlref +++ b/python/ql/test/query-tests/Expressions/comparisons/UselessComparisonTest.qlref @@ -1 +1,2 @@ -Expressions/Comparisons/UselessComparisonTest.ql \ No newline at end of file +query: Expressions/Comparisons/UselessComparisonTest.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/comparisons/test.py b/python/ql/test/query-tests/Expressions/comparisons/test.py index aac73f4932eb..172667144934 100644 --- a/python/ql/test/query-tests/Expressions/comparisons/test.py +++ b/python/ql/test/query-tests/Expressions/comparisons/test.py @@ -3,16 +3,16 @@ def f(w, x, y, z): if x < 0 or z < 0: raise Exception() - if x >= 0: # Useless test due to x < 0 being false + if x >= 0: # $ Alert # Useless test due to x < 0 being false y += 1 - if z >= 0: # Useless test due to z < 0 being false + if z >= 0: # $ Alert # Useless test due to z < 0 being false y += 1 while w >= 0: if y < 10: z += 1 - if y == 15: # Useless test due to y < 10 being true + if y == 15: # $ Alert # Useless test due to y < 10 being true z += 1 - elif y > 7: # Useless test + elif y > 7: # $ Alert # Useless test y -= 1 if y < 10: y += 1 @@ -24,10 +24,10 @@ def f(w, x, y, z): def g(w, x, y, z): if w < x or y < z+2: raise Exception() - if w >= x: # Useless test due to w < x being false + if w >= x: # $ Alert # Useless test due to w < x being false pass if cond: - if z > y-2: # Useless test due to y < z+2 being false + if z > y-2: # $ Alert # Useless test due to y < z+2 being false y += 1 else: if z >= y-2: # Not a useless test. @@ -46,7 +46,7 @@ def validate_series(start, end): def medium1(x, y): if x + 1000000000000000 > y + 1000000000000000: return - if x > y: # Redundant + if x > y: # $ Alert # Redundant pass def medium2(x, y): @@ -70,19 +70,19 @@ def big2(x, y): def odasa6782_v1(protocol): if protocol < 0: protocol = HIGHEST_PROTOCOL - elif not 0 <= protocol: + elif not 0 <= protocol: # $ Alert raise ValueError() def odasa6782_v2(protocol): if protocol < 0: protocol = HIGHEST_PROTOCOL - elif not 0 <= protocol <= HIGHEST_PROTOCOL: + elif not 0 <= protocol <= HIGHEST_PROTOCOL: # $ Alert raise ValueError() def odasa6782_v3(protocol): if protocol < 0: protocol = HIGHEST_PROTOCOL - elif 0 <= protocol <= HIGHEST_PROTOCOL: + elif 0 <= protocol <= HIGHEST_PROTOCOL: # $ Alert pass else: raise ValueError() diff --git a/python/ql/test/query-tests/Expressions/eq/IncorrectComparisonUsingIs.qlref b/python/ql/test/query-tests/Expressions/eq/IncorrectComparisonUsingIs.qlref index 73123cf76281..df847ee2b1bb 100644 --- a/python/ql/test/query-tests/Expressions/eq/IncorrectComparisonUsingIs.qlref +++ b/python/ql/test/query-tests/Expressions/eq/IncorrectComparisonUsingIs.qlref @@ -1 +1,2 @@ -Expressions/IncorrectComparisonUsingIs.ql +query: Expressions/IncorrectComparisonUsingIs.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/eq/NonPortableComparisonUsingIs.qlref b/python/ql/test/query-tests/Expressions/eq/NonPortableComparisonUsingIs.qlref index 13c08534293c..a62a6a40f60d 100644 --- a/python/ql/test/query-tests/Expressions/eq/NonPortableComparisonUsingIs.qlref +++ b/python/ql/test/query-tests/Expressions/eq/NonPortableComparisonUsingIs.qlref @@ -1 +1,2 @@ -Expressions/NonPortableComparisonUsingIs.ql +query: Expressions/NonPortableComparisonUsingIs.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/eq/expressions_test.py b/python/ql/test/query-tests/Expressions/eq/expressions_test.py index 3489bf3a1a94..632616583c39 100644 --- a/python/ql/test/query-tests/Expressions/eq/expressions_test.py +++ b/python/ql/test/query-tests/Expressions/eq/expressions_test.py @@ -43,12 +43,12 @@ def meth(self): #Using 'is' when should be using '==' s = "Hello " + "World" -if "Hello World" is s: +if "Hello World" is s: # $ Alert[py/comparison-using-is] print ("OK") #This is OK in CPython, but may not be portable s = str(7) -if "7" is s: +if "7" is s: # $ Alert[py/comparison-using-is-non-portable] print ("OK") #And some data flow diff --git a/python/ql/test/query-tests/Expressions/general/CompareConstants.qlref b/python/ql/test/query-tests/Expressions/general/CompareConstants.qlref index 0e2ab115eeec..5b5160d860d5 100644 --- a/python/ql/test/query-tests/Expressions/general/CompareConstants.qlref +++ b/python/ql/test/query-tests/Expressions/general/CompareConstants.qlref @@ -1 +1,2 @@ -Expressions/CompareConstants.ql +query: Expressions/CompareConstants.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/CompareIdenticalValues.qlref b/python/ql/test/query-tests/Expressions/general/CompareIdenticalValues.qlref index 4bc0ec69fc04..ad4cbb7600e8 100644 --- a/python/ql/test/query-tests/Expressions/general/CompareIdenticalValues.qlref +++ b/python/ql/test/query-tests/Expressions/general/CompareIdenticalValues.qlref @@ -1 +1,2 @@ -Expressions/CompareIdenticalValues.ql +query: Expressions/CompareIdenticalValues.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/CompareIdenticalValuesMissingSelf.qlref b/python/ql/test/query-tests/Expressions/general/CompareIdenticalValuesMissingSelf.qlref index f19a0dee4364..48f4d302afba 100644 --- a/python/ql/test/query-tests/Expressions/general/CompareIdenticalValuesMissingSelf.qlref +++ b/python/ql/test/query-tests/Expressions/general/CompareIdenticalValuesMissingSelf.qlref @@ -1 +1,2 @@ -Expressions/CompareIdenticalValuesMissingSelf.ql \ No newline at end of file +query: Expressions/CompareIdenticalValuesMissingSelf.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/ContainsNonContainer.qlref b/python/ql/test/query-tests/Expressions/general/ContainsNonContainer.qlref index 71df405e72c1..b52c39ed26d2 100644 --- a/python/ql/test/query-tests/Expressions/general/ContainsNonContainer.qlref +++ b/python/ql/test/query-tests/Expressions/general/ContainsNonContainer.qlref @@ -1 +1,2 @@ -Expressions/ContainsNonContainer.ql +query: Expressions/ContainsNonContainer.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/DuplicateKeyInDictionaryLiteral.qlref b/python/ql/test/query-tests/Expressions/general/DuplicateKeyInDictionaryLiteral.qlref index a1bb71098829..23123f187490 100644 --- a/python/ql/test/query-tests/Expressions/general/DuplicateKeyInDictionaryLiteral.qlref +++ b/python/ql/test/query-tests/Expressions/general/DuplicateKeyInDictionaryLiteral.qlref @@ -1 +1,2 @@ -Expressions/DuplicateKeyInDictionaryLiteral.ql \ No newline at end of file +query: Expressions/DuplicateKeyInDictionaryLiteral.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/EqualsNone.qlref b/python/ql/test/query-tests/Expressions/general/EqualsNone.qlref index 8d9699258e25..026a3f5bbc2f 100644 --- a/python/ql/test/query-tests/Expressions/general/EqualsNone.qlref +++ b/python/ql/test/query-tests/Expressions/general/EqualsNone.qlref @@ -1 +1,2 @@ -Expressions/EqualsNone.ql \ No newline at end of file +query: Expressions/EqualsNone.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/ExpectedMappingForFormatString.qlref b/python/ql/test/query-tests/Expressions/general/ExpectedMappingForFormatString.qlref index 83e92584ef27..fd322b848dca 100644 --- a/python/ql/test/query-tests/Expressions/general/ExpectedMappingForFormatString.qlref +++ b/python/ql/test/query-tests/Expressions/general/ExpectedMappingForFormatString.qlref @@ -1 +1,2 @@ -Expressions/ExpectedMappingForFormatString.ql \ No newline at end of file +query: Expressions/ExpectedMappingForFormatString.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/ExplicitCallToDel.qlref b/python/ql/test/query-tests/Expressions/general/ExplicitCallToDel.qlref index 932f1a3d366d..451bd74eee0e 100644 --- a/python/ql/test/query-tests/Expressions/general/ExplicitCallToDel.qlref +++ b/python/ql/test/query-tests/Expressions/general/ExplicitCallToDel.qlref @@ -1 +1,2 @@ -Expressions/ExplicitCallToDel.ql \ No newline at end of file +query: Expressions/ExplicitCallToDel.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/HashedButNoHash.qlref b/python/ql/test/query-tests/Expressions/general/HashedButNoHash.qlref index ee53e3674999..f30fd92870f0 100644 --- a/python/ql/test/query-tests/Expressions/general/HashedButNoHash.qlref +++ b/python/ql/test/query-tests/Expressions/general/HashedButNoHash.qlref @@ -1 +1,2 @@ -Expressions/HashedButNoHash.ql \ No newline at end of file +query: Expressions/HashedButNoHash.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/UnnecessaryLambda.qlref b/python/ql/test/query-tests/Expressions/general/UnnecessaryLambda.qlref index 49b3873f83ce..9141c5e49a65 100644 --- a/python/ql/test/query-tests/Expressions/general/UnnecessaryLambda.qlref +++ b/python/ql/test/query-tests/Expressions/general/UnnecessaryLambda.qlref @@ -1 +1,2 @@ -Expressions/UnnecessaryLambda.ql \ No newline at end of file +query: Expressions/UnnecessaryLambda.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/UnsupportedFormatCharacter.qlref b/python/ql/test/query-tests/Expressions/general/UnsupportedFormatCharacter.qlref index 3cb459229e4a..8e50b947401e 100644 --- a/python/ql/test/query-tests/Expressions/general/UnsupportedFormatCharacter.qlref +++ b/python/ql/test/query-tests/Expressions/general/UnsupportedFormatCharacter.qlref @@ -1 +1,2 @@ -Expressions/UnsupportedFormatCharacter.ql \ No newline at end of file +query: Expressions/UnsupportedFormatCharacter.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/WrongNumberArgumentsForFormat.qlref b/python/ql/test/query-tests/Expressions/general/WrongNumberArgumentsForFormat.qlref index 0d127e1b618b..744334a6aeb1 100644 --- a/python/ql/test/query-tests/Expressions/general/WrongNumberArgumentsForFormat.qlref +++ b/python/ql/test/query-tests/Expressions/general/WrongNumberArgumentsForFormat.qlref @@ -1 +1,2 @@ -Expressions/WrongNumberArgumentsForFormat.ql \ No newline at end of file +query: Expressions/WrongNumberArgumentsForFormat.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/general/compare.py b/python/ql/test/query-tests/Expressions/general/compare.py index 141b5e6a0286..c48e06f4b1ca 100644 --- a/python/ql/test/query-tests/Expressions/general/compare.py +++ b/python/ql/test/query-tests/Expressions/general/compare.py @@ -5,12 +5,12 @@ a.x == b.x #Same variables -a == a -a.x == a.x +a == a # $ Alert[py/comparison-of-identical-expressions] +a.x == a.x # $ Alert[py/comparison-of-identical-expressions] #Compare constants -1 == 1 -1 == 2 +1 == 1 # $ Alert[py/comparison-of-constants] +1 == 2 # $ Alert[py/comparison-of-constants] #Maybe missing self class X(object): @@ -19,7 +19,7 @@ def __init__(self, x): self.x = x def missing_self(self, x): - if x == x: + if x == x: # $ Alert[py/comparison-missing-self] print ("Yes") #Compare constants in assert -- ok diff --git a/python/ql/test/query-tests/Expressions/general/expressions_test.py b/python/ql/test/query-tests/Expressions/general/expressions_test.py index 5e07b58e2041..71e0d1ba7cf0 100644 --- a/python/ql/test/query-tests/Expressions/general/expressions_test.py +++ b/python/ql/test/query-tests/Expressions/general/expressions_test.py @@ -1,16 +1,16 @@ #encoding: utf-8 def dup_key(): - return { 1: -1, + return { 1: -1, # $ Alert[py/duplicate-key-dict-literal] 1: -2, - u'a' : u'A', + u'a' : u'A', # $ Alert[py/duplicate-key-dict-literal] u'a' : u'B' } def simple_func(*args, **kwrgs): pass #Unnecessary lambdas -lambda arg0, arg1: simple_func(arg0, arg1) -lambda arg0, *arg1: simple_func(arg0, *arg1) -lambda arg0, **arg1: simple_func(arg0, **arg1) +lambda arg0, arg1: simple_func(arg0, arg1) # $ Alert[py/unnecessary-lambda] +lambda arg0, *arg1: simple_func(arg0, *arg1) # $ Alert[py/unnecessary-lambda] +lambda arg0, **arg1: simple_func(arg0, **arg1) # $ Alert[py/unnecessary-lambda] # these lambdas are_ necessary lambda arg0, arg1=1: simple_func(arg0, arg1) lambda arg0, arg1: simple_func(arg0, *arg1) @@ -34,12 +34,12 @@ def call_non_callable(arg): dont_know() # Not a violation #Explicit call to __del__ -x.__del__() +x.__del__() # $ Alert[py/explicit-call-to-delete] #Unhashable object def func(): mapping = dict(); unhash = list() - return mapping[unhash] + return mapping[unhash] # $ Alert[py/hash-unhashable-value] #Using 'is' when should be using '==' s = "Hello " + "World" @@ -86,9 +86,9 @@ def next(self): def non_container(): seq = XIter() - if 1 in seq: + if 1 in seq: # $ Alert[py/member-test-non-container] pass - if 1 not in seq: + if 1 not in seq: # $ Alert[py/member-test-non-container] pass #Container inheriting from builtin @@ -112,7 +112,7 @@ def is_container(): #Equals none def x(arg): - return arg == None + return arg == None # $ Alert[py/test-equals-none] class NotMyDict(object): @@ -130,7 +130,7 @@ def __del__(self): # This is permitted and required. Test.__del__(self) # This is a violation. - self.__del__() + self.__del__() # $ Alert[py/explicit-call-to-delete] # This is an alternate syntax for the super() call, and hence OK. super(SubTest, self).__del__() # This is the Python 3 spelling of the same. @@ -138,15 +138,15 @@ def __del__(self): #Some more lambdas #Unnecessary lambdas -lambda arg0: len(arg0) -lambda arg0: XIter.next(arg0) +lambda arg0: len(arg0) # $ Alert[py/unnecessary-lambda] +lambda arg0: XIter.next(arg0) # $ Alert[py/unnecessary-lambda] class UL(object): def f(self, x): pass def g(self): - return lambda x: self.f(x) + return lambda x: self.f(x) # $ Alert[py/unnecessary-lambda] # these lambdas are necessary lambda arg0: XIter.next(arg0, arg1) diff --git a/python/ql/test/query-tests/Expressions/general/str_fmt_test.py b/python/ql/test/query-tests/Expressions/general/str_fmt_test.py index e941b842c319..f7441ef9a8ad 100644 --- a/python/ql/test/query-tests/Expressions/general/str_fmt_test.py +++ b/python/ql/test/query-tests/Expressions/general/str_fmt_test.py @@ -2,16 +2,16 @@ def expected_mapping_for_fmt_string(): x = [ u'list', u'not', u'mapping' ] - print (u"%(name)s" % x) + print (u"%(name)s" % x) # $ Alert[py/percent-format/not-mapping] def unsupported_format_char(arg): - print (u"%Z" % arg) + print (u"%Z" % arg) # $ Alert[py/percent-format/unsupported-character] def wrong_arg_count_format(arg): - print(u"%s %s" % (arg, arg, 0)) + print(u"%s %s" % (arg, arg, 0)) # $ Alert[py/percent-format/wrong-arguments] format = u"%hd" args = (1, u'foo') - print(format % args) + print(format % args) # $ Alert[py/percent-format/wrong-arguments] def ok(): diff --git a/python/ql/test/query-tests/Expressions/strings/UnintentionalImplicitStringConcatenation.qlref b/python/ql/test/query-tests/Expressions/strings/UnintentionalImplicitStringConcatenation.qlref index c305fd129f8b..7159e5c79721 100644 --- a/python/ql/test/query-tests/Expressions/strings/UnintentionalImplicitStringConcatenation.qlref +++ b/python/ql/test/query-tests/Expressions/strings/UnintentionalImplicitStringConcatenation.qlref @@ -1 +1,2 @@ -Expressions/UnintentionalImplicitStringConcatenation.ql \ No newline at end of file +query: Expressions/UnintentionalImplicitStringConcatenation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/strings/test.py b/python/ql/test/query-tests/Expressions/strings/test.py index 15b3c9216e33..1767a2d109be 100644 --- a/python/ql/test/query-tests/Expressions/strings/test.py +++ b/python/ql/test/query-tests/Expressions/strings/test.py @@ -15,13 +15,13 @@ def test(): error1 = [ "foo", "/usr/local" - "/usr/bin" + "/usr/bin" # $ Alert ] error2 = [ "foo" + "bar", "/usr/local" - "/usr/bin" + "/usr/bin" # $ Alert ] #Examples from documentation @@ -31,9 +31,9 @@ def unclear(): return [ "first part of long string" - " and the second part", + " and the second part", # $ Alert "/usr/local" - "/usr/bin" + "/usr/bin" # $ Alert ] def clarified(): diff --git a/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.qlref b/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.qlref index c3beeaede04b..e1ed0c122bea 100644 --- a/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.qlref +++ b/python/ql/test/query-tests/Expressions/super/CallToSuperWrongClass.qlref @@ -1 +1,2 @@ -Expressions/CallToSuperWrongClass.ql \ No newline at end of file +query: Expressions/CallToSuperWrongClass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Expressions/super/test.py b/python/ql/test/query-tests/Expressions/super/test.py index e2e667cd25d7..947bc3814b2a 100644 --- a/python/ql/test/query-tests/Expressions/super/test.py +++ b/python/ql/test/query-tests/Expressions/super/test.py @@ -7,7 +7,7 @@ class MyDict(dict): class NotMyDict(object): def f(self): - super(MyDict, self).f() + super(MyDict, self).f() # $ Alert #Splitting PY2 = sys.version_info[0] == 2 diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref index 8c4044e8feeb..e8937358e32f 100644 --- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref @@ -1 +1 @@ -Functions/ModificationOfParameterWithDefault.ql +query: Functions/ModificationOfParameterWithDefault.ql diff --git a/python/ql/test/query-tests/Functions/general/DeprecatedSliceMethod.qlref b/python/ql/test/query-tests/Functions/general/DeprecatedSliceMethod.qlref index c38b8d1f7619..3043411c1ce4 100644 --- a/python/ql/test/query-tests/Functions/general/DeprecatedSliceMethod.qlref +++ b/python/ql/test/query-tests/Functions/general/DeprecatedSliceMethod.qlref @@ -1 +1,2 @@ -Functions/DeprecatedSliceMethod.ql \ No newline at end of file +query: Functions/DeprecatedSliceMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/ExplicitReturnInInit.qlref b/python/ql/test/query-tests/Functions/general/ExplicitReturnInInit.qlref index a23550c48650..df13334dcbf5 100644 --- a/python/ql/test/query-tests/Functions/general/ExplicitReturnInInit.qlref +++ b/python/ql/test/query-tests/Functions/general/ExplicitReturnInInit.qlref @@ -1 +1,2 @@ -Functions/ExplicitReturnInInit.ql \ No newline at end of file +query: Functions/ExplicitReturnInInit.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/InitIsGenerator.qlref b/python/ql/test/query-tests/Functions/general/InitIsGenerator.qlref index a3df140ff1e6..2662a7ca03a3 100644 --- a/python/ql/test/query-tests/Functions/general/InitIsGenerator.qlref +++ b/python/ql/test/query-tests/Functions/general/InitIsGenerator.qlref @@ -1 +1,2 @@ -Functions/InitIsGenerator.ql \ No newline at end of file +query: Functions/InitIsGenerator.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/IterReturnsNonIterator.qlref b/python/ql/test/query-tests/Functions/general/IterReturnsNonIterator.qlref index 3d0965f7b115..14655b261d42 100644 --- a/python/ql/test/query-tests/Functions/general/IterReturnsNonIterator.qlref +++ b/python/ql/test/query-tests/Functions/general/IterReturnsNonIterator.qlref @@ -1 +1 @@ -Functions/IterReturnsNonIterator.ql +query: Functions/IterReturnsNonIterator.ql diff --git a/python/ql/test/query-tests/Functions/general/OverlyComplexDelMethod.qlref b/python/ql/test/query-tests/Functions/general/OverlyComplexDelMethod.qlref index 601501aac303..90dba842c0e7 100644 --- a/python/ql/test/query-tests/Functions/general/OverlyComplexDelMethod.qlref +++ b/python/ql/test/query-tests/Functions/general/OverlyComplexDelMethod.qlref @@ -1 +1,2 @@ -Functions/OverlyComplexDelMethod.ql +query: Functions/OverlyComplexDelMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/SignatureOverriddenMethod.qlref b/python/ql/test/query-tests/Functions/general/SignatureOverriddenMethod.qlref index a306477b3b48..5470a05e0e41 100644 --- a/python/ql/test/query-tests/Functions/general/SignatureOverriddenMethod.qlref +++ b/python/ql/test/query-tests/Functions/general/SignatureOverriddenMethod.qlref @@ -1 +1,2 @@ -Functions/SignatureOverriddenMethod.ql +query: Functions/SignatureOverriddenMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/SignatureSpecialMethods.qlref b/python/ql/test/query-tests/Functions/general/SignatureSpecialMethods.qlref index bc1b29b6c0d0..ab188ef5bc28 100644 --- a/python/ql/test/query-tests/Functions/general/SignatureSpecialMethods.qlref +++ b/python/ql/test/query-tests/Functions/general/SignatureSpecialMethods.qlref @@ -1 +1,2 @@ -Functions/SignatureSpecialMethods.ql \ No newline at end of file +query: Functions/SignatureSpecialMethods.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/general/explicit_return_in_init.py b/python/ql/test/query-tests/Functions/general/explicit_return_in_init.py index 47a2933ad6ef..9024b13aa786 100644 --- a/python/ql/test/query-tests/Functions/general/explicit_return_in_init.py +++ b/python/ql/test/query-tests/Functions/general/explicit_return_in_init.py @@ -1,7 +1,7 @@ class ExplicitReturnInInit(object): def __init__(self): - return self + return self # $ Alert[py/explicit-return-in-init] # These are OK class ExplicitReturnNoneInInit(object): @@ -29,7 +29,7 @@ def __init__(self): class InitIsGenerator(object): - def __init__(self): + def __init__(self): # $ Alert[py/init-method-is-generator] yield self # OK as it returns result of a call to super().__init__() @@ -99,4 +99,4 @@ def __init__(self, b): p = procedure_implicit_none() else: p = not_ok - return p() + return p() # $ Alert[py/explicit-return-in-init] diff --git a/python/ql/test/query-tests/Functions/general/functions_test.py b/python/ql/test/query-tests/Functions/general/functions_test.py index 741599abd5b0..a306ef8ccc82 100644 --- a/python/ql/test/query-tests/Functions/general/functions_test.py +++ b/python/ql/test/query-tests/Functions/general/functions_test.py @@ -92,13 +92,13 @@ def ok_to_ignore(): class DeprecatedSliceMethods(object): - def __getslice__(self, start, stop): + def __getslice__(self, start, stop): # $ Alert[py/deprecated-slice-method] pass - def __setslice__(self, start, stop, value): + def __setslice__(self, start, stop, value): # $ Alert[py/deprecated-slice-method] pass - def __delslice__(self, start, stop): + def __delslice__(self, start, stop): # $ Alert[py/deprecated-slice-method] pass diff --git a/python/ql/test/query-tests/Functions/general/om_test.py b/python/ql/test/query-tests/Functions/general/om_test.py index 959ed6bfe348..edaa81bd0628 100644 --- a/python/ql/test/query-tests/Functions/general/om_test.py +++ b/python/ql/test/query-tests/Functions/general/om_test.py @@ -29,10 +29,10 @@ def ok1(self, arg1, arg2 = 2): def ok2(self, arg1, arg2 = 2, arg3 = 3): return arg1, arg2, arg3 - def grossly_wrong1(self, arg1): + def grossly_wrong1(self, arg1): # $ Alert[py/inheritance/signature-mismatch] return arg1 - def grossly_wrong2(self, arg1, arg2, arg3): + def grossly_wrong2(self, arg1, arg2, arg3): # $ Alert[py/inheritance/signature-mismatch] return arg1, arg2, arg3 def strictly_wrong1(self, arg1): @@ -56,19 +56,19 @@ def __str__(self): class WrongSpecials(object): - def __div__(self, x, y): + def __div__(self, x, y): # $ Alert[py/special-method-wrong-signature] return self, x, y - def __mul__(self): + def __mul__(self): # $ Alert[py/special-method-wrong-signature] return self - def __neg__(self, other): + def __neg__(self, other): # $ Alert[py/special-method-wrong-signature] return self, other - def __exit__(self, arg0, arg1): + def __exit__(self, arg0, arg1): # $ Alert[py/special-method-wrong-signature] return arg0 == arg1 - def __repr__(): + def __repr__(): # $ Alert[py/special-method-wrong-signature] return "" def __add__(self, other="Unused default"): @@ -80,7 +80,7 @@ def __abs__(): class OKSpecials(object): - def __del__(): + def __del__(): # $ Alert[py/special-method-wrong-signature] state = some_state() def __del__(self): diff --git a/python/ql/test/query-tests/Functions/general/protocols.py b/python/ql/test/query-tests/Functions/general/protocols.py index dd12fc3ed40f..68f0aaf29c09 100644 --- a/python/ql/test/query-tests/Functions/general/protocols.py +++ b/python/ql/test/query-tests/Functions/general/protocols.py @@ -71,7 +71,7 @@ def __iter__(self): class MegaDel(object): - def __del__(self): + def __del__(self): # $ Alert[py/overly-complex-delete] a = self.x + self.y if a: print(a) diff --git a/python/ql/test/query-tests/Functions/iterators/IterReturnsNonSelf.qlref b/python/ql/test/query-tests/Functions/iterators/IterReturnsNonSelf.qlref index b806215d26c8..828fca864dae 100644 --- a/python/ql/test/query-tests/Functions/iterators/IterReturnsNonSelf.qlref +++ b/python/ql/test/query-tests/Functions/iterators/IterReturnsNonSelf.qlref @@ -1 +1,2 @@ -Functions/IterReturnsNonSelf.ql \ No newline at end of file +query: Functions/IterReturnsNonSelf.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/iterators/test.py b/python/ql/test/query-tests/Functions/iterators/test.py index ced389967e41..860d199dae8a 100644 --- a/python/ql/test/query-tests/Functions/iterators/test.py +++ b/python/ql/test/query-tests/Functions/iterators/test.py @@ -2,7 +2,7 @@ class Bad1: def __next__(self): return 0 - def __iter__(self): # BAD: Iter does not return self + def __iter__(self): # $ Alert # BAD: Iter does not return self yield 0 class Good1: @@ -48,6 +48,6 @@ def __next__(self): self._it = iter(self) return next(self._it) - def __iter__(self): # SPURIOUS, GOOD: implementation of next ensures the iterator is equivalent to the one returned by iter, but this is not detected. + def __iter__(self): # $ Alert # SPURIOUS, GOOD: implementation of next ensures the iterator is equivalent to the one returned by iter, but this is not detected. yield 0 - yield 0 \ No newline at end of file + yield 0 diff --git a/python/ql/test/query-tests/Functions/overriding/IncorrectlyOverriddenMethod.qlref b/python/ql/test/query-tests/Functions/overriding/IncorrectlyOverriddenMethod.qlref index d1637c1f1d37..9d5a8324c796 100644 --- a/python/ql/test/query-tests/Functions/overriding/IncorrectlyOverriddenMethod.qlref +++ b/python/ql/test/query-tests/Functions/overriding/IncorrectlyOverriddenMethod.qlref @@ -1 +1,2 @@ -Functions/IncorrectlyOverriddenMethod.ql \ No newline at end of file +query: Functions/IncorrectlyOverriddenMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/overriding/IncorrectlySpecifiedOverriddenMethod.qlref b/python/ql/test/query-tests/Functions/overriding/IncorrectlySpecifiedOverriddenMethod.qlref index 8a07cb1297ea..258840b2fc43 100644 --- a/python/ql/test/query-tests/Functions/overriding/IncorrectlySpecifiedOverriddenMethod.qlref +++ b/python/ql/test/query-tests/Functions/overriding/IncorrectlySpecifiedOverriddenMethod.qlref @@ -1 +1,2 @@ -Functions/IncorrectlySpecifiedOverriddenMethod.ql \ No newline at end of file +query: Functions/IncorrectlySpecifiedOverriddenMethod.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/overriding/WrongNameForArgumentInCall.qlref b/python/ql/test/query-tests/Functions/overriding/WrongNameForArgumentInCall.qlref index 3599f204f55e..c6b6ca3d30fa 100644 --- a/python/ql/test/query-tests/Functions/overriding/WrongNameForArgumentInCall.qlref +++ b/python/ql/test/query-tests/Functions/overriding/WrongNameForArgumentInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNameForArgumentInCall.ql \ No newline at end of file +query: Expressions/WrongNameForArgumentInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/overriding/WrongNumberArgumentsInCall.qlref b/python/ql/test/query-tests/Functions/overriding/WrongNumberArgumentsInCall.qlref index 1bffe8f1cad4..68dc510d5c6e 100644 --- a/python/ql/test/query-tests/Functions/overriding/WrongNumberArgumentsInCall.qlref +++ b/python/ql/test/query-tests/Functions/overriding/WrongNumberArgumentsInCall.qlref @@ -1 +1,2 @@ -Expressions/WrongNumberArgumentsInCall.ql \ No newline at end of file +query: Expressions/WrongNumberArgumentsInCall.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/overriding/test.py b/python/ql/test/query-tests/Functions/overriding/test.py index 879efdbe2913..640563700460 100644 --- a/python/ql/test/query-tests/Functions/overriding/test.py +++ b/python/ql/test/query-tests/Functions/overriding/test.py @@ -2,10 +2,10 @@ class Base(object): - def meth1(self): + def meth1(self): # $ Alert[py/inheritance/incorrect-overridden-signature] pass - def meth2(self, spam): + def meth2(self, spam): # $ Alert[py/inheritance/incorrect-overridden-signature] pass def meth3(self): @@ -13,18 +13,18 @@ def meth3(self): def foo(self): self.meth1() - self.meth1(0) - self.meth2() + self.meth1(0) # $ Alert[py/call/wrong-arguments] + self.meth2() # $ Alert[py/call/wrong-arguments] self.meth2(0) - self.meth1(spam="eggs") + self.meth1(spam="eggs") # $ Alert[py/call/wrong-named-argument] self.meth2(spam="eggs") class Derived(Base): - def meth1(self, spam): # $ Alert[py/inheritance/signature-mismatch] # Has 1 more arg, base called in Base.foo + def meth1(self, spam): # $ Alert[py/inheritance/signature-mismatch] Alert[py/inheritance/incorrect-overriding-signature] # Has 1 more arg, base called in Base.foo pass - def meth2(self): # $ Alert[py/inheritance/signature-mismatch] # Has 1 fewer arg, base called in Base.foo + def meth2(self): # $ Alert[py/inheritance/signature-mismatch] Alert[py/inheritance/incorrect-overriding-signature] # Has 1 fewer arg, base called in Base.foo pass def meth3(self, eggs): # $ Alert[py/inheritance/signature-mismatch] # Has 1 more arg. Method is not called. @@ -61,7 +61,7 @@ def meth(self, arg): class BlameBase(object): - def meth(self): + def meth(self): # $ Alert[py/inheritance/incorrect-overridden-signature] pass class Correct1(BlameBase): @@ -109,7 +109,7 @@ def call_some(self): self.meth1() self.meth1(x=2) self.meth3() - self.meth3(x=2) + self.meth3(x=2) # $ Alert[py/call/wrong-named-argument] self.meth6(2, 3, 4) self.meth7() self.meth8(1,y=3) diff --git a/python/ql/test/query-tests/Functions/return_values/ConsistentReturns.qlref b/python/ql/test/query-tests/Functions/return_values/ConsistentReturns.qlref index 0904074f25b4..6f10808f42bf 100644 --- a/python/ql/test/query-tests/Functions/return_values/ConsistentReturns.qlref +++ b/python/ql/test/query-tests/Functions/return_values/ConsistentReturns.qlref @@ -1 +1,2 @@ -Functions/ConsistentReturns.ql +query: Functions/ConsistentReturns.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/return_values/ReturnConsistentTupleSizes.qlref b/python/ql/test/query-tests/Functions/return_values/ReturnConsistentTupleSizes.qlref index c91661b33cf4..c7eaa3205b2e 100644 --- a/python/ql/test/query-tests/Functions/return_values/ReturnConsistentTupleSizes.qlref +++ b/python/ql/test/query-tests/Functions/return_values/ReturnConsistentTupleSizes.qlref @@ -1 +1,2 @@ -Functions/ReturnConsistentTupleSizes.ql +query: Functions/ReturnConsistentTupleSizes.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/return_values/ReturnValueIgnored.qlref b/python/ql/test/query-tests/Functions/return_values/ReturnValueIgnored.qlref index 61002533ef49..ded6bf8e609c 100644 --- a/python/ql/test/query-tests/Functions/return_values/ReturnValueIgnored.qlref +++ b/python/ql/test/query-tests/Functions/return_values/ReturnValueIgnored.qlref @@ -1 +1,2 @@ -Functions/ReturnValueIgnored.ql \ No newline at end of file +query: Functions/ReturnValueIgnored.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/return_values/UseImplicitNoneReturnValue.qlref b/python/ql/test/query-tests/Functions/return_values/UseImplicitNoneReturnValue.qlref index b23115e8950c..af71ab6388e2 100644 --- a/python/ql/test/query-tests/Functions/return_values/UseImplicitNoneReturnValue.qlref +++ b/python/ql/test/query-tests/Functions/return_values/UseImplicitNoneReturnValue.qlref @@ -1 +1,2 @@ -Functions/UseImplicitNoneReturnValue.ql \ No newline at end of file +query: Functions/UseImplicitNoneReturnValue.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Functions/return_values/functions_test.py b/python/ql/test/query-tests/Functions/return_values/functions_test.py index 9f72a7fec600..8a8e947e84d9 100644 --- a/python/ql/test/query-tests/Functions/return_values/functions_test.py +++ b/python/ql/test/query-tests/Functions/return_values/functions_test.py @@ -15,11 +15,11 @@ def ok2(x): else: return "Hi" -def cr1(x): +def cr1(x): # $ Alert[py/mixed-returns] if x: return 4 -def cr2(x): +def cr2(x): # $ Alert[py/mixed-returns] if x: return 4 else: @@ -74,7 +74,7 @@ def ok4(x): def use_implicit_return_value(arg): - x = do_nothing() + x = do_nothing() # $ Alert[py/procedure-return-value-used] return call_non_callable(arg) #The return in the lambda is OK as it is auto-generated @@ -156,9 +156,9 @@ def do_nothing(): def return_value_ignored(): - ok2() - ok4() - sorted([1,2]) + ok2() # $ Alert[py/ignored-return-value] + ok4() # $ Alert[py/ignored-return-value] + sorted([1,2]) # $ Alert[py/ignored-return-value] d = {} @@ -231,7 +231,7 @@ def mutli_return(arg): if arg: return do_something() else: - return do_nothing() + return do_nothing() # $ Alert[py/procedure-return-value-used] #Modification of parameter with default @@ -303,7 +303,7 @@ def foo(x): # Returning tuples with different sizes -def returning_different_tuple_sizes(x): +def returning_different_tuple_sizes(x): # $ Alert[py/mixed-tuple-returns] if x: return 1,2 else: @@ -326,14 +326,14 @@ def indirectly_returning_different_tuple_sizes(x): # OK, since we only look at l return function_returning_2_tuple() else: return function_returning_3_tuple() - + def mismatched_multi_assign(x): a,b = returning_different_tuple_sizes(x) return a,b -def ok_match(x): # FP +def ok_match(x): # $ SPURIOUS: Alert[py/mixed-returns] # FP match x: case True | 'true': return 0 @@ -341,7 +341,7 @@ def ok_match(x): # FP raise ValueError(x) -def ok_match2(x): # FP +def ok_match2(x): # $ SPURIOUS: Alert[py/mixed-returns] # FP match x: case None: return 0 diff --git a/python/ql/test/query-tests/Imports/PyCheckerTests/ImportandImportFrom.qlref b/python/ql/test/query-tests/Imports/PyCheckerTests/ImportandImportFrom.qlref index 3d50843db7eb..ed5a37e9d476 100644 --- a/python/ql/test/query-tests/Imports/PyCheckerTests/ImportandImportFrom.qlref +++ b/python/ql/test/query-tests/Imports/PyCheckerTests/ImportandImportFrom.qlref @@ -1 +1,2 @@ -Imports/ImportandImportFrom.ql +query: Imports/ImportandImportFrom.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/PyCheckerTests/ModuleImportsItself.qlref b/python/ql/test/query-tests/Imports/PyCheckerTests/ModuleImportsItself.qlref index e6bc27b30652..a5a25747abf6 100644 --- a/python/ql/test/query-tests/Imports/PyCheckerTests/ModuleImportsItself.qlref +++ b/python/ql/test/query-tests/Imports/PyCheckerTests/ModuleImportsItself.qlref @@ -1 +1,2 @@ -Imports/ModuleImportsItself.ql +query: Imports/ModuleImportsItself.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/PyCheckerTests/imports_test.py b/python/ql/test/query-tests/Imports/PyCheckerTests/imports_test.py index 6224c788c5eb..b8fa4a7ae375 100644 --- a/python/ql/test/query-tests/Imports/PyCheckerTests/imports_test.py +++ b/python/ql/test/query-tests/Imports/PyCheckerTests/imports_test.py @@ -1,11 +1,11 @@ #Import and import from -import test_module2 +import test_module2 # $ Alert[py/import-and-import-from] from test_module2 import func #Module imports itself -import imports_test +import imports_test # $ Alert[py/import-own-module] import pkg_ok import pkg_notok diff --git a/python/ql/test/query-tests/Imports/PyCheckerTests/pkg_notok/__init__.py b/python/ql/test/query-tests/Imports/PyCheckerTests/pkg_notok/__init__.py index b0e269d67a5c..ecfa5291dc30 100644 --- a/python/ql/test/query-tests/Imports/PyCheckerTests/pkg_notok/__init__.py +++ b/python/ql/test/query-tests/Imports/PyCheckerTests/pkg_notok/__init__.py @@ -1,7 +1,7 @@ class Foo(object): pass -import pkg_notok +import pkg_notok # $ Alert[py/import-and-import-from] Alert[py/import-own-module] # This import is a bit tricky. It will make `bar` available in as `pkg_notok.bar` as a # side effect (see https://docs.python.org/3/reference/import.html#submodules), but the @@ -9,6 +9,6 @@ class Foo(object): # module imports itself. import pkg_notok.bar -from pkg_notok import Foo -from pkg_notok import Foo as NotOkFoo -from pkg_notok import * +from pkg_notok import Foo # $ Alert[py/import-own-module] +from pkg_notok import Foo as NotOkFoo # $ Alert[py/import-own-module] +from pkg_notok import * # $ Alert[py/import-own-module] diff --git a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/ModuleLevelCyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/ModuleLevelCyclicImport.qlref index 8b9bc8c123ae..e0e35483fedd 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/ModuleLevelCyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/ModuleLevelCyclicImport.qlref @@ -1 +1,2 @@ -Imports/ModuleLevelCyclicImport.ql +query: Imports/ModuleLevelCyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module3.py b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module3.py index 83f5eda9557a..e3d76ff53a7a 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module3.py +++ b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module3.py @@ -5,4 +5,4 @@ @dataclasses.dataclass() class Foo: - bars: typing.List[module4.Bar] + bars: typing.List[module4.Bar] # $ Alert diff --git a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module4.py b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module4.py index b6da208fbe34..e7864e9b6cab 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module4.py +++ b/python/ql/test/query-tests/Imports/cyclic-module-annotations-fp/module4.py @@ -5,5 +5,5 @@ @dataclasses.dataclass() class Bar: - def is_in_foo(self, foo: module3.Foo): + def is_in_foo(self, foo: module3.Foo): # $ Alert return self in foo.bars diff --git a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/CyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/CyclicImport.qlref index 814bba9fad6a..082797c92265 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/CyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/CyclicImport.qlref @@ -1 +1,2 @@ -Imports/CyclicImport.ql \ No newline at end of file +query: Imports/CyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/ModuleLevelCyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/ModuleLevelCyclicImport.qlref index 5119f8fdaae2..e0e35483fedd 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/ModuleLevelCyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/false-negative/ModuleLevelCyclicImport.qlref @@ -1 +1,2 @@ -Imports/ModuleLevelCyclicImport.ql \ No newline at end of file +query: Imports/ModuleLevelCyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/CyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/CyclicImport.qlref index 814bba9fad6a..082797c92265 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/CyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/CyclicImport.qlref @@ -1 +1,2 @@ -Imports/CyclicImport.ql \ No newline at end of file +query: Imports/CyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/ModuleLevelCyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/ModuleLevelCyclicImport.qlref index 5119f8fdaae2..e0e35483fedd 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/ModuleLevelCyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module-package-fp/true-negative/ModuleLevelCyclicImport.qlref @@ -1 +1,2 @@ -Imports/ModuleLevelCyclicImport.ql \ No newline at end of file +query: Imports/ModuleLevelCyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module/CyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module/CyclicImport.qlref index 814bba9fad6a..082797c92265 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/CyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module/CyclicImport.qlref @@ -1 +1,2 @@ -Imports/CyclicImport.ql \ No newline at end of file +query: Imports/CyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module/ModuleLevelCyclicImport.qlref b/python/ql/test/query-tests/Imports/cyclic-module/ModuleLevelCyclicImport.qlref index 5119f8fdaae2..e0e35483fedd 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/ModuleLevelCyclicImport.qlref +++ b/python/ql/test/query-tests/Imports/cyclic-module/ModuleLevelCyclicImport.qlref @@ -1 +1,2 @@ -Imports/ModuleLevelCyclicImport.ql \ No newline at end of file +query: Imports/ModuleLevelCyclicImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module1.py b/python/ql/test/query-tests/Imports/cyclic-module/module1.py index 55ef075e9e6e..e17ac87cdca2 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module1.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module1.py @@ -1,20 +1,20 @@ # potentially crashing cycles import module2 -import module3 +import module3 # $ Alert[py/cyclic-import] -a1 = module2.a2 +a1 = module2.a2 # $ Alert[py/unsafe-cyclic-import] b1 = 2 # bad style cycles -import module4 +import module4 # $ Alert[py/cyclic-import] def foo(): - import module5 + import module5 # $ Alert[py/cyclic-import] # okay, because some of the cycle is not top level -import module6 +import module6 # $ Alert[py/cyclic-import] # OK because this import occurs after relevant definition (a1) -import module8 +import module8 # $ Alert[py/cyclic-import] #OK because cycle is guarded by `if False:` from module10 import x diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module2.py b/python/ql/test/query-tests/Imports/cyclic-module/module2.py index 333b8516adb3..81899e72e569 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module2.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module2.py @@ -1,4 +1,4 @@ import module1 # direct use -a2 = module1.a1 \ No newline at end of file +a2 = module1.a1 # $ Alert[py/unsafe-cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module3.py b/python/ql/test/query-tests/Imports/cyclic-module/module3.py index 2180fb54a285..dd391cfcf5aa 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module3.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module3.py @@ -1,2 +1,2 @@ # use via import member -from module1 import a1 \ No newline at end of file +from module1 import a1 # $ Alert[py/unsafe-cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module4.py b/python/ql/test/query-tests/Imports/cyclic-module/module4.py index 65db406bb451..790e92121d5d 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module4.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module4.py @@ -1 +1 @@ -import module1 \ No newline at end of file +import module1 # $ Alert[py/cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module5.py b/python/ql/test/query-tests/Imports/cyclic-module/module5.py index 65db406bb451..790e92121d5d 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module5.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module5.py @@ -1 +1 @@ -import module1 \ No newline at end of file +import module1 # $ Alert[py/cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module6.py b/python/ql/test/query-tests/Imports/cyclic-module/module6.py index 5a5fcd149ac6..df0376aceaa9 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module6.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module6.py @@ -1,2 +1,2 @@ def foo(): - import module7 \ No newline at end of file + import module7 # $ Alert[py/cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module7.py b/python/ql/test/query-tests/Imports/cyclic-module/module7.py index d0b18ba5894d..6a961467bad7 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module7.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module7.py @@ -1 +1 @@ -from module1 import a1 \ No newline at end of file +from module1 import a1 # $ Alert[py/cyclic-import] \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module8.py b/python/ql/test/query-tests/Imports/cyclic-module/module8.py index 185ee214da83..8117f9a6f9c5 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module8.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module8.py @@ -1,4 +1,4 @@ -import module1 +import module1 # $ Alert[py/cyclic-import] class Foo(object): a = module1.a1 \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/cyclic-module/module9.py b/python/ql/test/query-tests/Imports/cyclic-module/module9.py index 06ab5b933058..b8dfb4e10a6d 100644 --- a/python/ql/test/query-tests/Imports/cyclic-module/module9.py +++ b/python/ql/test/query-tests/Imports/cyclic-module/module9.py @@ -1,6 +1,6 @@ x = 1 -import main +import main # $ Alert[py/cyclic-import] y = 2 \ No newline at end of file diff --git a/python/ql/test/query-tests/Imports/deprecated/DeprecatedModule.qlref b/python/ql/test/query-tests/Imports/deprecated/DeprecatedModule.qlref index 9f87b11d807c..93ed1e7b4be7 100644 --- a/python/ql/test/query-tests/Imports/deprecated/DeprecatedModule.qlref +++ b/python/ql/test/query-tests/Imports/deprecated/DeprecatedModule.qlref @@ -1 +1,2 @@ -Imports/DeprecatedModule.ql +query: Imports/DeprecatedModule.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/deprecated/test.py b/python/ql/test/query-tests/Imports/deprecated/test.py index ce70d29794eb..6cf11feb7824 100644 --- a/python/ql/test/query-tests/Imports/deprecated/test.py +++ b/python/ql/test/query-tests/Imports/deprecated/test.py @@ -1,11 +1,11 @@ # Some deprecated modules -import rfc822 -import posixfile +import rfc822 # $ Alert +import posixfile # $ Alert # We should only report a bad import once class Foo(object): def foo(self): - import md5 + import md5 # $ Alert # Backwards compatible code, should not report try: diff --git a/python/ql/test/query-tests/Imports/general/FromImportOfMutableAttribute.qlref b/python/ql/test/query-tests/Imports/general/FromImportOfMutableAttribute.qlref index 9353115309f8..302bb0895a6b 100644 --- a/python/ql/test/query-tests/Imports/general/FromImportOfMutableAttribute.qlref +++ b/python/ql/test/query-tests/Imports/general/FromImportOfMutableAttribute.qlref @@ -1 +1,2 @@ -Imports/FromImportOfMutableAttribute.ql \ No newline at end of file +query: Imports/FromImportOfMutableAttribute.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/ImportShadowedByLoopVar.qlref b/python/ql/test/query-tests/Imports/general/ImportShadowedByLoopVar.qlref index 3844f21922fb..d5b4aaa16938 100644 --- a/python/ql/test/query-tests/Imports/general/ImportShadowedByLoopVar.qlref +++ b/python/ql/test/query-tests/Imports/general/ImportShadowedByLoopVar.qlref @@ -1 +1,2 @@ -Imports/ImportShadowedByLoopVar.ql \ No newline at end of file +query: Imports/ImportShadowedByLoopVar.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/ImportStarUsed.qlref b/python/ql/test/query-tests/Imports/general/ImportStarUsed.qlref index 35f8bff3e5fc..099627be88cd 100644 --- a/python/ql/test/query-tests/Imports/general/ImportStarUsed.qlref +++ b/python/ql/test/query-tests/Imports/general/ImportStarUsed.qlref @@ -1 +1,2 @@ -Imports/ImportStarUsed.ql \ No newline at end of file +query: Imports/ImportStarUsed.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/Imports.qlref b/python/ql/test/query-tests/Imports/general/Imports.qlref index 6bcdb2d9b5fd..926c62f0a410 100644 --- a/python/ql/test/query-tests/Imports/general/Imports.qlref +++ b/python/ql/test/query-tests/Imports/general/Imports.qlref @@ -1 +1,2 @@ -Imports/Imports.ql +query: Imports/Imports.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/MultipleImport.qlref b/python/ql/test/query-tests/Imports/general/MultipleImport.qlref index a4d2195b6886..7826fb7e33c9 100644 --- a/python/ql/test/query-tests/Imports/general/MultipleImport.qlref +++ b/python/ql/test/query-tests/Imports/general/MultipleImport.qlref @@ -1 +1,2 @@ -Imports/MultipleImports.ql +query: Imports/MultipleImports.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/UnintentionalImport.qlref b/python/ql/test/query-tests/Imports/general/UnintentionalImport.qlref index 4f1b985d5c2c..0ea9a54298fd 100644 --- a/python/ql/test/query-tests/Imports/general/UnintentionalImport.qlref +++ b/python/ql/test/query-tests/Imports/general/UnintentionalImport.qlref @@ -1 +1,2 @@ -Imports/UnintentionalImport.ql +query: Imports/UnintentionalImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/general/imports_mutable.py b/python/ql/test/query-tests/Imports/general/imports_mutable.py index 0519a2071d8a..91efefc7e9f1 100644 --- a/python/ql/test/query-tests/Imports/general/imports_mutable.py +++ b/python/ql/test/query-tests/Imports/general/imports_mutable.py @@ -1,4 +1,4 @@ -from mutable_attr import x, y +from mutable_attr import x, y # $ Alert[py/import-of-mutable-attribute] def f(): print(x) diff --git a/python/ql/test/query-tests/Imports/general/imports_test.py b/python/ql/test/query-tests/Imports/general/imports_test.py index 4b51f8254fc4..8a4faf16a345 100644 --- a/python/ql/test/query-tests/Imports/general/imports_test.py +++ b/python/ql/test/query-tests/Imports/general/imports_test.py @@ -1,5 +1,5 @@ #Multiple imports on a single line -import module1, module2 +import module1, module2 # $ Alert[py/multiple-imports-on-line] #Cyclic import @@ -13,13 +13,13 @@ import module -for module in range(10): +for module in range(10): # $ Alert[py/import-shadowed-loop-variable] print(module) #Import * used -from module import * -from module_without_all import * +from module import * # $ Alert[py/import-star-used] +from module_without_all import * # $ Alert[py/import-star-used] Alert[py/polluting-import] #Unused import @@ -30,8 +30,8 @@ func1 #Duplicate import -import module1 -import module2 +import module1 # $ Alert[py/repeated-import] +import module2 # $ Alert[py/repeated-import] #OK -- Import used in epytext documentation. import used_in_docs @@ -62,4 +62,4 @@ def __init__(self): different # FP reported in https://github.com/github/codeql/issues/4003 -from module_that_does_not_exist import * +from module_that_does_not_exist import * # $ Alert[py/import-star-used] diff --git a/python/ql/test/query-tests/Imports/unused/UnusedImport.qlref b/python/ql/test/query-tests/Imports/unused/UnusedImport.qlref index e6bb7ab44cb0..103f075bb149 100644 --- a/python/ql/test/query-tests/Imports/unused/UnusedImport.qlref +++ b/python/ql/test/query-tests/Imports/unused/UnusedImport.qlref @@ -1 +1,2 @@ -Imports/UnusedImport.ql +query: Imports/UnusedImport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Imports/unused/import_structure_1.py b/python/ql/test/query-tests/Imports/unused/import_structure_1.py index a76fe99f12cc..3afada1956b3 100644 --- a/python/ql/test/query-tests/Imports/unused/import_structure_1.py +++ b/python/ql/test/query-tests/Imports/unused/import_structure_1.py @@ -2,7 +2,7 @@ # lines from typing import Optional -from unknown import foo, bar +from unknown import foo, bar # $ Alert var: Optional['foo'] = None diff --git a/python/ql/test/query-tests/Imports/unused/import_structure_2.py b/python/ql/test/query-tests/Imports/unused/import_structure_2.py index 90d4255ba399..01db62d54f8c 100644 --- a/python/ql/test/query-tests/Imports/unused/import_structure_2.py +++ b/python/ql/test/query-tests/Imports/unused/import_structure_2.py @@ -3,6 +3,6 @@ from typing import Optional from unknown import foo -from unknown import bar +from unknown import bar # $ Alert var: Optional['foo'] = None diff --git a/python/ql/test/query-tests/Imports/unused/imports_test.py b/python/ql/test/query-tests/Imports/unused/imports_test.py index 71363235987c..d3c7068dd88a 100644 --- a/python/ql/test/query-tests/Imports/unused/imports_test.py +++ b/python/ql/test/query-tests/Imports/unused/imports_test.py @@ -1,13 +1,13 @@ #Multiple imports on a single line -import module1, module2 +import module1, module2 # $ Alert #Cyclic import -import cycle +import cycle # $ Alert #Top level cyclic import -import top_level_cycle +import top_level_cycle # $ Alert #Import shadowed by loop variable @@ -24,14 +24,14 @@ #Unused import from module2 import func1 -from module2 import func2 +from module2 import func2 # $ Alert module1.func func1 #Duplicate import import module1 -import module2 +import module2 # $ Alert #OK -- Import used in epytext documentation. import used_in_docs @@ -113,6 +113,6 @@ def baz() -> Optional['subexpression_return_type']: pass -from pytest_fixtures import not_a_fixture # BAD +from pytest_fixtures import not_a_fixture # $ Alert # BAD from pytest_fixtures import fixture, wrapped_fixture # GOOD (pytest fixtures are used implicitly by pytest) from pytest_fixtures import session_fixture, wrapped_autouse_fixture # GOOD (pytest fixtures are used implicitly by pytest) diff --git a/python/ql/test/query-tests/Lexical/ToDoComment/ToDoComment.qlref b/python/ql/test/query-tests/Lexical/ToDoComment/ToDoComment.qlref index 4568a99f3882..2915fa8c3668 100644 --- a/python/ql/test/query-tests/Lexical/ToDoComment/ToDoComment.qlref +++ b/python/ql/test/query-tests/Lexical/ToDoComment/ToDoComment.qlref @@ -1 +1 @@ -Lexical/ToDoComment.ql \ No newline at end of file +Lexical/ToDoComment.ql diff --git a/python/ql/test/query-tests/Lexical/commented_out_code/test.py b/python/ql/test/query-tests/Lexical/commented_out_code/test.py index 067855b67447..2502799cca73 100644 --- a/python/ql/test/query-tests/Lexical/commented_out_code/test.py +++ b/python/ql/test/query-tests/Lexical/commented_out_code/test.py @@ -14,56 +14,56 @@ def f(x): do_something() #else: # do_something_else() - -# Some non-code comments. + +# Some non-code comments. # Space immediately after scope start and between functions. -# +# #class CommentedOut: -# +# # def __init__(self): # pass -# +# # def method(self): # # pass -# +# #def g(y): -# assert y +# assert y # with y: # # Commented out comment # if y: # do_something() # else: # do_something_else() -# +# #def h(z): # '''Doc string # ''' # # Commented out comment -# +# # followed_by_space() -# +# # more_code() - + #def j(): # """ Doc string """ # pass - + #def k(): # # """ Doc string """ # pass - + #def l(): # -# """ -# Doc string +# """ +# Doc string # """ # # pass - + # # # @@ -72,7 +72,7 @@ def f(x): # pass # # -# +# some_code_to_break_up_comments() #with x: @@ -88,7 +88,7 @@ def a_function_to_break_up_comments(): pass # An example explaining -# something which contains +# something which contains # the following code: # # def f(): @@ -96,5 +96,3 @@ def a_function_to_break_up_comments(): # x.y = z # return x # - - \ No newline at end of file diff --git a/python/ql/test/query-tests/Metrics/cyclo/CyclomaticComplexity.qlref b/python/ql/test/query-tests/Metrics/cyclo/CyclomaticComplexity.qlref index c74ae215bb40..8e150c5a5c8a 100644 --- a/python/ql/test/query-tests/Metrics/cyclo/CyclomaticComplexity.qlref +++ b/python/ql/test/query-tests/Metrics/cyclo/CyclomaticComplexity.qlref @@ -1 +1 @@ -Metrics/CyclomaticComplexity.ql +query: Metrics/CyclomaticComplexity.ql diff --git a/python/ql/test/query-tests/Metrics/functions/FunctionStatementNestingDepth.qlref b/python/ql/test/query-tests/Metrics/functions/FunctionStatementNestingDepth.qlref index 797f223792f2..5be0496cf087 100644 --- a/python/ql/test/query-tests/Metrics/functions/FunctionStatementNestingDepth.qlref +++ b/python/ql/test/query-tests/Metrics/functions/FunctionStatementNestingDepth.qlref @@ -1 +1 @@ -Metrics/FunctionStatementNestingDepth.ql \ No newline at end of file +query: Metrics/FunctionStatementNestingDepth.ql diff --git a/python/ql/test/query-tests/Metrics/imports/DirectImports.qlref b/python/ql/test/query-tests/Metrics/imports/DirectImports.qlref index 84fe2dc5805b..0878b8892634 100644 --- a/python/ql/test/query-tests/Metrics/imports/DirectImports.qlref +++ b/python/ql/test/query-tests/Metrics/imports/DirectImports.qlref @@ -1 +1 @@ -Metrics/DirectImports.ql +query: Metrics/DirectImports.ql diff --git a/python/ql/test/query-tests/Metrics/imports/TransitiveImports.qlref b/python/ql/test/query-tests/Metrics/imports/TransitiveImports.qlref index 1bacdce45c28..35e369b89b41 100644 --- a/python/ql/test/query-tests/Metrics/imports/TransitiveImports.qlref +++ b/python/ql/test/query-tests/Metrics/imports/TransitiveImports.qlref @@ -1 +1 @@ -Metrics/TransitiveImports.ql \ No newline at end of file +query: Metrics/TransitiveImports.ql diff --git a/python/ql/test/query-tests/Metrics/lines/CommentRatio.qlref b/python/ql/test/query-tests/Metrics/lines/CommentRatio.qlref index 9c3179ac5033..a8be2d84cc5d 100644 --- a/python/ql/test/query-tests/Metrics/lines/CommentRatio.qlref +++ b/python/ql/test/query-tests/Metrics/lines/CommentRatio.qlref @@ -1 +1 @@ -Metrics/CommentRatio.ql +query: Metrics/CommentRatio.ql diff --git a/python/ql/test/query-tests/Metrics/lines/FLinesOfCode.qlref b/python/ql/test/query-tests/Metrics/lines/FLinesOfCode.qlref index 2ac69b8f67a8..6a2c24b94b1d 100644 --- a/python/ql/test/query-tests/Metrics/lines/FLinesOfCode.qlref +++ b/python/ql/test/query-tests/Metrics/lines/FLinesOfCode.qlref @@ -1 +1 @@ -Metrics/FLinesOfCode.ql +query: Metrics/FLinesOfCode.ql diff --git a/python/ql/test/query-tests/Metrics/ratios/CommentRatio.qlref b/python/ql/test/query-tests/Metrics/ratios/CommentRatio.qlref index dc273e169828..a8be2d84cc5d 100644 --- a/python/ql/test/query-tests/Metrics/ratios/CommentRatio.qlref +++ b/python/ql/test/query-tests/Metrics/ratios/CommentRatio.qlref @@ -1 +1 @@ -Metrics/CommentRatio.ql \ No newline at end of file +query: Metrics/CommentRatio.ql diff --git a/python/ql/test/query-tests/Metrics/ratios/DocStringRatio.qlref b/python/ql/test/query-tests/Metrics/ratios/DocStringRatio.qlref index ec66c5cdc834..c8c5812818f6 100644 --- a/python/ql/test/query-tests/Metrics/ratios/DocStringRatio.qlref +++ b/python/ql/test/query-tests/Metrics/ratios/DocStringRatio.qlref @@ -1 +1 @@ -Metrics/DocStringRatio.ql \ No newline at end of file +query: Metrics/DocStringRatio.ql diff --git a/python/ql/test/query-tests/Metrics/tests/FNumberOfTests.qlref b/python/ql/test/query-tests/Metrics/tests/FNumberOfTests.qlref index e7301c3b2302..46d66e549876 100644 --- a/python/ql/test/query-tests/Metrics/tests/FNumberOfTests.qlref +++ b/python/ql/test/query-tests/Metrics/tests/FNumberOfTests.qlref @@ -1 +1 @@ -Metrics/FNumberOfTests.ql \ No newline at end of file +query: Metrics/FNumberOfTests.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.expected b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.expected index cf3a06ac7c8f..6e9c8ff47dc8 100644 --- a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.expected @@ -1,3 +1,7 @@ +#select +| django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input | +| django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input | +| django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | django_tests.py:11:26:11:32 | ControlFlowNode for request | django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | Cookie is constructed from a $@. | django_tests.py:11:26:11:32 | ControlFlowNode for request | user-supplied input | edges | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:6:21:6:31 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:7:21:7:31 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | @@ -22,7 +26,3 @@ nodes | django_tests.py:13:59:13:69 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | django_tests.py:13:59:13:82 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths -#select -| django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input | -| django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input | -| django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | django_tests.py:11:26:11:32 | ControlFlowNode for request | django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | Cookie is constructed from a $@. | django_tests.py:11:26:11:32 | ControlFlowNode for request | user-supplied input | diff --git a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.qlref b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.qlref index a405c564b1bf..788c1b424ff5 100644 --- a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/CookieInjection.qlref @@ -1 +1,2 @@ -Security/CWE-020/CookieInjection.ql \ No newline at end of file +query: Security/CWE-020/CookieInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/django_tests.py b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/django_tests.py index e070f5cab82b..f77e8f20ea21 100644 --- a/python/ql/test/query-tests/Security/CWE-020-CookieInjection/django_tests.py +++ b/python/ql/test/query-tests/Security/CWE-020-CookieInjection/django_tests.py @@ -1,20 +1,20 @@ import django.http from django.urls import path -def django_response_bad(request): +def django_response_bad(request): # $ Source resp = django.http.HttpResponse() - resp.set_cookie(request.GET.get("name"), # BAD: Cookie is constructed from user input - request.GET.get("value")) + resp.set_cookie(request.GET.get("name"), # $ Alert # BAD: Cookie is constructed from user input + request.GET.get("value")) # $ Alert return resp -def django_response_bad2(request): +def django_response_bad2(request): # $ Source response = django.http.HttpResponse() - response['Set-Cookie'] = f"{request.GET.get('name')}={request.GET.get('value')}; SameSite=None;" # BAD: Cookie header is constructed from user input. + response['Set-Cookie'] = f"{request.GET.get('name')}={request.GET.get('value')}; SameSite=None;" # $ Alert # BAD: Cookie header is constructed from user input. return response # fake setup, you can't actually run this urlpatterns = [ path("response_bad", django_response_bad), path("response_bd2", django_response_bad2) -] \ No newline at end of file +] diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.qlref b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.qlref index c91bf44f815c..34ac0b640147 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.qlref @@ -1 +1 @@ -Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.ql +query: Security/CWE-020-ExternalAPIs/ExternalAPIsUsedWithUntrustedData.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.qlref b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.qlref index 03c06feeec88..fbacbf2a07a0 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.qlref @@ -1 +1,2 @@ -Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql +query: Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py index 18b46298d8af..f2857914c03b 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/test.py @@ -2,7 +2,7 @@ import hmac import base64 -from flask import Flask, request, make_response +from flask import Flask, request, make_response # $ Source app = Flask(__name__) SECRET_KEY = b"SECRET_KEY" @@ -12,7 +12,7 @@ def hmac_example(): data_raw = request.args.get("data").encode('utf-8') data = base64.decodebytes(data_raw) - my_hmac = hmac.new(SECRET_KEY, data, hashlib.sha256) + my_hmac = hmac.new(SECRET_KEY, data, hashlib.sha256) # $ Alert digest = my_hmac.digest() print(digest) return "ok" @@ -22,7 +22,7 @@ def hmac_example(): def hmac_example2(): data_raw = request.args.get("data").encode('utf-8') data = base64.decodebytes(data_raw) - my_hmac = hmac.new(key=SECRET_KEY, msg=data, digestmod=hashlib.sha256) + my_hmac = hmac.new(key=SECRET_KEY, msg=data, digestmod=hashlib.sha256) # $ Alert digest = my_hmac.digest() print(digest) return "ok" @@ -32,16 +32,16 @@ def hmac_example2(): def unknown_lib_1(): from unknown.lib import func data = request.args.get("data") - func(data) - func(kw=data) + func(data) # $ Alert + func(kw=data) # $ Alert @app.route("/unknown-lib-2") def unknown_lib_2(): import unknown.lib data = request.args.get("data") - unknown.lib.func(data) - unknown.lib.func(kw=data) + unknown.lib.func(data) # $ Alert + unknown.lib.func(kw=data) # $ Alert def handle_this(arg, application = None): diff --git a/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref b/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref index e818d9472521..d1afa3858252 100644 --- a/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref @@ -1 +1,2 @@ -Security/CWE-020/IncompleteHostnameRegExp.ql \ No newline at end of file +query: Security/CWE-020/IncompleteHostnameRegExp.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/hosttest.py b/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/hosttest.py index ca7f7094a8c9..e2e90e651424 100644 --- a/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/hosttest.py +++ b/python/ql/test/query-tests/Security/CWE-020-IncompleteHostnameRegExp/hosttest.py @@ -3,7 +3,7 @@ app = Flask(__name__) -UNSAFE_REGEX = re.compile("(www|beta).example.com/") +UNSAFE_REGEX = re.compile("(www|beta).example.com/") # $ Alert SAFE_REGEX = re.compile(r"(www|beta)\.example\.com/") @app.route('/some/path/bad') diff --git a/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref b/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref index 3fa6794419d7..1c4c23821534 100644 --- a/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref @@ -1 +1,2 @@ -Security/CWE-020/IncompleteUrlSubstringSanitization.ql \ No newline at end of file +query: Security/CWE-020/IncompleteUrlSubstringSanitization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/urltest.py b/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/urltest.py index 308b946603b8..bc59d83819ac 100644 --- a/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/urltest.py +++ b/python/ql/test/query-tests/Security/CWE-020-IncompleteUrlSubstringSanitization/urltest.py @@ -6,13 +6,13 @@ @app.route('/some/path/bad1') def unsafe1(request): target = request.args.get('target', '') - if "example.com" in target: + if "example.com" in target: # $ Alert return redirect(target) @app.route('/some/path/bad2') def unsafe2(request): target = request.args.get('target', '') - if target.endswith("example.com"): + if target.endswith("example.com"): # $ Alert return redirect(target) diff --git a/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref b/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref index 77b5c92707f9..c42315c4550e 100644 --- a/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref +++ b/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref @@ -1 +1,2 @@ -Security/CWE-020/OverlyLargeRange.ql +query: Security/CWE-020/OverlyLargeRange.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/test.py b/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/test.py index 43380ccef0db..ca3cfd991909 100644 --- a/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/test.py +++ b/python/ql/test/query-tests/Security/CWE-020-SuspiciousRegexpRange/test.py @@ -1,10 +1,10 @@ import re -overlap1 = re.compile(r'^[0-93-5]$') # NOT OK +overlap1 = re.compile(r'^[0-93-5]$') # $ Alert # NOT OK -overlap2 = re.compile(r'[A-ZA-z]') # NOT OK +overlap2 = re.compile(r'[A-ZA-z]') # $ Alert # NOT OK -isEmpty = re.compile(r'^[z-a]$') # NOT OK +isEmpty = re.compile(r'^[z-a]$') # $ Alert # NOT OK isAscii = re.compile(r'^[\x00-\x7F]*$') # OK @@ -14,18 +14,18 @@ NON_ALPHANUMERIC_REGEXP = re.compile(r'([^\#-~| |!])') # OK -smallOverlap = re.compile(r'[0-9a-fA-f]') # NOT OK +smallOverlap = re.compile(r'[0-9a-fA-f]') # $ Alert # NOT OK -weirdRange = re.compile(r'[$-`]') # NOT OK +weirdRange = re.compile(r'[$-`]') # $ Alert # NOT OK -keywordOperator = re.compile(r'[!\~\*\/%+-<>\^|=&]') # NOT OK +keywordOperator = re.compile(r'[!\~\*\/%+-<>\^|=&]') # $ Alert # NOT OK -notYoutube = re.compile(r'youtu\.be\/[a-z1-9.-_]+') # NOT OK +notYoutube = re.compile(r'youtu\.be\/[a-z1-9.-_]+') # $ Alert # NOT OK -numberToLetter = re.compile(r'[7-F]') # NOT OK +numberToLetter = re.compile(r'[7-F]') # $ Alert # NOT OK -overlapsWithClass1 = re.compile(r'[0-9\d]') # NOT OK +overlapsWithClass1 = re.compile(r'[0-9\d]') # $ Alert # NOT OK -overlapsWithClass2 = re.compile(r'[\w,.-?:*+]') # NOT OK +overlapsWithClass2 = re.compile(r'[\w,.-?:*+]') # $ Alert # NOT OK -unicodeStuff = re.compile('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]') # NOT OK \ No newline at end of file +unicodeStuff = re.compile('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]') # $ Alert # NOT OK diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index 6f98ea1aae2b..abdccddd631b 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -1,3 +1,13 @@ +#select +| tarslip.py:15:1:15:3 | ControlFlowNode for tar | tarslip.py:14:7:14:39 | ControlFlowNode for Attribute() | tarslip.py:15:1:15:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:14:7:14:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:20:17:20:21 | ControlFlowNode for entry | tarslip.py:18:7:18:39 | ControlFlowNode for Attribute() | tarslip.py:20:17:20:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:18:7:18:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:39:17:39:21 | ControlFlowNode for entry | tarslip.py:35:7:35:39 | ControlFlowNode for Attribute() | tarslip.py:39:17:39:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:35:7:35:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:43:24:43:26 | ControlFlowNode for tar | tarslip.py:42:7:42:39 | ControlFlowNode for Attribute() | tarslip.py:43:24:43:26 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:42:7:42:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:61:21:61:25 | ControlFlowNode for entry | tarslip.py:58:7:58:39 | ControlFlowNode for Attribute() | tarslip.py:61:21:61:25 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:58:7:58:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:91:1:91:3 | ControlFlowNode for tar | tarslip.py:90:7:90:39 | ControlFlowNode for Attribute() | tarslip.py:91:1:91:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:90:7:90:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:96:17:96:21 | ControlFlowNode for entry | tarslip.py:94:7:94:39 | ControlFlowNode for Attribute() | tarslip.py:96:17:96:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:94:7:94:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:110:1:110:3 | ControlFlowNode for tar | tarslip.py:109:7:109:39 | ControlFlowNode for Attribute() | tarslip.py:110:1:110:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:109:7:109:39 | ControlFlowNode for Attribute() | potentially untrusted source | +| tarslip.py:113:24:113:26 | ControlFlowNode for tar | tarslip.py:112:7:112:39 | ControlFlowNode for Attribute() | tarslip.py:113:24:113:26 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:112:7:112:39 | ControlFlowNode for Attribute() | potentially untrusted source | edges | tarslip.py:14:1:14:3 | ControlFlowNode for tar | tarslip.py:15:1:15:3 | ControlFlowNode for tar | provenance | | | tarslip.py:14:7:14:39 | ControlFlowNode for Attribute() | tarslip.py:14:1:14:3 | ControlFlowNode for tar | provenance | | @@ -54,13 +64,3 @@ nodes | tarslip.py:112:7:112:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | tarslip.py:113:24:113:26 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | subpaths -#select -| tarslip.py:15:1:15:3 | ControlFlowNode for tar | tarslip.py:14:7:14:39 | ControlFlowNode for Attribute() | tarslip.py:15:1:15:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:14:7:14:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:20:17:20:21 | ControlFlowNode for entry | tarslip.py:18:7:18:39 | ControlFlowNode for Attribute() | tarslip.py:20:17:20:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:18:7:18:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:39:17:39:21 | ControlFlowNode for entry | tarslip.py:35:7:35:39 | ControlFlowNode for Attribute() | tarslip.py:39:17:39:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:35:7:35:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:43:24:43:26 | ControlFlowNode for tar | tarslip.py:42:7:42:39 | ControlFlowNode for Attribute() | tarslip.py:43:24:43:26 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:42:7:42:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:61:21:61:25 | ControlFlowNode for entry | tarslip.py:58:7:58:39 | ControlFlowNode for Attribute() | tarslip.py:61:21:61:25 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:58:7:58:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:91:1:91:3 | ControlFlowNode for tar | tarslip.py:90:7:90:39 | ControlFlowNode for Attribute() | tarslip.py:91:1:91:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:90:7:90:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:96:17:96:21 | ControlFlowNode for entry | tarslip.py:94:7:94:39 | ControlFlowNode for Attribute() | tarslip.py:96:17:96:21 | ControlFlowNode for entry | This file extraction depends on a $@. | tarslip.py:94:7:94:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:110:1:110:3 | ControlFlowNode for tar | tarslip.py:109:7:109:39 | ControlFlowNode for Attribute() | tarslip.py:110:1:110:3 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:109:7:109:39 | ControlFlowNode for Attribute() | potentially untrusted source | -| tarslip.py:113:24:113:26 | ControlFlowNode for tar | tarslip.py:112:7:112:39 | ControlFlowNode for Attribute() | tarslip.py:113:24:113:26 | ControlFlowNode for tar | This file extraction depends on a $@. | tarslip.py:112:7:112:39 | ControlFlowNode for Attribute() | potentially untrusted source | diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref index cfede0c92b21..c9b6b9f4f069 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.qlref @@ -1 +1,2 @@ -Security/CWE-022/TarSlip.ql +query: Security/CWE-022/TarSlip.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py b/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py index 2c06d01adfd5..b2614b8a6d11 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/tarslip.py @@ -11,13 +11,13 @@ for entry in tar: tar.extract(entry) -tar = tarfile.open(unsafe_filename_tar) -tar.extractall() +tar = tarfile.open(unsafe_filename_tar) # $ Source +tar.extractall() # $ Alert tar.close() -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source for entry in tar: - tar.extract(entry) + tar.extract(entry) # $ Alert tar = tarfile.open(safe_filename_tar) tar.extractall() @@ -32,15 +32,15 @@ tar.extract(entry, "/tmp/unpack/") #Part Sanitized -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source for entry in tar: if ".." in entry.name: raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert #Unsanitized members -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(members=tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source +tar.extractall(members=tar) # $ Alert #Sanitize members @@ -55,10 +55,10 @@ def safemembers(members): # Wrong sanitizer (is missing not) -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source for entry in tar: if os.path.isabs(entry.name) or ".." in entry.name: - tar.extract(entry, "/tmp/unpack/") + tar.extract(entry, "/tmp/unpack/") # $ Alert # OK Sanitized using not @@ -87,13 +87,13 @@ def safemembers(members): extraction_filter = "fully_trusted" -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(filter=extraction_filter) # unsafe +tar = tarfile.open(unsafe_filename_tar) # $ Source +tar.extractall(filter=extraction_filter) # $ Alert # unsafe tar.close() -tar = tarfile.open(unsafe_filename_tar) +tar = tarfile.open(unsafe_filename_tar) # $ Source for entry in tar: - tar.extract(entry, filter=extraction_filter) # unsafe + tar.extract(entry, filter=extraction_filter) # $ Alert # unsafe extraction_filter = "data" @@ -106,11 +106,11 @@ def safemembers(members): tar.extract(entry, filter=extraction_filter) # safe extraction_filter = None -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(filter=extraction_filter) # unsafe +tar = tarfile.open(unsafe_filename_tar) # $ Source +tar.extractall(filter=extraction_filter) # $ Alert # unsafe -tar = tarfile.open(unsafe_filename_tar) -tar.extractall(members=tar, filter=extraction_filter) # unsafe +tar = tarfile.open(unsafe_filename_tar) # $ Source +tar.extractall(members=tar, filter=extraction_filter) # $ Alert # unsafe tar = tarfile.open(unsafe_filename_tar) tar.extractall(members=safemembers(tar), filter=extraction_filter) # safe -- we assume `safemembers` makes up for the unsafe filter diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py index f1fe834e4936..432286eeb6d3 100644 --- a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/JinjaSsti.py @@ -4,21 +4,21 @@ from jinja2 import Environment, DictLoader, escape -def a(request): +def a(request): # $ Source # Load the template template = request.GET['template'] - t = Template(template) # BAD: Template constructed from user input + t = Template(template) # $ Alert # BAD: Template constructed from user input name = request.GET['name'] # Render the template with the context data html = t.render(name=escape(name)) return HttpResponse(html) -def b(request): +def b(request): # $ Source import jinja2 # Load the template template = request.GET['template'] env = Environment() - t = env.from_string(template) # BAD: Template constructed from user input + t = env.from_string(template) # $ Alert # BAD: Template constructed from user input name = request.GET['name'] # Render the template with the context data html = t.render(name=escape(name)) diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected index f92107728395..a4bf57e174c1 100644 --- a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.expected @@ -1,3 +1,6 @@ +#select +| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | +| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | edges | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | provenance | AdditionalTaintStep | | JinjaSsti.py:9:5:9:12 | ControlFlowNode for template | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | provenance | | @@ -11,6 +14,3 @@ nodes | JinjaSsti.py:19:5:19:12 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | semmle.label | ControlFlowNode for template | subpaths -#select -| JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | JinjaSsti.py:10:18:10:25 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:7:7:7:13 | ControlFlowNode for request | user-provided value | -| JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | JinjaSsti.py:21:25:21:32 | ControlFlowNode for template | This template construction depends on a $@. | JinjaSsti.py:16:7:16:13 | ControlFlowNode for request | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref index ead6bb469c6a..818407e3eb80 100644 --- a/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-074-TemplateInjection/TemplateInjection.qlref @@ -1 +1,2 @@ -Security/CWE-074/TemplateInjection.ql \ No newline at end of file +query: Security/CWE-074/TemplateInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.qlref b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.qlref index e38b88f29197..8d677af35712 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.qlref @@ -1 +1,2 @@ -Security/CWE-078/CommandInjection.ql +query: Security/CWE-078/CommandInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/command_injection.py b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/command_injection.py index 09dd2bf97168..676215f29d1b 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/command_injection.py +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/command_injection.py @@ -2,7 +2,7 @@ import platform import popen2 -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @@ -16,14 +16,14 @@ def python2_specific(): """ files = request.args.get("files", "") - os.popen2("ls " + files) - os.popen3("ls " + files) - os.popen4("ls " + files) + os.popen2("ls " + files) # $ Alert + os.popen3("ls " + files) # $ Alert + os.popen4("ls " + files) # $ Alert - platform.popen("ls " + files) + platform.popen("ls " + files) # $ Alert - popen2.popen2("ls " + files) - popen2.popen3("ls " + files) - popen2.popen4("ls " + files) - popen2.Popen3("ls " + files) - popen2.Popen4("ls " + files) + popen2.popen2("ls " + files) # $ Alert + popen2.popen3("ls " + files) # $ Alert + popen2.popen4("ls " + files) # $ Alert + popen2.Popen3("ls " + files) # $ Alert + popen2.Popen4("ls " + files) # $ Alert diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.qlref b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.qlref index e38b88f29197..47dd63a884ea 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.qlref @@ -1 +1 @@ -Security/CWE-078/CommandInjection.ql +query: Security/CWE-078/CommandInjection.ql diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref index fdc01b9ecbf7..6d6ee0abf7d8 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref @@ -1 +1 @@ -Security/CWE-078/UnsafeShellCommandConstruction.ql +query: Security/CWE-078/UnsafeShellCommandConstruction.ql diff --git a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.qlref b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.qlref index 9fefcf4a030d..d63a6068dc22 100644 --- a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.qlref +++ b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/Jinja2WithoutEscaping.qlref @@ -1 +1,2 @@ -Security/CWE-079/Jinja2WithoutEscaping.ql +query: Security/CWE-079/Jinja2WithoutEscaping.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/jinja2_escaping.py b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/jinja2_escaping.py index aed840ce8863..f3d1150df9ae 100644 --- a/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/jinja2_escaping.py +++ b/python/ql/test/query-tests/Security/CWE-079-Jinja2WithoutEscaping/jinja2_escaping.py @@ -6,7 +6,7 @@ app = Flask(__name__) loader = FileSystemLoader( searchpath="templates/" ) -unsafe_env = Environment(loader=loader) +unsafe_env = Environment(loader=loader) # $ Alert safe1_env = Environment(loader=loader, autoescape=True) safe2_env = Environment(loader=loader, autoescape=select_autoescape()) @@ -38,18 +38,18 @@ def safe2(): auto = select_autoescape e = Environment(autoescape=auto) # GOOD z = 0 -e = Environment(autoescape=z) # BAD +e = Environment(autoescape=z) # $ Alert # BAD E = Environment -E() # BAD -E(autoescape=z) # BAD +E() # $ Alert # BAD +E(autoescape=z) # $ Alert # BAD E(autoescape=auto) # GOOD E(autoescape=0+1) # GOOD def checked(cond=False): if cond: - e = Environment(autoescape=cond) # GOOD + e = Environment(autoescape=cond) # $ Alert # GOOD -unsafe_tmpl = Template('Hello {{ name }}!') +unsafe_tmpl = Template('Hello {{ name }}!') # $ Alert safe1_tmpl = Template('Hello {{ name }}!', autoescape=True) safe2_tmpl = Template('Hello {{ name }}!', autoescape=select_autoescape()) diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index d332231e0c99..bf4f584c8157 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -1,3 +1,7 @@ +#select +| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | edges | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:2:26:2:32 | ControlFlowNode for request | provenance | | | reflected_xss.py:2:26:2:32 | ControlFlowNode for request | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | provenance | | @@ -28,7 +32,3 @@ nodes | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths -#select -| reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to a $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.qlref b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.qlref index e0efe1024162..9cd0122e556e 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.qlref +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.qlref @@ -1 +1,2 @@ -Security/CWE-079/ReflectedXss.ql +query: Security/CWE-079/ReflectedXss.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/reflected_xss.py b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/reflected_xss.py index 98682f04f3cb..67fcf0bf9ffe 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/reflected_xss.py +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/reflected_xss.py @@ -1,5 +1,5 @@ import json -from flask import Flask, request, make_response, escape, jsonify +from flask import Flask, request, make_response, escape, jsonify # $ Source app = Flask(__name__) @@ -7,7 +7,7 @@ @app.route("/unsafe") def unsafe(): first_name = request.args.get("name", "") - return make_response("Your name is " + first_name) # NOT OK + return make_response("Your name is " + first_name) # $ Alert # NOT OK @app.route("/safe") @@ -19,13 +19,13 @@ def safe(): @app.route("/unsafe/json") def unsafe_json(): data = json.loads(request.data) - return make_response(json.dumps(data)) # NOT OK + return make_response(json.dumps(data)) # $ Alert # NOT OK @app.route("/safe/json") def safe_json(): data = json.loads(request.data) - return make_response(json.dumps(data), 200, {'Content-Type': 'application/json'}) # OK, FP + return make_response(json.dumps(data), 200, {'Content-Type': 'application/json'}) # $ SPURIOUS: Alert # OK, FP @app.route("/jsonify") diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/SqlInjection.qlref b/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/SqlInjection.qlref index b6916bd2cd46..e19181577447 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/SqlInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/SqlInjection.qlref @@ -1,2 +1,4 @@ query: Security/CWE-089/SqlInjection.ql -postprocess: utils/test/PrettyPrintModels.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/test.py b/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/test.py index 97bfa393cedf..70959d0bff03 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/test.py +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection-local-threat-model/test.py @@ -3,4 +3,4 @@ import psycopg conn = psycopg.connect(...) -conn.execute(sys.argv[1]) +conn.execute(sys.argv[1]) # $ Alert diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.qlref b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.qlref index d1d02cbe8d37..444c0e5f46aa 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.qlref @@ -1 +1,2 @@ -Security/CWE-089/SqlInjection.ql +query: Security/CWE-089/SqlInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sql_injection.py b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sql_injection.py index c79bee16cb21..52aa3169616e 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sql_injection.py +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sql_injection.py @@ -11,19 +11,19 @@ class User(models.Model): pass @app.route("/users/") -def show_user(username): +def show_user(username): # $ Source with connection.cursor() as cursor: # GOOD -- Using parameters cursor.execute("SELECT * FROM users WHERE username = %s", username) User.objects.raw("SELECT * FROM users WHERE username = %s", (username,)) # BAD -- Using string formatting - cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) + cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) # $ Alert # BAD -- other ways of executing raw SQL code with string interpolation - User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username)) - User.objects.raw("insert into names_file ('name') values ('%s')" % username) - User.objects.extra("insert into names_file ('name') values ('%s')" % username) + User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username)) # $ Alert + User.objects.raw("insert into names_file ('name') values ('%s')" % username) # $ Alert + User.objects.extra("insert into names_file ('name') values ('%s')" % username) # $ Alert # BAD (but currently no custom query to find this) # diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py index a54d64517d42..f35b1325366c 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py @@ -20,15 +20,15 @@ class User(Base): @app.route("/users/") -def show_user(username): +def show_user(username): # $ Source session = sqlalchemy.orm.Session(engine) # BAD, normal SQL injection - stmt = sqlalchemy.text("SELECT * FROM users WHERE username = '{}'".format(username)) + stmt = sqlalchemy.text("SELECT * FROM users WHERE username = '{}'".format(username)) # $ Alert results = session.execute(stmt).fetchall() # BAD, allows SQL injection - username_formatted_for_sql = sqlalchemy.text("'{}'".format(username)) + username_formatted_for_sql = sqlalchemy.text("'{}'".format(username)) # $ Alert stmt = sqlalchemy.select(User).where(User.username == username_formatted_for_sql) results = session.execute(stmt).scalars().all() @@ -38,14 +38,14 @@ def show_user(username): # All of these should be flagged by query - t1 = sqlalchemy.text(username) - t2 = sqlalchemy.text(text=username) - t3 = sqlalchemy.sql.text(username) - t4 = sqlalchemy.sql.text(text=username) - t5 = sqlalchemy.sql.expression.text(username) - t6 = sqlalchemy.sql.expression.text(text=username) - t7 = sqlalchemy.sql.expression.TextClause(username) - t8 = sqlalchemy.sql.expression.TextClause(text=username) - - t9 = db.text(username) - t10 = db.text(text=username) + t1 = sqlalchemy.text(username) # $ Alert + t2 = sqlalchemy.text(text=username) # $ Alert + t3 = sqlalchemy.sql.text(username) # $ Alert + t4 = sqlalchemy.sql.text(text=username) # $ Alert + t5 = sqlalchemy.sql.expression.text(username) # $ Alert + t6 = sqlalchemy.sql.expression.text(text=username) # $ Alert + t7 = sqlalchemy.sql.expression.TextClause(username) # $ Alert + t8 = sqlalchemy.sql.expression.TextClause(text=username) # $ Alert + + t9 = db.text(username) # $ Alert + t10 = db.text(text=username) # $ Alert diff --git a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.qlref b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.qlref index 19112f987ada..87db0e58f847 100644 --- a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.qlref @@ -1 +1,2 @@ -Security/CWE-090/LdapInjection.ql +query: Security/CWE-090/LdapInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap3_bad.py b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap3_bad.py index 2edb986fccfc..a69aef9ad3d8 100644 --- a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap3_bad.py +++ b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap3_bad.py @@ -1,4 +1,4 @@ -from flask import request, Flask +from flask import request, Flask # $ Source import ldap3 app = Flask(__name__) @@ -18,7 +18,7 @@ def normal(): srv = ldap3.Server('ldap://127.0.0.1') conn = ldap3.Connection(srv, user=dn, auto_bind=True) - conn.search(dn, search_filter) + conn.search(dn, search_filter) # $ Alert @app.route("/direct") @@ -35,7 +35,7 @@ def direct(): srv = ldap3.Server('ldap://127.0.0.1') conn = ldap3.Connection(srv, user=dn, auto_bind=True).search( - dn, search_filter) + dn, search_filter) # $ Alert # if __name__ == "__main__": # app.run(debug=True) diff --git a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap_bad.py b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap_bad.py index 133b0baaf9c0..8fd38f52f577 100644 --- a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap_bad.py +++ b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/ldap_bad.py @@ -1,4 +1,4 @@ -from flask import request, Flask +from flask import request, Flask # $ Source import ldap app = Flask(__name__) @@ -18,7 +18,7 @@ def normal(): ldap_connection = ldap.initialize("ldap://127.0.0.1") user = ldap_connection.search_s( - dn, ldap.SCOPE_SUBTREE, search_filter) + dn, ldap.SCOPE_SUBTREE, search_filter) # $ Alert @app.route("/direct") @@ -34,7 +34,7 @@ def direct(): search_filter = "(user={})".format(unsafe_filter) user = ldap.initialize("ldap://127.0.0.1").search_s( - dn, ldap.SCOPE_SUBTREE, search_filter) + dn, ldap.SCOPE_SUBTREE, search_filter) # $ Alert @app.route("/normal_argbyname") @@ -52,7 +52,7 @@ def normal_argbyname(): ldap_connection = ldap.initialize("ldap://127.0.0.1") user = ldap_connection.search_s( - dn, ldap.SCOPE_SUBTREE, filterstr=search_filter) + dn, ldap.SCOPE_SUBTREE, filterstr=search_filter) # $ Alert # if __name__ == "__main__": diff --git a/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests2-with-wsgi-validator/HeaderInjection.qlref b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests2-with-wsgi-validator/HeaderInjection.qlref index 7dbe28e4b591..4379f3d416b4 100644 --- a/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests2-with-wsgi-validator/HeaderInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests2-with-wsgi-validator/HeaderInjection.qlref @@ -1 +1,2 @@ -Security/CWE-113/HeaderInjection.ql \ No newline at end of file +query: Security/CWE-113/HeaderInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/BadTagFilter.qlref b/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/BadTagFilter.qlref index e5fc84fd48a9..443c007de0cb 100644 --- a/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/BadTagFilter.qlref +++ b/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/BadTagFilter.qlref @@ -1 +1,2 @@ -Security/CWE-116/BadTagFilter.ql +query: Security/CWE-116/BadTagFilter.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/tst.py b/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/tst.py index 2c3ec0667e39..04b81be29e6c 100644 --- a/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/tst.py +++ b/python/ql/test/query-tests/Security/CWE-116-BadTagFilter/tst.py @@ -1,28 +1,28 @@ import re filters = [ - re.compile(r""".*?<\/script>""", re.IGNORECASE), # NOT OK - doesn't match newlines or `` - re.compile(r""".*?<\/script>""", re.IGNORECASE | re.DOTALL), # NOT OK - doesn't match `` + re.compile(r""".*?<\/script>""", re.IGNORECASE), # $ Alert # NOT OK - doesn't match newlines or `` + re.compile(r""".*?<\/script>""", re.IGNORECASE | re.DOTALL), # $ Alert # NOT OK - doesn't match `` re.compile(r""".*?<\/script[^>]*>""", re.IGNORECASE | re.DOTALL), # OK re.compile(r"""""", re.IGNORECASE | re.DOTALL), # OK - we don't care regexps that only match comments re.compile(r""")|([^\/\s>]+)[\S\s]*?>"""), #// NOT OK - doesn't match comments with the right capture groups - re.compile(r"""<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"""), # NOT OK - capture groups - re.compile(r"""(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)""", re.IGNORECASE), # NOT OK - capture groups - re.compile(r"""<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"""), # NOT OK - capture groups + re.compile(r"""]*>([\s\S]*?)<\/script>""", re.IGNORECASE | re.DOTALL), # $ Alert # NOT OK - too strict matching on the end tag + re.compile(r"""<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>"""), # $ Alert #// NOT OK - doesn't match comments with the right capture groups + re.compile(r"""<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))"""), # $ Alert # NOT OK - capture groups + re.compile(r"""(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)""", re.IGNORECASE), # $ Alert # NOT OK - capture groups + re.compile(r"""<(?:(?:!--([\w\W]*?)-->)|(?:!\[CDATA\[([\w\W]*?)\]\]>)|(?:!DOCTYPE([\w\W]*?)>)|(?:\?([^\s\/<>]+) ?([\w\W]*?)[?/]>)|(?:\/([A-Za-z][A-Za-z0-9\-_\:\.]*)>)|(?:([A-Za-z][A-Za-z0-9\-_\:\.]*)((?:\s+[^"'>]+(?:(?:"[^"]*")|(?:'[^']*')|[^>]*))*|\/|\s+)>))"""), # $ Alert # NOT OK - capture groups ] doFilters(filters) diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected index fd9b5fe6bb65..67274311bf42 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.expected @@ -1,3 +1,8 @@ +#select +| LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | +| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | edges | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for request | provenance | | | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for request | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | provenance | | @@ -44,8 +49,3 @@ nodes | LogInjectionBad.py:35:12:35:35 | 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:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | -| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on a $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.qlref b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.qlref index 1837c628c33e..fc8a61c453d2 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjection.qlref @@ -1 +1,2 @@ -Security/CWE-117/LogInjection.ql +query: Security/CWE-117/LogInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjectionBad.py b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjectionBad.py index 0c0cbe1a8fee..e8b4837a4bd8 100644 --- a/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjectionBad.py +++ b/python/ql/test/query-tests/Security/CWE-117-LogInjection/LogInjectionBad.py @@ -4,7 +4,7 @@ @Desc シ哭og Injection """ from flask import Flask -from flask import request +from flask import request # $ Source from django.utils.log import request_logger import logging @@ -15,26 +15,26 @@ @app.route('/bad1') def bad1(): name = request.args.get('name') - app.logger.info('User name: ' + name) # Bad + app.logger.info('User name: ' + name) # $ Alert # Bad return 'bad1' @app.route('/bad2') def bad2(): name = request.args.get('name') - logging.info('User name: ' + name) # Bad + logging.info('User name: ' + name) # $ Alert # Bad return 'bad2' @app.route('/bad3') def bad3(): name = request.args.get('name') - request_logger.warn('User name: ' + name) # Bad + request_logger.warn('User name: ' + name) # $ Alert # Bad return 'bad3' @app.route('/bad4') def bad4(): name = request.args.get('name') logtest = logging.getLogger('test') - logtest.debug('User name: ' + name) # Bad + logtest.debug('User name: ' + name) # $ Alert # Bad return 'bad4' if __name__ == '__main__': diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.qlref b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.qlref index 18cf2d49a1aa..1dd7d31abad3 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.qlref +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.qlref @@ -1 +1 @@ -Security/CWE-209/StackTraceExposure.ql +query: Security/CWE-209/StackTraceExposure.ql diff --git a/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/FlaskDebug.qlref b/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/FlaskDebug.qlref index 0e21a3ac14fe..0fad5641329e 100644 --- a/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/FlaskDebug.qlref +++ b/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/FlaskDebug.qlref @@ -1 +1,2 @@ -Security/CWE-215/FlaskDebug.ql +query: Security/CWE-215/FlaskDebug.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/test.py b/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/test.py index c1d653aab937..b828784994a1 100644 --- a/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/test.py +++ b/python/ql/test/query-tests/Security/CWE-215-FlaskDebug/test.py @@ -7,8 +7,8 @@ def main(): raise Exception() # bad -app.run(debug=True) -app.run('host', 8080, True) +app.run(debug=True) # $ Alert +app.run('host', 8080, True) # $ Alert # okay app.run() @@ -23,11 +23,11 @@ def main(): DEBUG = True -app.run(debug=DEBUG) # NOT OK +app.run(debug=DEBUG) # $ Alert # NOT OK DEBUG = 1 -app.run(debug=DEBUG) # NOT OK +app.run(debug=DEBUG) # $ Alert # NOT OK if False: app.run(debug=True) @@ -35,12 +35,12 @@ def main(): runapp = app.run -runapp(debug=True) # NOT OK +runapp(debug=True) # $ Alert # NOT OK # imports from other module import settings -app.run(debug=settings.ALWAYS_TRUE) # NOT OK +app.run(debug=settings.ALWAYS_TRUE) # $ Alert # NOT OK # depending on environment values diff --git a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.qlref b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.qlref index 81915461d7ad..de31c362b6ca 100644 --- a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.qlref +++ b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/PamAuthorization.qlref @@ -1 +1,2 @@ -Security/CWE-285/PamAuthorization.ql +query: Security/CWE-285/PamAuthorization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/pam_test.py b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/pam_test.py index f16e3c9941ea..364b2a64f7da 100644 --- a/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/pam_test.py +++ b/python/ql/test/query-tests/Security/CWE-285-PamAuthorization/pam_test.py @@ -1,7 +1,7 @@ from ctypes import CDLL, POINTER, Structure, byref from ctypes import c_char_p, c_int from ctypes.util import find_library -from flask import Flask, request, redirect +from flask import Flask, request, redirect # $ Source class PamHandle(Structure): @@ -73,7 +73,7 @@ def bad(): conv = PamConv(None, 0) retval = pam_start(service, username, byref(conv), byref(handle)) - retval = pam_authenticate(handle, 0) + retval = pam_authenticate(handle, 0) # $ Alert # NOT OK: no call to `pam_acct_mgmt` auth_success = retval == 0 diff --git a/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/MissingHostKeyValidation.qlref b/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/MissingHostKeyValidation.qlref index c366095516af..5b75b5eea103 100644 --- a/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/MissingHostKeyValidation.qlref +++ b/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/MissingHostKeyValidation.qlref @@ -1 +1,2 @@ -Security/CWE-295/MissingHostKeyValidation.ql +query: Security/CWE-295/MissingHostKeyValidation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/paramiko_host_key.py b/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/paramiko_host_key.py index 3d0a59dcd8f9..d41d5e180982 100644 --- a/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/paramiko_host_key.py +++ b/python/ql/test/query-tests/Security/CWE-295-MissingHostKeyValidation/paramiko_host_key.py @@ -2,19 +2,19 @@ client = SSHClient() -client.set_missing_host_key_policy(AutoAddPolicy) # bad +client.set_missing_host_key_policy(AutoAddPolicy) # $ Alert # bad client.set_missing_host_key_policy(RejectPolicy) # good -client.set_missing_host_key_policy(WarningPolicy) # bad +client.set_missing_host_key_policy(WarningPolicy) # $ Alert # bad # Using instances -client.set_missing_host_key_policy(AutoAddPolicy()) # bad +client.set_missing_host_key_policy(AutoAddPolicy()) # $ Alert # bad client.set_missing_host_key_policy(RejectPolicy()) # good -client.set_missing_host_key_policy(WarningPolicy()) # bad +client.set_missing_host_key_policy(WarningPolicy()) # $ Alert # bad # different import import paramiko client = paramiko.SSHClient() -client.set_missing_host_key_policy(paramiko.AutoAddPolicy) # bad +client.set_missing_host_key_policy(paramiko.AutoAddPolicy) # $ Alert # bad diff --git a/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/RequestWithoutValidation.qlref b/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/RequestWithoutValidation.qlref index 7ad4d4d2ae34..cda6ce83c836 100644 --- a/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/RequestWithoutValidation.qlref +++ b/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/RequestWithoutValidation.qlref @@ -1 +1,2 @@ -Security/CWE-295/RequestWithoutValidation.ql +query: Security/CWE-295/RequestWithoutValidation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/make_request.py b/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/make_request.py index 29e857e07b1c..8c355cd206e6 100644 --- a/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/make_request.py +++ b/python/ql/test/query-tests/Security/CWE-295-RequestWithoutValidation/make_request.py @@ -2,14 +2,14 @@ #Simple cases requests.get('https://semmle.com', verify=True) # GOOD -requests.get('https://semmle.com', verify=False) # BAD +requests.get('https://semmle.com', verify=False) # $ Alert # BAD requests.post('https://semmle.com', verify=True) # GOOD -requests.post('https://semmle.com', verify=False) # BAD +requests.post('https://semmle.com', verify=False) # $ Alert # BAD # Simple flow put = requests.put put('https://semmle.com', verify="/path/to/cert/") # GOOD -put('https://semmle.com', verify=False) # BAD +put('https://semmle.com', verify=False) # $ Alert # BAD #Other flow delete = requests.delete @@ -25,17 +25,17 @@ def req1(verify=False): patch = requests.patch def req2(verify): - patch('https://semmle.com', verify=verify) # BAD (from line 30) + patch('https://semmle.com', verify=verify) # $ Alert # BAD (from line 30) req2(False) # BAD (at line 28) req2("/path/to/cert/") # GOOD #Falsey value -requests.post('https://semmle.com', verify=0) # BAD +requests.post('https://semmle.com', verify=0) # $ Alert # BAD # requests treat `None` as default value, which means it is turned on requests.get('https://semmle.com') # OK requests.get('https://semmle.com', verify=None) # OK s = requests.Session() -s.get("url", verify=False) # BAD +s.get("url", verify=False) # $ Alert # BAD diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 5da1b60eee12..47f27dbc5f27 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -1,3 +1,28 @@ +#select +| test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:22:58:22:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:23:58:23:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:27:40:27:47 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:30:58:30:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:45:11:45:11 | ControlFlowNode for x | test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | test.py:44:9:44:25 | ControlFlowNode for Attribute() | sensitive data (password) | +| test.py:49:15:49:36 | ControlFlowNode for social_security_number | test.py:48:14:48:35 | ControlFlowNode for social_security_number | test.py:49:15:49:36 | ControlFlowNode for social_security_number | This expression logs $@ as clear text. | test.py:48:14:48:35 | ControlFlowNode for social_security_number | sensitive data (private) | +| test.py:50:15:50:17 | ControlFlowNode for ssn | test.py:48:38:48:40 | ControlFlowNode for ssn | test.py:50:15:50:17 | ControlFlowNode for ssn | This expression logs $@ as clear text. | test.py:48:38:48:40 | ControlFlowNode for ssn | sensitive data (private) | +| test.py:52:15:52:24 | ControlFlowNode for passportNo | test.py:48:54:48:63 | ControlFlowNode for passportNo | test.py:52:15:52:24 | ControlFlowNode for passportNo | This expression logs $@ as clear text. | test.py:48:54:48:63 | ControlFlowNode for passportNo | sensitive data (private) | +| test.py:55:15:55:23 | ControlFlowNode for post_code | test.py:54:14:54:22 | ControlFlowNode for post_code | test.py:55:15:55:23 | ControlFlowNode for post_code | This expression logs $@ as clear text. | test.py:54:14:54:22 | ControlFlowNode for post_code | sensitive data (private) | +| test.py:56:15:56:21 | ControlFlowNode for zipCode | test.py:54:25:54:31 | ControlFlowNode for zipCode | test.py:56:15:56:21 | ControlFlowNode for zipCode | This expression logs $@ as clear text. | test.py:54:25:54:31 | ControlFlowNode for zipCode | sensitive data (private) | +| test.py:57:15:57:26 | ControlFlowNode for home_address | test.py:54:34:54:45 | ControlFlowNode for home_address | test.py:57:15:57:26 | ControlFlowNode for home_address | This expression logs $@ as clear text. | test.py:54:34:54:45 | ControlFlowNode for home_address | sensitive data (private) | +| test.py:60:15:60:27 | ControlFlowNode for user_latitude | test.py:59:14:59:26 | ControlFlowNode for user_latitude | test.py:60:15:60:27 | ControlFlowNode for user_latitude | This expression logs $@ as clear text. | test.py:59:14:59:26 | ControlFlowNode for user_latitude | sensitive data (private) | +| test.py:61:15:61:28 | ControlFlowNode for user_longitude | test.py:59:29:59:42 | ControlFlowNode for user_longitude | test.py:61:15:61:28 | ControlFlowNode for user_longitude | This expression logs $@ as clear text. | test.py:59:29:59:42 | ControlFlowNode for user_longitude | sensitive data (private) | +| test.py:64:15:64:27 | ControlFlowNode for mobile_number | test.py:63:14:63:26 | ControlFlowNode for mobile_number | test.py:64:15:64:27 | ControlFlowNode for mobile_number | This expression logs $@ as clear text. | test.py:63:14:63:26 | ControlFlowNode for mobile_number | sensitive data (private) | +| test.py:65:15:65:21 | ControlFlowNode for phoneNo | test.py:63:29:63:35 | ControlFlowNode for phoneNo | test.py:65:15:65:21 | ControlFlowNode for phoneNo | This expression logs $@ as clear text. | test.py:63:29:63:35 | ControlFlowNode for phoneNo | sensitive data (private) | +| test.py:68:15:68:24 | ControlFlowNode for creditcard | test.py:67:14:67:23 | ControlFlowNode for creditcard | test.py:68:15:68:24 | ControlFlowNode for creditcard | This expression logs $@ as clear text. | test.py:67:14:67:23 | ControlFlowNode for creditcard | sensitive data (private) | +| test.py:69:15:69:24 | ControlFlowNode for debit_card | test.py:67:26:67:35 | ControlFlowNode for debit_card | test.py:69:15:69:24 | ControlFlowNode for debit_card | This expression logs $@ as clear text. | test.py:67:26:67:35 | ControlFlowNode for debit_card | sensitive data (private) | +| test.py:70:15:70:25 | ControlFlowNode for bank_number | test.py:67:38:67:48 | ControlFlowNode for bank_number | test.py:70:15:70:25 | ControlFlowNode for bank_number | This expression logs $@ as clear text. | test.py:67:38:67:48 | ControlFlowNode for bank_number | sensitive data (private) | +| test.py:73:15:73:17 | ControlFlowNode for ccn | test.py:67:76:67:78 | ControlFlowNode for ccn | test.py:73:15:73:17 | ControlFlowNode for ccn | This expression logs $@ as clear text. | test.py:67:76:67:78 | ControlFlowNode for ccn | sensitive data (private) | +| test.py:74:15:74:22 | ControlFlowNode for user_ccn | test.py:67:81:67:88 | ControlFlowNode for user_ccn | test.py:74:15:74:22 | ControlFlowNode for user_ccn | This expression logs $@ as clear text. | test.py:67:81:67:88 | ControlFlowNode for user_ccn | sensitive data (private) | edges | test.py:19:5:19:12 | ControlFlowNode for password | test.py:20:48:20:55 | ControlFlowNode for password | provenance | | | test.py:19:5:19:12 | ControlFlowNode for password | test.py:22:58:22:65 | ControlFlowNode for password | provenance | | @@ -67,28 +92,3 @@ nodes | test.py:73:15:73:17 | ControlFlowNode for ccn | semmle.label | ControlFlowNode for ccn | | test.py:74:15:74:22 | ControlFlowNode for user_ccn | semmle.label | ControlFlowNode for user_ccn | subpaths -#select -| test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:22:58:22:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:23:58:23:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:27:40:27:47 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:30:58:30:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:45:11:45:11 | ControlFlowNode for x | test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | test.py:44:9:44:25 | ControlFlowNode for Attribute() | sensitive data (password) | -| test.py:49:15:49:36 | ControlFlowNode for social_security_number | test.py:48:14:48:35 | ControlFlowNode for social_security_number | test.py:49:15:49:36 | ControlFlowNode for social_security_number | This expression logs $@ as clear text. | test.py:48:14:48:35 | ControlFlowNode for social_security_number | sensitive data (private) | -| test.py:50:15:50:17 | ControlFlowNode for ssn | test.py:48:38:48:40 | ControlFlowNode for ssn | test.py:50:15:50:17 | ControlFlowNode for ssn | This expression logs $@ as clear text. | test.py:48:38:48:40 | ControlFlowNode for ssn | sensitive data (private) | -| test.py:52:15:52:24 | ControlFlowNode for passportNo | test.py:48:54:48:63 | ControlFlowNode for passportNo | test.py:52:15:52:24 | ControlFlowNode for passportNo | This expression logs $@ as clear text. | test.py:48:54:48:63 | ControlFlowNode for passportNo | sensitive data (private) | -| test.py:55:15:55:23 | ControlFlowNode for post_code | test.py:54:14:54:22 | ControlFlowNode for post_code | test.py:55:15:55:23 | ControlFlowNode for post_code | This expression logs $@ as clear text. | test.py:54:14:54:22 | ControlFlowNode for post_code | sensitive data (private) | -| test.py:56:15:56:21 | ControlFlowNode for zipCode | test.py:54:25:54:31 | ControlFlowNode for zipCode | test.py:56:15:56:21 | ControlFlowNode for zipCode | This expression logs $@ as clear text. | test.py:54:25:54:31 | ControlFlowNode for zipCode | sensitive data (private) | -| test.py:57:15:57:26 | ControlFlowNode for home_address | test.py:54:34:54:45 | ControlFlowNode for home_address | test.py:57:15:57:26 | ControlFlowNode for home_address | This expression logs $@ as clear text. | test.py:54:34:54:45 | ControlFlowNode for home_address | sensitive data (private) | -| test.py:60:15:60:27 | ControlFlowNode for user_latitude | test.py:59:14:59:26 | ControlFlowNode for user_latitude | test.py:60:15:60:27 | ControlFlowNode for user_latitude | This expression logs $@ as clear text. | test.py:59:14:59:26 | ControlFlowNode for user_latitude | sensitive data (private) | -| test.py:61:15:61:28 | ControlFlowNode for user_longitude | test.py:59:29:59:42 | ControlFlowNode for user_longitude | test.py:61:15:61:28 | ControlFlowNode for user_longitude | This expression logs $@ as clear text. | test.py:59:29:59:42 | ControlFlowNode for user_longitude | sensitive data (private) | -| test.py:64:15:64:27 | ControlFlowNode for mobile_number | test.py:63:14:63:26 | ControlFlowNode for mobile_number | test.py:64:15:64:27 | ControlFlowNode for mobile_number | This expression logs $@ as clear text. | test.py:63:14:63:26 | ControlFlowNode for mobile_number | sensitive data (private) | -| test.py:65:15:65:21 | ControlFlowNode for phoneNo | test.py:63:29:63:35 | ControlFlowNode for phoneNo | test.py:65:15:65:21 | ControlFlowNode for phoneNo | This expression logs $@ as clear text. | test.py:63:29:63:35 | ControlFlowNode for phoneNo | sensitive data (private) | -| test.py:68:15:68:24 | ControlFlowNode for creditcard | test.py:67:14:67:23 | ControlFlowNode for creditcard | test.py:68:15:68:24 | ControlFlowNode for creditcard | This expression logs $@ as clear text. | test.py:67:14:67:23 | ControlFlowNode for creditcard | sensitive data (private) | -| test.py:69:15:69:24 | ControlFlowNode for debit_card | test.py:67:26:67:35 | ControlFlowNode for debit_card | test.py:69:15:69:24 | ControlFlowNode for debit_card | This expression logs $@ as clear text. | test.py:67:26:67:35 | ControlFlowNode for debit_card | sensitive data (private) | -| test.py:70:15:70:25 | ControlFlowNode for bank_number | test.py:67:38:67:48 | ControlFlowNode for bank_number | test.py:70:15:70:25 | ControlFlowNode for bank_number | This expression logs $@ as clear text. | test.py:67:38:67:48 | ControlFlowNode for bank_number | sensitive data (private) | -| test.py:73:15:73:17 | ControlFlowNode for ccn | test.py:67:76:67:78 | ControlFlowNode for ccn | test.py:73:15:73:17 | ControlFlowNode for ccn | This expression logs $@ as clear text. | test.py:67:76:67:78 | ControlFlowNode for ccn | sensitive data (private) | -| test.py:74:15:74:22 | ControlFlowNode for user_ccn | test.py:67:81:67:88 | ControlFlowNode for user_ccn | test.py:74:15:74:22 | ControlFlowNode for user_ccn | This expression logs $@ as clear text. | test.py:67:81:67:88 | ControlFlowNode for user_ccn | sensitive data (private) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.qlref b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.qlref index de9273391c84..2309f8c643a1 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.qlref +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.qlref @@ -1 +1,2 @@ -Security/CWE-312/CleartextLogging.ql \ No newline at end of file +query: Security/CWE-312/CleartextLogging.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py index ff01680ed81c..4bb8be6fa93e 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py @@ -16,62 +16,62 @@ def get_cert(): def log_password(): - password = get_password() - logging.info("logging.info Password '%s'", password) # NOT OK + password = get_password() # $ Source + logging.info("logging.info Password '%s'", password) # $ Alert # NOT OK - LOGGER.log(logging.INFO, "LOGGER.log Password '%s'", password) # NOT OK - logging.root.info("logging.root.info Password '%s'", password) # NOT OK + LOGGER.log(logging.INFO, "LOGGER.log Password '%s'", password) # $ Alert # NOT OK + logging.root.info("logging.root.info Password '%s'", password) # $ Alert # NOT OK # name of logger variable should not matter foo = LOGGER - foo.info("foo.info Password '%s'", password) # NOT OK + foo.info("foo.info Password '%s'", password) # $ Alert # NOT OK # return value from function - get_logger().info("get_logger().info Password '%s'", password) # NOT OK + get_logger().info("get_logger().info Password '%s'", password) # $ Alert # NOT OK def log_cert(): logging.debug("Cert=%s", get_cert()) # OK def print_password(): - print(get_password()) # NOT OK + print(get_password()) # $ Alert # NOT OK - sys.stdout.write(get_password()) # NOT OK - sys.stderr.write(get_password()) # NOT OK + sys.stdout.write(get_password()) # $ Alert # NOT OK + sys.stderr.write(get_password()) # $ Alert # NOT OK import getpass - x = getpass.getpass() - print(x) # NOT OK + x = getpass.getpass() # $ Source + print(x) # $ Alert # NOT OK def log_private(): - def log1(social_security_number, ssn, className, passportNo): - print(social_security_number) # NOT OK - print(ssn) # NOT OK + def log1(social_security_number, ssn, className, passportNo): # $ Source + print(social_security_number) # $ Alert # NOT OK + print(ssn) # $ Alert # NOT OK print(className) # OK - print(passportNo) # NOT OK + print(passportNo) # $ Alert # NOT OK - def log2(post_code, zipCode, home_address): - print(post_code) # NOT OK - print(zipCode) # NOT OK - print(home_address) # NOT OK + def log2(post_code, zipCode, home_address): # $ Source + print(post_code) # $ Alert # NOT OK + print(zipCode) # $ Alert # NOT OK + print(home_address) # $ Alert # NOT OK - def log3(user_latitude, user_longitude): - print(user_latitude) # NOT OK - print(user_longitude) # NOT OK + def log3(user_latitude, user_longitude): # $ Source + print(user_latitude) # $ Alert # NOT OK + print(user_longitude) # $ Alert # NOT OK - def log4(mobile_number, phoneNo): - print(mobile_number) # NOT OK - print(phoneNo) # NOT OK + def log4(mobile_number, phoneNo): # $ Source + print(mobile_number) # $ Alert # NOT OK + print(phoneNo) # $ Alert # NOT OK - def log5(creditcard, debit_card, bank_number, bank_account, accountNo, ccn, user_ccn, succNode): - print(creditcard) # NOT OK - print(debit_card) # NOT OK - print(bank_number) # NOT OK + def log5(creditcard, debit_card, bank_number, bank_account, accountNo, ccn, user_ccn, succNode): # $ Source + print(creditcard) # $ Alert # NOT OK + print(debit_card) # $ Alert # NOT OK + print(bank_number) # $ Alert # NOT OK print(bank_account) # NOT OK, but NOT FOUND - "account" is treated as having the "id" classification and thus excluded. print(accountNo) # NOT OK, but NOT FOUND - "account" is treated as having the "id" classification and thus excluded. - print(ccn) # NOT OK - print(user_ccn) # NOT OK + print(ccn) # $ Alert # NOT OK + print(user_ccn) # $ Alert # NOT OK print(succNode) # OK diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected index 588cfae32ef5..66c192b89e03 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected @@ -1,3 +1,7 @@ +#select +| test.py:12:21:12:28 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:12:21:12:28 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:13:22:13:45 | ControlFlowNode for Attribute() | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:13:22:13:45 | ControlFlowNode for Attribute() | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:15:26:15:33 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:15:26:15:33 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | edges | test.py:9:5:9:12 | ControlFlowNode for password | test.py:12:21:12:28 | ControlFlowNode for password | provenance | | | test.py:9:5:9:12 | ControlFlowNode for password | test.py:13:22:13:45 | ControlFlowNode for Attribute() | provenance | | @@ -10,7 +14,3 @@ nodes | test.py:13:22:13:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:15:26:15:33 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | subpaths -#select -| test.py:12:21:12:28 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:12:21:12:28 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:13:22:13:45 | ControlFlowNode for Attribute() | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:13:22:13:45 | ControlFlowNode for Attribute() | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:15:26:15:33 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:15:26:15:33 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.qlref b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.qlref index a32206e8d6a4..a39c1b1c4efd 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.qlref +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.qlref @@ -1 +1,2 @@ -Security/CWE-312/CleartextStorage.ql \ No newline at end of file +query: Security/CWE-312/CleartextStorage.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py index 91b7fb7e6c26..a433f7dc85c2 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py @@ -6,10 +6,10 @@ def get_password(): def write_password(filename): - password = get_password() + password = get_password() # $ Source path = pathlib.Path(filename) - path.write_text(password) # NOT OK - path.write_bytes(password.encode("utf-8")) # NOT OK + path.write_text(password) # $ Alert # NOT OK + path.write_bytes(password.encode("utf-8")) # $ Alert # NOT OK - path.open("w").write(password) # NOT OK + path.open("w").write(password) # $ Alert # NOT OK diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected index ea41c1ba6516..ed748c70df3e 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected @@ -1,3 +1,8 @@ +#select +| password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | sensitive data (password) | +| password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | sensitive data (password) | +| test.py:17:20:17:27 | ControlFlowNode for password | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:17:20:17:27 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:19:25:19:29 | ControlFlowNode for lines | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:19:25:19:29 | ControlFlowNode for lines | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | edges | password_in_cookie.py:7:5:7:12 | ControlFlowNode for password | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | provenance | | | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:7:5:7:12 | ControlFlowNode for password | provenance | | @@ -24,8 +29,3 @@ nodes | test.py:18:18:18:32 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | test.py:19:25:19:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | subpaths -#select -| password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | sensitive data (password) | -| password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | sensitive data (password) | -| test.py:17:20:17:27 | ControlFlowNode for password | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:17:20:17:27 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:19:25:19:29 | ControlFlowNode for lines | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:19:25:19:29 | ControlFlowNode for lines | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.qlref b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.qlref index a32206e8d6a4..a39c1b1c4efd 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.qlref +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.qlref @@ -1 +1,2 @@ -Security/CWE-312/CleartextStorage.ql \ No newline at end of file +query: Security/CWE-312/CleartextStorage.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/password_in_cookie.py b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/password_in_cookie.py index 2688c13dace3..c85405f38609 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/password_in_cookie.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/password_in_cookie.py @@ -4,14 +4,14 @@ @app.route('/') def index(): - password = request.args.get("password") + password = request.args.get("password") # $ Source resp = make_response(render_template(...)) - resp.set_cookie("password", password) # NOT OK + resp.set_cookie("password", password) # $ Alert # NOT OK return resp @app.route('/') def index2(): - password = request.args.get("password") + password = request.args.get("password") # $ Source resp = Response(...) - resp.set_cookie("password", password) # NOT OK + resp.set_cookie("password", password) # $ Alert # NOT OK return resp diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py index 6d04aa4b1702..58613efd4b29 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py @@ -12,11 +12,11 @@ def write_cert(filename): file.writelines(lines) # OK def write_password(filename): - password = get_password() + password = get_password() # $ Source with open(filename, "w") as file: - file.write(password) # NOT OK + file.write(password) # $ Alert # NOT OK lines = [password + "\n"] - file.writelines(lines) # NOT OK + file.writelines(lines) # $ Alert # NOT OK def FPs(): # just like for cleartext-logging see that file for more elaborate tests diff --git a/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/WeakCryptoKey.qlref b/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/WeakCryptoKey.qlref index 70a66eef06ef..3ee942673d37 100644 --- a/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/WeakCryptoKey.qlref +++ b/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/WeakCryptoKey.qlref @@ -1 +1,2 @@ -Security/CWE-326/WeakCryptoKey.ql +query: Security/CWE-326/WeakCryptoKey.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/weak_crypto.py b/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/weak_crypto.py index 5ec929c7d094..87ed42d12bf6 100644 --- a/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/weak_crypto.py +++ b/python/ql/test/query-tests/Security/CWE-326-WeakCryptoKey/weak_crypto.py @@ -65,23 +65,23 @@ # Weak keys -dsa_gen_key(DSA_WEAK) -ec_gen_key(EC_WEAK) -rsa_gen_key(65537, RSA_WEAK) +dsa_gen_key(DSA_WEAK) # $ Alert +ec_gen_key(EC_WEAK) # $ Alert +rsa_gen_key(65537, RSA_WEAK) # $ Alert -dsa_gen_key(key_size=DSA_WEAK) -ec_gen_key(curve=EC_WEAK) -rsa_gen_key(65537, key_size=RSA_WEAK) +dsa_gen_key(key_size=DSA_WEAK) # $ Alert +ec_gen_key(curve=EC_WEAK) # $ Alert +rsa_gen_key(65537, key_size=RSA_WEAK) # $ Alert -DSA.generate(DSA_WEAK) -RSA.generate(RSA_WEAK) +DSA.generate(DSA_WEAK) # $ Alert +RSA.generate(RSA_WEAK) # $ Alert # ------------------------------------------------------------------------------ # Through function calls def make_new_rsa_key_weak(bits): - return RSA.generate(bits) # NOT OK + return RSA.generate(bits) # $ Alert # NOT OK make_new_rsa_key_weak(RSA_WEAK) diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.qlref b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.qlref index 3f7aff53700d..81a5bd0ae94e 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.qlref +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.qlref @@ -1 +1,2 @@ -Security/CWE-327/BrokenCryptoAlgorithm.ql +query: Security/CWE-327/BrokenCryptoAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py index 16482054eb23..6735f21ccd67 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptodome.py @@ -8,11 +8,11 @@ secret_message = b"secret message" cipher = ARC4.new(key) -encrypted = cipher.encrypt(secret_message) # NOT OK +encrypted = cipher.encrypt(secret_message) # $ Alert # NOT OK print(secret_message, encrypted) cipher = AES.new(key, AES.MODE_ECB) -encrypted = cipher.encrypt(secret_message) # NOT OK +encrypted = cipher.encrypt(secret_message) # $ Alert # NOT OK print(secret_message, encrypted) diff --git a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py index 4c7317cdba40..076a9b4f870a 100644 --- a/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py +++ b/python/ql/test/query-tests/Security/CWE-327-BrokenCryptoAlgorithm/test_cryptography.py @@ -10,7 +10,7 @@ secret_message = b"secret message" encryptor = cipher.encryptor() -encrypted = encryptor.update(secret_message) # NOT OK +encrypted = encryptor.update(secret_message) # $ Alert # NOT OK encrypted += encryptor.finalize() print(secret_message, encrypted) @@ -19,7 +19,7 @@ cipher = Cipher(algorithm, mode=modes.ECB()) encryptor = cipher.encryptor() -encrypted = encryptor.update(secret_message + b'\x80\x00') # NOT OK +encrypted = encryptor.update(secret_message + b'\x80\x00') # $ Alert # NOT OK encrypted += encryptor.finalize() print(secret_message, encrypted) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureDefaultProtocol.qlref b/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureDefaultProtocol.qlref index 13599b14931c..64b934bc3855 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureDefaultProtocol.qlref +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureDefaultProtocol.qlref @@ -1 +1,2 @@ -Security/CWE-327/InsecureDefaultProtocol.ql +query: Security/CWE-327/InsecureDefaultProtocol.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureProtocol.py b/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureProtocol.py index 1ea2a51a44e7..a99bfe3005a5 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureProtocol.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureDefaultProtocol/InsecureProtocol.py @@ -4,4 +4,4 @@ ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1_2) # possibly insecure default -ssl.wrap_socket() +ssl.wrap_socket() # $ Alert diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.py index ab80ed47dacd..80af8bbad378 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.py @@ -3,25 +3,25 @@ from ssl import SSLContext # insecure versions specified -ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2) -ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3) -ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1) +ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2) # $ Alert +ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3) # $ Alert +ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1) # $ Alert -SSLContext(protocol=ssl.PROTOCOL_SSLv2) -SSLContext(protocol=ssl.PROTOCOL_SSLv3) -SSLContext(protocol=ssl.PROTOCOL_TLSv1) +SSLContext(protocol=ssl.PROTOCOL_SSLv2) # $ Alert +SSLContext(protocol=ssl.PROTOCOL_SSLv3) # $ Alert +SSLContext(protocol=ssl.PROTOCOL_TLSv1) # $ Alert -SSL.Context(SSL.SSLv2_METHOD) -SSL.Context(SSL.SSLv3_METHOD) -SSL.Context(SSL.TLSv1_METHOD) +SSL.Context(SSL.SSLv2_METHOD) # $ Alert +SSL.Context(SSL.SSLv3_METHOD) # $ Alert +SSL.Context(SSL.TLSv1_METHOD) # $ Alert METHOD = SSL.SSLv2_METHOD -SSL.Context(METHOD) +SSL.Context(METHOD) # $ Alert # importing the protocol constant directly from ssl import PROTOCOL_SSLv2 -ssl.wrap_socket(ssl_version=PROTOCOL_SSLv2) -SSLContext(protocol=PROTOCOL_SSLv2) +ssl.wrap_socket(ssl_version=PROTOCOL_SSLv2) # $ Alert +SSLContext(protocol=PROTOCOL_SSLv2) # $ Alert # secure versions specified ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1_2) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.qlref b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.qlref index c06a937ff57d..75ce269cc68b 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.qlref +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.qlref @@ -1 +1,2 @@ -Security/CWE-327/InsecureProtocol.ql +query: Security/CWE-327/InsecureProtocol.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py index aab459ceeead..5a2f4614afaf 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py @@ -22,9 +22,9 @@ print(ssock.version()) with socket.create_connection((hostname, 443)) as sock: - with copy_completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + with copy_completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) with socket.create_connection((hostname, 443)) as sock: - with copy_also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + with copy_also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py index 3c12fd813558..390acf747ab1 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py @@ -10,9 +10,9 @@ print(ssock.version()) with socket.create_connection((hostname, 443)) as sock: - with completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + with completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) with socket.create_connection((hostname, 443)) as sock: - with also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + with also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/pyOpenSSL_fluent.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/pyOpenSSL_fluent.py index fa7714118828..729e968e5c10 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/pyOpenSSL_fluent.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/pyOpenSSL_fluent.py @@ -5,7 +5,7 @@ def test_fluent(): hostname = 'www.python.org' context = SSL.Context(SSL.SSLv23_METHOD) - conn = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + conn = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) # $ Alert r = conn.connect((hostname, 443)) print(conn.get_protocol_version_name()) @@ -15,7 +15,7 @@ def test_fluent_no_TLSv1(): context = SSL.Context(SSL.SSLv23_METHOD) context.set_options(SSL.OP_NO_TLSv1) - conn = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + conn = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) # $ Alert r = conn.connect((hostname, 443)) print(conn.get_protocol_version_name()) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/ssl_fluent.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/ssl_fluent.py index a8e491a42f1e..e4d71de56955 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/ssl_fluent.py +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/ssl_fluent.py @@ -6,7 +6,7 @@ def test_fluent_tls(): context = ssl.SSLContext(ssl.PROTOCOL_TLS) with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) @@ -16,7 +16,7 @@ def test_fluent_tls_no_TLSv1(): context.options |= ssl.OP_NO_TLSv1 with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_fluent_tls_client_no_TLSv1(): @@ -25,7 +25,7 @@ def test_fluent_tls_client_no_TLSv1(): context.options |= ssl.OP_NO_TLSv1 with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_fluent_tls_server_no_TLSv1(): @@ -34,7 +34,7 @@ def test_fluent_tls_server_no_TLSv1(): context.options |= ssl.OP_NO_TLSv1 with socket.create_server((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_fluent_tls_safe(): @@ -54,7 +54,7 @@ def test_fluent_ssl(): context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) @@ -68,13 +68,13 @@ def create_secure_context(): def create_connection(context): with socket.create_connection(('www.python.org', 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_delegated_context_unsafe(): context = create_relaxed_context() with socket.create_connection(('www.python.org', 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_delegated_context_safe(): @@ -94,7 +94,7 @@ def test_delegated_context_made_unsafe(): context = create_secure_context() context.options &= ~ssl.OP_NO_TLSv1_1 with socket.create_connection(('www.python.org', 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_delegated_connection_unsafe(): @@ -143,7 +143,7 @@ def test_fluent_ssl_unsafe_version(): context.minimum_version = ssl.TLSVersion.TLSv1_1 with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) def test_fluent_ssl_safe_version(): @@ -162,5 +162,5 @@ def test_fluent_explicitly_unsafe(): context.options &= ~ssl.OP_NO_SSLv3 with socket.create_connection((hostname, 443)) as sock: - with context.wrap_socket(sock, server_hostname=hostname) as ssock: + with context.wrap_socket(sock, server_hostname=hostname) as ssock: # $ Alert print(ssock.version()) diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected index 1027fbf4963c..ae081dd1aa05 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected @@ -1,3 +1,16 @@ +#select +| test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | Sensitive data (certificate) | +| test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:13:17:13:30 | ControlFlowNode for get_password() | Sensitive data (password) | +| test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | Sensitive data (password) | +| test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous | test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptography.py:7:17:7:33 | ControlFlowNode for get_certificate() | Sensitive data (certificate) | +| test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | Sensitive data (password) | +| test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | Sensitive data (password) | +| test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | Sensitive data (password) | edges | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:2:23:2:34 | ControlFlowNode for get_password | provenance | | | test_cryptodome.py:2:23:2:34 | ControlFlowNode for get_password | test_cryptodome.py:13:17:13:28 | ControlFlowNode for get_password | provenance | | @@ -61,16 +74,3 @@ nodes | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | semmle.label | ControlFlowNode for dangerous | subpaths -#select -| test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | Sensitive data (certificate) | -| test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:15:19:15:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:13:17:13:30 | ControlFlowNode for get_password() | Sensitive data (password) | -| test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | test_cryptodome.py:24:19:24:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:2:23:2:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptodome.py:20:17:20:30 | ControlFlowNode for get_password() | Sensitive data (password) | -| test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous | test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | test_cryptography.py:9:19:9:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptography.py:3:37:3:51 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptography.py:7:17:7:33 | ControlFlowNode for get_certificate() | Sensitive data (certificate) | -| test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | Sensitive data (password) | -| test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | test_cryptography.py:17:19:17:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:15:17:15:30 | ControlFlowNode for get_password() | Sensitive data (password) | -| test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:3:23:3:34 | ControlFlowNode for ImportMember | Sensitive data (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 | $@ is used in a hashing algorithm (SHA256) that is insecure for password hashing, since it is not a computationally expensive hash function. | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | Sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.qlref b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.qlref index 6c8eeda7222b..495cb9c979c3 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.qlref +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.qlref @@ -1 +1,2 @@ -Security/CWE-327/WeakSensitiveDataHashing.ql +query: Security/CWE-327/WeakSensitiveDataHashing.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptodome.py b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptodome.py index 3e196196ef9b..2a8fa6522ba9 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptodome.py +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptodome.py @@ -1,25 +1,25 @@ from Cryptodome.Hash import MD5, SHA256 -from my_module import get_password, get_certificate +from my_module import get_password, get_certificate # $ Source def get_badly_hashed_certificate(): - dangerous = get_certificate() + dangerous = get_certificate() # $ Source hasher = MD5.new() - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK return hasher.hexdigest() def get_badly_hashed_password(): - dangerous = get_password() + dangerous = get_password() # $ Source hasher = MD5.new() - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK return hasher.hexdigest() def get_badly_hashed_password2(): - dangerous = get_password() + dangerous = get_password() # $ Source # Although SHA-256 is a strong cryptographic hash functions, # it is not suitable for password hashing. hasher = SHA256.new() - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK return hasher.hexdigest() diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptography.py b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptography.py index 1090fda959c8..09e58768e9f7 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptography.py +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/test_cryptography.py @@ -1,29 +1,29 @@ from cryptography.hazmat.primitives import hashes from binascii import hexlify -from my_module import get_password, get_certificate +from my_module import get_password, get_certificate # $ Source def get_badly_hashed_certificate(): - dangerous = get_certificate() + dangerous = get_certificate() # $ Source hasher = hashes.Hash(hashes.MD5()) - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK digest = hasher.finalize() return hexlify(digest).decode("utf-8") def get_badly_hashed_password(): - dangerous = get_password() + dangerous = get_password() # $ Source hasher = hashes.Hash(hashes.MD5()) - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK digest = hasher.finalize() return hexlify(digest).decode("utf-8") def get_badly_hashed_password2(): - dangerous = get_password() + dangerous = get_password() # $ Source # Although SHA-256 is a strong cryptographic hash functions, # it is not suitable for password hashing. hasher = hashes.Hash(hashes.SHA256()) - hasher.update(dangerous) # NOT OK + hasher.update(dangerous) # $ Alert # NOT OK digest = hasher.finalize() return hexlify(digest).decode("utf-8") diff --git a/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.py b/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.py index 3c68affed8c4..5b7e820706e5 100644 --- a/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.py +++ b/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.py @@ -2,19 +2,19 @@ import os def write_results1(results): - filename = mktemp() + filename = mktemp() # $ Alert with open(filename, "w+") as f: f.write(results) print("Results written to", filename) def write_results2(results): - filename = os.tempnam() + filename = os.tempnam() # $ Alert with open(filename, "w+") as f: f.write(results) print("Results written to", filename) def write_results3(results): - filename = os.tmpnam() + filename = os.tmpnam() # $ Alert with open(filename, "w+") as f: f.write(results) print("Results written to", filename) diff --git a/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.qlref b/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.qlref index 68a27dfb2690..c64f78a01039 100644 --- a/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.qlref +++ b/python/ql/test/query-tests/Security/CWE-377-InsecureTemporaryFile/InsecureTemporaryFile.qlref @@ -1 +1,2 @@ -Security/CWE-377/InsecureTemporaryFile.ql +query: Security/CWE-377/InsecureTemporaryFile.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected index bab1e34c912b..309ef858d3b4 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected @@ -1,3 +1,9 @@ +#select +| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | +| unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | edges | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for request | provenance | | | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for request | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | provenance | | @@ -22,9 +28,3 @@ nodes | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | | unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | subpaths -#select -| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | -| unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | unsafe_deserialization.py:24:24:24:30 | ControlFlowNode for payload | Unsafe deserialization depends on a $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.qlref b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.qlref index fa9c0ceb3cb8..2eba44efb96b 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.qlref +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.qlref @@ -1 +1,2 @@ -Security/CWE-502/UnsafeDeserialization.ql +query: Security/CWE-502/UnsafeDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/unsafe_deserialization.py b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/unsafe_deserialization.py index d9189a92f41c..81a73c23f5ff 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/unsafe_deserialization.py +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/unsafe_deserialization.py @@ -5,20 +5,20 @@ from yaml import SafeLoader -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @app.route("/") def hello(): payload = request.args.get("payload") - pickle.loads(payload) # NOT OK - yaml.load(payload) # NOT OK + pickle.loads(payload) # $ Alert # NOT OK + yaml.load(payload) # $ Alert # NOT OK yaml.load(payload, Loader=SafeLoader) # OK - marshal.loads(payload) # NOT OK + marshal.loads(payload) # $ Alert # NOT OK import dill - dill.loads(payload) # NOT OK + dill.loads(payload) # $ Alert # NOT OK import pandas - pandas.read_pickle(payload) # NOT OK \ No newline at end of file + pandas.read_pickle(payload) # $ Alert # NOT OK diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected index 551299a64dc4..3e43c112e2a3 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected @@ -1,3 +1,16 @@ +#select +| test.py:8:21:8:26 | ControlFlowNode for target | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:93:18:93:26 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:93:18:93:26 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:114:25:114:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:114:25:114:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:140:25:140:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:140:25:140:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:148:25:148:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:148:25:148:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | edges | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:1:26:1:32 | ControlFlowNode for request | provenance | | | test.py:1:26:1:32 | ControlFlowNode for request | test.py:7:14:7:20 | ControlFlowNode for request | provenance | | @@ -138,16 +151,3 @@ nodes | test.py:145:17:145:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:148:25:148:33 | ControlFlowNode for untrusted | semmle.label | ControlFlowNode for untrusted | subpaths -#select -| test.py:8:21:8:26 | ControlFlowNode for target | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:93:18:93:26 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:93:18:93:26 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:114:25:114:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:114:25:114:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:140:25:140:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:140:25:140:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:148:25:148:33 | ControlFlowNode for untrusted | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:148:25:148:33 | ControlFlowNode for untrusted | Untrusted URL redirection depends on a $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.qlref b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.qlref index 8b63d80f0db2..863d71f68b18 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.qlref +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.qlref @@ -1,2 +1,2 @@ -Security/CWE-601/UrlRedirect.ql - +query: Security/CWE-601/UrlRedirect.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/test.py b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/test.py index 538e4d3910ba..dd374618a9db 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/test.py +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/test.py @@ -1,11 +1,11 @@ -from flask import Flask, request, redirect +from flask import Flask, request, redirect # $ Source app = Flask(__name__) @app.route('/') def hello(): target = request.args.get('target', '') - return redirect(target, code=302) + return redirect(target, code=302) # $ Alert # Check for safe prefixes @@ -29,21 +29,21 @@ def ok2(): def ok3(): untrusted = request.args.get('target', '') safe = "https://safe.com/{}".format(untrusted) - return redirect(safe, code=302) # FP + return redirect(safe, code=302) # $ SPURIOUS: Alert # FP @app.route('/ok4') def ok4(): untrusted = request.args.get('target', '') safe = f"https://safe.com/{untrusted}" - return redirect(safe, code=302) # FP + return redirect(safe, code=302) # $ SPURIOUS: Alert # FP @app.route('/ok5') def ok5(): untrusted = request.args.get('target', '') safe = "https://safe.com/%s" % untrusted - return redirect(safe, code=302) # FP + return redirect(safe, code=302) # $ SPURIOUS: Alert # FP @app.route('/const-str-compare') @@ -59,41 +59,41 @@ def const_str_compare(): def not_ok1(): untrusted = request.args.get('target', '') unsafe = untrusted + "?login=success" - return redirect(unsafe, code=302) + return redirect(unsafe, code=302) # $ Alert @app.route('/not_ok2') def not_ok2(): untrusted = request.args.get('target', '') unsafe = "{}?login=success".format(untrusted) - return redirect(unsafe, code=302) + return redirect(unsafe, code=302) # $ Alert @app.route('/not_ok3') def not_ok3(): untrusted = request.args.get('target', '') unsafe = f"{untrusted}?login=success" - return redirect(unsafe, code=302) + return redirect(unsafe, code=302) # $ Alert @app.route('/not_ok4') def not_ok4(): untrusted = request.args.get('target', '') unsafe = "%s?login=success" % untrusted - return redirect(unsafe, code=302) + return redirect(unsafe, code=302) # $ Alert from django.utils.http import url_has_allowed_host_and_scheme -import math +import math @app.route('/ok6') def ok6(): untrusted = request.args.get('target', '') - # random chance. + # random chance. if math.random() > 0.5: - redirect(untrusted, code=302) # NOT OK + redirect(untrusted, code=302) # $ Alert # NOT OK if url_has_allowed_host_and_scheme(untrusted, allowed_hosts=None): return redirect(untrusted, code=302) # OK - + return redirect("https://example.com", code=302) # OK import yarl @@ -111,7 +111,7 @@ def not_ok5(): untrusted = request.args.get('target', '') # no backslash replace if not yarl.URL(untrusted).is_absolute(): - return redirect(untrusted, code=302) # NOT OK + return redirect(untrusted, code=302) # $ Alert # NOT OK return redirect("/", code=302) from urllib.parse import urlparse @@ -137,7 +137,7 @@ def not_ok6(): untrusted = request.args.get('target', '') # no backslash replace if not urlparse(untrusted).netloc: - return redirect(untrusted, code=302) # NOT OK + return redirect(untrusted, code=302) # $ Alert # NOT OK return redirect("/", code=302) @app.route('/not_ok7') @@ -145,7 +145,7 @@ def not_ok7(): untrusted = request.args.get('target', '') # wrong check if urlparse(untrusted).netloc != "": - return redirect(untrusted, code=302) # NOT OK + return redirect(untrusted, code=302) # $ Alert # NOT OK return redirect("/", code=302) @app.route('/ok10') diff --git a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.qlref b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.qlref index 62a3f7f22d97..9473e8620152 100644 --- a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.qlref +++ b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.qlref @@ -1 +1,2 @@ -Security/CWE-611/Xxe.ql +query: Security/CWE-611/Xxe.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-611-Xxe/test.py b/python/ql/test/query-tests/Security/CWE-611-Xxe/test.py index 104f2663d59e..e84a05a76632 100644 --- a/python/ql/test/query-tests/Security/CWE-611-Xxe/test.py +++ b/python/ql/test/query-tests/Security/CWE-611-Xxe/test.py @@ -1,4 +1,4 @@ -from flask import Flask, request +from flask import Flask, request # $ Source import lxml.etree import markupsafe @@ -7,7 +7,7 @@ @app.route("/vuln-handler") def vuln_handler(): xml_content = request.args['xml_content'] - return lxml.etree.fromstring(xml_content).text + return lxml.etree.fromstring(xml_content).text # $ Alert @app.route("/safe-handler") def safe_handler(): @@ -28,7 +28,7 @@ def super_vuln_handler(): # allows DoS attacks huge_tree=True, ) - return lxml.etree.fromstring(xml_content, parser=parser).text + return lxml.etree.fromstring(xml_content, parser=parser).text # $ Alert @app.route("/sanitized-handler") def sanitized_handler(): diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.qlref b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.qlref index a61523e1767a..20ce4fdfd933 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.qlref +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/XpathInjection.qlref @@ -1 +1,2 @@ -Security/CWE-643/XpathInjection.ql +query: Security/CWE-643/XpathInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathBad.py b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathBad.py index ee836dd385eb..26a2f8d0d9a1 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathBad.py +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathBad.py @@ -6,11 +6,11 @@ from django.template import Template, Context, Engine, engines -def a(request): +def a(request): # $ Source value = request.GET['xpath'] f = StringIO('') tree = etree.parse(f) - r = tree.xpath("/tag[@id='%s']" % value) + r = tree.xpath("/tag[@id='%s']" % value) # $ Alert urlpatterns = [ diff --git a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathFlow.py b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathFlow.py index c2fe2ce1edb3..0a4f97ce30e7 100644 --- a/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathFlow.py +++ b/python/ql/test/query-tests/Security/CWE-643-XPathInjection/xpathFlow.py @@ -1,5 +1,5 @@ from io import StringIO -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @@ -11,7 +11,7 @@ def xpath1(): xpathQuery = request.args.get('xml', '') f = StringIO('') tree = etree.parse(f) - r = tree.xpath(xpathQuery) + r = tree.xpath(xpathQuery) # $ Alert @app.route("/xpath2") @@ -20,7 +20,7 @@ def xpath2(): xpathQuery = request.args.get('xml', '') root = etree.XML("TEXT") - find_text = etree.XPath(xpathQuery) + find_text = etree.XPath(xpathQuery) # $ Alert text = find_text(root)[0] @@ -29,7 +29,7 @@ def xpath3(): from lxml import etree xpathQuery = request.args.get('xml', '') root = etree.XML("TEXT") - find_text = etree.XPath(xpathQuery, smart_strings=False) + find_text = etree.XPath(xpathQuery, smart_strings=False) # $ Alert text = find_text(root)[0] @@ -38,7 +38,7 @@ def xpath4(): from lxml import etree xpathQuery = request.args.get('xml', '') root = etree.XML("TEXT") - find_text = etree.ETXPath(xpathQuery) + find_text = etree.ETXPath(xpathQuery) # $ Alert text = find_text(root)[0] @app.route("/xpath5") @@ -46,4 +46,4 @@ def xpath5(): import libxml2 xpathQuery = request.args.get('xml', '') doc = libxml2.parseFile('xpath_injection/credential.xml') - results = doc.xpathEval(xpathQuery) + results = doc.xpathEval(xpathQuery) # $ Alert diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index aa8cea07ed16..22fcfd05fa19 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -1,3 +1,9 @@ +#select +| test.py:8:30:8:33 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:8:19:8:21 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:25:9:27 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:29:11:31 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:21:18:23 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:271:20:272 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | edges | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:2:26:2:32 | ControlFlowNode for request | provenance | | | test.py:2:26:2:32 | ControlFlowNode for request | test.py:7:12:7:18 | ControlFlowNode for request | provenance | | @@ -26,9 +32,3 @@ nodes | test.py:18:28:18:31 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | | test.py:21:18:21:21 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | subpaths -#select -| test.py:8:30:8:33 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:8:19:8:21 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:25:9:27 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:29:11:31 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:21:18:23 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:271:20:272 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.qlref b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.qlref index 8c457eb7467e..1847f552d933 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.qlref +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.qlref @@ -1 +1,2 @@ -Security/CWE-730/PolynomialReDoS.ql +query: Security/CWE-730/PolynomialReDoS.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py index 622fa6803b90..60584229b917 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py @@ -1,22 +1,22 @@ import re -from flask import Flask, request +from flask import Flask, request # $ Source app = Flask(__name__) @app.route("/poly-redos") def code_execution(): text = request.args.get("text") - re.sub(r"^\s+|\s+$", "", text) # NOT OK - re.match(r"^0\.\d+E?\d+$", text) # NOT OK + re.sub(r"^\s+|\s+$", "", text) # $ Alert # NOT OK + re.match(r"^0\.\d+E?\d+$", text) # $ Alert # NOT OK reg = re.compile(r"^\s+|\s+$") - reg.sub("", text) # NOT OK + reg.sub("", text) # $ Alert # NOT OK def indirect(input_reg_str, my_text): my_reg = re.compile(input_reg_str) - my_reg.sub("", my_text) # NOT OK + my_reg.sub("", my_text) # $ Alert # NOT OK indirect(r"^\s+|\s+$", text) reg2 = re.compile(r"(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y") - reg2.sub("", text) # NOT OK + reg2.sub("", text) # $ Alert # NOT OK diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/KnownCVEs.py b/python/ql/test/query-tests/Security/CWE-730-ReDoS/KnownCVEs.py index 14a8ff528090..6e63bf28f3c1 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/KnownCVEs.py +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/KnownCVEs.py @@ -12,7 +12,7 @@ toFlag = re.compile(newline) # https://github.com/github/codeql-python-CVE-coverage/issues/400 -re.compile(r'[+-]?(\d+)*\.\d+%?') +re.compile(r'[+-]?(\d+)*\.\d+%?') # $ Alert re.compile(r'"""\s+(?:.|\n)*?\s+"""') re.compile(r'(\{\s+)(\S+)(\s+[^}]+\s+\}\s)') re.compile(r'".*``.*``.*"') @@ -27,12 +27,12 @@ simple_email_re = re.compile(r"^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$") # https://github.com/github/codeql-python-CVE-coverage/issues/249 -rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' +rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' # $ Alert 'realm=(["\']?)([^"\']*)\\2', re.I) # https://github.com/github/codeql-python-CVE-coverage/issues/248 gauntlet = re.compile( - r"""^([-/:,#%.'"\s!\w]|\w-\w|'[\s\w]+'\s*|"[\s\w]+"|\([\d,%\.\s]+\))*$""", + r"""^([-/:,#%.'"\s!\w]|\w-\w|'[\s\w]+'\s*|"[\s\w]+"|\([\d,%\.\s]+\))*$""", # $ Alert flags=re.U ) diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.qlref b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.qlref index 4c19d395edbe..2cc0b9cb67cb 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.qlref +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.qlref @@ -1 +1,2 @@ -Security/CWE-730/ReDoS.ql +query: Security/CWE-730/ReDoS.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py b/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py index 4aad94021e40..736bb5a936e5 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py @@ -3,7 +3,7 @@ # NOT GOOD; attack: "_" + "__".repeat(100) # Adapted from marked (https://github.com/markedjs/marked), which is licensed # under the MIT license; see file marked-LICENSE. -bad1 = re.compile(r'''^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)''') +bad1 = re.compile(r'''^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)''') # $ Alert # GOOD # Adapted from marked (https://github.com/markedjs/marked), which is licensed @@ -18,7 +18,7 @@ # NOT GOOD; attack: " '" + "\\\\".repeat(100) # Adapted from CodeMirror (https://github.com/codemirror/codemirror), # which is licensed under the MIT license; see file CodeMirror-LICENSE. -bad2 = re.compile(r'''^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?''') +bad2 = re.compile(r'''^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?''') # $ Alert # GOOD # Adapted from lulucms2 (https://github.com/yiifans/lulucms2). @@ -30,53 +30,53 @@ good3 = re.compile(r'''^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*''') # NOT GOOD, variant of good3; attack: "a|\n:|\n" + "||\n".repeat(100) -bad4 = re.compile(r'''^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)a''') +bad4 = re.compile(r'''^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)a''') # $ Alert # NOT GOOD; attack: "/" + "\\/a".repeat(100) # Adapted from ANodeBlog (https://github.com/gefangshuai/ANodeBlog), # which is licensed under the Apache License 2.0; see file ANodeBlog-LICENSE. -bad5 = re.compile(r'''\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)''') +bad5 = re.compile(r'''\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)''') # $ Alert # NOT GOOD; attack: "##".repeat(100) + "\na" # Adapted from CodeMirror (https://github.com/codemirror/codemirror), # which is licensed under the MIT license; see file CodeMirror-LICENSE. -bad6 = re.compile(r'''^([\s\[\{\(]|#.*)*$''') +bad6 = re.compile(r'''^([\s\[\{\(]|#.*)*$''') # $ Alert # GOOD good4 = re.compile(r'''(\r\n|\r|\n)+''') # BAD - PoC: `node -e "/((?:[^\"\']|\".*?\"|\'.*?\')*?)([(,)]|$)/.test(\"'''''''''''''''''''''''''''''''''''''''''''''\\\"\");"`. It's complicated though, because the regexp still matches something, it just matches the empty-string after the attack string. -actuallyBad = re.compile(r'''((?:[^"']|".*?"|'.*?')*?)([(,)]|$)''') +actuallyBad = re.compile(r'''((?:[^"']|".*?"|'.*?')*?)([(,)]|$)''') # $ Alert # NOT GOOD; attack: "a" + "[]".repeat(100) + ".b\n" # Adapted from Knockout (https://github.com/knockout/knockout), which is # licensed under the MIT license; see file knockout-LICENSE -bad6 = re.compile(r'''^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$''') +bad6 = re.compile(r'''^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$''') # $ Alert # GOOD good6 = re.compile(r'''(a|.)*''') # Testing the NFA - only some of the below are detected. -bad7 = re.compile(r'''^([a-z]+)+$''') -bad8 = re.compile(r'''^([a-z]*)*$''') -bad9 = re.compile(r'''^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$''') -bad10 = re.compile(r'''^(([a-z])+.)+[A-Z]([a-z])+$''') +bad7 = re.compile(r'''^([a-z]+)+$''') # $ Alert +bad8 = re.compile(r'''^([a-z]*)*$''') # $ Alert +bad9 = re.compile(r'''^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$''') # $ Alert +bad10 = re.compile(r'''^(([a-z])+.)+[A-Z]([a-z])+$''') # $ Alert # NOT GOOD; attack: "[" + "][".repeat(100) + "]!" # Adapted from Prototype.js (https://github.com/prototypejs/prototype), which # is licensed under the MIT license; see file Prototype.js-LICENSE. -bad11 = re.compile(r'''(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)''') +bad11 = re.compile(r'''(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)''') # $ Alert # NOT GOOD; attack: "'" + "\\a".repeat(100) + '"' # Adapted from Prism (https://github.com/PrismJS/prism), which is licensed # under the MIT license; see file Prism-LICENSE. -bad12 = re.compile(r'''("|')(\\?.)*?\1''') +bad12 = re.compile(r'''("|')(\\?.)*?\1''') # $ Alert # NOT GOOD -bad13 = re.compile(r'''(b|a?b)*c''') +bad13 = re.compile(r'''(b|a?b)*c''') # $ Alert # NOT GOOD -bad15 = re.compile(r'''(a|aa?)*b''') +bad15 = re.compile(r'''(a|aa?)*b''') # $ Alert # GOOD good7 = re.compile(r'''(.|\n)*!''') @@ -88,31 +88,31 @@ good8 = re.compile(r'''([\w.]+)*''') # NOT GOOD -bad17 = re.compile(r'''(a|aa?)*b''') +bad17 = re.compile(r'''(a|aa?)*b''') # $ Alert # GOOD - not used as regexp good9 = '(a|aa?)*b' # NOT GOOD -bad18 = re.compile(r'''(([\s\S]|[^a])*)"''') +bad18 = re.compile(r'''(([\s\S]|[^a])*)"''') # $ Alert # GOOD - there is no witness in the end that could cause the regexp to not match good10 = re.compile(r'''([^"']+)*''') # NOT GOOD -bad20 = re.compile(r'''((.|[^a])*)"''') +bad20 = re.compile(r'''((.|[^a])*)"''') # $ Alert # GOOD good10 = re.compile(r'''((a|[^a])*)"''') # NOT GOOD -bad21 = re.compile(r'''((b|[^a])*)"''') +bad21 = re.compile(r'''((b|[^a])*)"''') # $ Alert # NOT GOOD -bad22 = re.compile(r'''((G|[^a])*)"''') +bad22 = re.compile(r'''((G|[^a])*)"''') # $ Alert # NOT GOOD -bad23 = re.compile(r'''(([0-9]|[^a])*)"''') +bad23 = re.compile(r'''(([0-9]|[^a])*)"''') # $ Alert # NOT GOOD bad24 = re.compile(r'''(?:=(?:([!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+)|"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"])*)"))?''') @@ -124,55 +124,55 @@ bad26 = re.compile(r'''"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"\\])*)"''') # NOT GOOD -bad27 = re.compile(r'''(([a-z]|[d-h])*)"''') +bad27 = re.compile(r'''(([a-z]|[d-h])*)"''') # $ Alert # NOT GOOD -bad27 = re.compile(r'''(([^a-z]|[^0-9])*)"''') +bad27 = re.compile(r'''(([^a-z]|[^0-9])*)"''') # $ Alert # NOT GOOD -bad28 = re.compile(r'''((\d|[0-9])*)"''') +bad28 = re.compile(r'''((\d|[0-9])*)"''') # $ Alert # NOT GOOD -bad29 = re.compile(r'''((\s|\s)*)"''') +bad29 = re.compile(r'''((\s|\s)*)"''') # $ Alert # NOT GOOD -bad30 = re.compile(r'''((\w|G)*)"''') +bad30 = re.compile(r'''((\w|G)*)"''') # $ Alert # GOOD good11 = re.compile(r'''((\s|\d)*)"''') # NOT GOOD -bad31 = re.compile(r'''((\d|\w)*)"''') +bad31 = re.compile(r'''((\d|\w)*)"''') # $ Alert # NOT GOOD -bad32 = re.compile(r'''((\d|5)*)"''') +bad32 = re.compile(r'''((\d|5)*)"''') # $ Alert # NOT GOOD -bad33 = re.compile(r'''((\s|[\f])*)"''') +bad33 = re.compile(r'''((\s|[\f])*)"''') # $ Alert # NOT GOOD -bad34 = re.compile(r'''((\s|[\v]|\\v)*)"''') +bad34 = re.compile(r'''((\s|[\v]|\\v)*)"''') # $ Alert # NOT GOOD -bad35 = re.compile(r'''((\f|[\f])*)"''') +bad35 = re.compile(r'''((\f|[\f])*)"''') # $ Alert # NOT GOOD -bad36 = re.compile(r'''((\W|\D)*)"''') +bad36 = re.compile(r'''((\W|\D)*)"''') # $ Alert # NOT GOOD -bad37 = re.compile(r'''((\S|\w)*)"''') +bad37 = re.compile(r'''((\S|\w)*)"''') # $ Alert # NOT GOOD -bad38 = re.compile(r'''((\S|[\w])*)"''') +bad38 = re.compile(r'''((\S|[\w])*)"''') # $ Alert # NOT GOOD -bad39 = re.compile(r'''((1s|[\da-z])*)"''') +bad39 = re.compile(r'''((1s|[\da-z])*)"''') # $ Alert # NOT GOOD -bad40 = re.compile(r'''((0|[\d])*)"''') +bad40 = re.compile(r'''((0|[\d])*)"''') # $ Alert # NOT GOOD -bad41 = re.compile(r'''(([\d]+)*)"''') +bad41 = re.compile(r'''(([\d]+)*)"''') # $ Alert # GOOD - there is no witness in the end that could cause the regexp to not match good12 = re.compile(r'''(\d+(X\d+)?)+''') @@ -184,49 +184,49 @@ good15 = re.compile(r'''^([^>]+)*(>|$)''') # NOT GOOD -bad43 = re.compile(r'''^([^>a]+)*(>|$)''') +bad43 = re.compile(r'''^([^>a]+)*(>|$)''') # $ Alert # NOT GOOD -bad44 = re.compile(r'''(\n\s*)+$''') +bad44 = re.compile(r'''(\n\s*)+$''') # $ Alert # NOT GOOD -bad45 = re.compile(r'''^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})''') +bad45 = re.compile(r'''^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})''') # $ Alert # NOT GOOD -bad46 = re.compile(r'''\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)((\s*([a-zA-Z]+)\: ?([ a-zA-Z{}]+),?)+)*\s*\]\}''') +bad46 = re.compile(r'''\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)((\s*([a-zA-Z]+)\: ?([ a-zA-Z{}]+),?)+)*\s*\]\}''') # $ Alert # NOT GOOD -bad47 = re.compile(r'''(a+|b+|c+)*c''') +bad47 = re.compile(r'''(a+|b+|c+)*c''') # $ Alert # NOT GOOD -bad48 = re.compile(r'''(((a+a?)*)+b+)''') +bad48 = re.compile(r'''(((a+a?)*)+b+)''') # $ Alert # NOT GOOD -bad49 = re.compile(r'''(a+)+bbbb''') +bad49 = re.compile(r'''(a+)+bbbb''') # $ Alert # GOOD good16 = re.compile(r'''(a+)+aaaaa*a+''') # NOT GOOD -bad50 = re.compile(r'''(a+)+aaaaa$''') +bad50 = re.compile(r'''(a+)+aaaaa$''') # $ Alert # GOOD good17 = re.compile(r'''(\n+)+\n\n''') # NOT GOOD -bad51 = re.compile(r'''(\n+)+\n\n$''') +bad51 = re.compile(r'''(\n+)+\n\n$''') # $ Alert # NOT GOOD -bad52 = re.compile(r'''([^X]+)*$''') +bad52 = re.compile(r'''([^X]+)*$''') # $ Alert # NOT GOOD -bad53 = re.compile(r'''(([^X]b)+)*$''') +bad53 = re.compile(r'''(([^X]b)+)*$''') # $ Alert # GOOD good18 = re.compile(r'''(([^X]b)+)*($|[^X]b)''') # NOT GOOD -bad54 = re.compile(r'''(([^X]b)+)*($|[^X]c)''') +bad54 = re.compile(r'''(([^X]b)+)*($|[^X]c)''') # $ Alert # GOOD good20 = re.compile(r'''((ab)+)*ababab''') @@ -238,13 +238,13 @@ good22 = re.compile(r'''((ab)+)*''') # NOT GOOD -bad55 = re.compile(r'''((ab)+)*$''') +bad55 = re.compile(r'''((ab)+)*$''') # $ Alert # GOOD good23 = re.compile(r'''((ab)+)*[a1][b1][a2][b2][a3][b3]''') # NOT GOOD -bad56 = re.compile(r'''([\n\s]+)*(.)''') +bad56 = re.compile(r'''([\n\s]+)*(.)''') # $ Alert # GOOD - any witness passes through the accept state. good24 = re.compile(r'''(A*A*X)*''') @@ -253,76 +253,76 @@ good26 = re.compile(r'''([^\\\]]+)*''') # NOT GOOD -bad59 = re.compile(r'''(\w*foobarbaz\w*foobarbaz\w*foobarbaz\w*foobarbaz\s*foobarbaz\d*foobarbaz\w*)+-''') +bad59 = re.compile(r'''(\w*foobarbaz\w*foobarbaz\w*foobarbaz\w*foobarbaz\s*foobarbaz\d*foobarbaz\w*)+-''') # $ Alert # NOT GOOD -bad60 = re.compile(r'''(.thisisagoddamnlongstringforstresstestingthequery|\sthisisagoddamnlongstringforstresstestingthequery)*-''') +bad60 = re.compile(r'''(.thisisagoddamnlongstringforstresstestingthequery|\sthisisagoddamnlongstringforstresstestingthequery)*-''') # $ Alert # NOT GOOD -bad61 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|this\w+query)*-''') +bad61 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|this\w+query)*-''') # $ Alert # GOOD good27 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|imanotherbutunrelatedstringcomparedtotheotherstring)*-''') # GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) -good28 = re.compile('''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') +good28 = re.compile('''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') # $ Alert # GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) -good29 = re.compile('''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') +good29 = re.compile('''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') # $ Alert # NOT GOOD (but cannot currently construct a prefix) -bad62 = re.compile(r'''a{2,3}(b+)+X''') +bad62 = re.compile(r'''a{2,3}(b+)+X''') # $ Alert # NOT GOOD (and a good prefix test) -bad63 = re.compile(r'''^<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>''') +bad63 = re.compile(r'''^<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>''') # $ Alert # GOOD good30 = re.compile(r'''(a+)*[\s\S][\s\S][\s\S]?''') # GOOD - but we fail to see that repeating the attack string ends in the "accept any" state (due to not parsing the range `[\s\S]{2,3}`). -good31 = re.compile(r'''(a+)*[\s\S]{2,3}''') +good31 = re.compile(r'''(a+)*[\s\S]{2,3}''') # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists (due to not parsing the range `[\s\S]{2,}` when constructing the NFA). -good32 = re.compile(r'''(a+)*([\s\S]{2,}|X)$''') +good32 = re.compile(r'''(a+)*([\s\S]{2,}|X)$''') # $ Alert # GOOD good33 = re.compile(r'''(a+)*([\s\S]*|X)$''') # NOT GOOD -bad64 = re.compile(r'''((a+)*$|[\s\S]+)''') +bad64 = re.compile(r'''((a+)*$|[\s\S]+)''') # $ Alert # GOOD - but still flagged. The only change compared to the above is the order of alternatives, which we don't model. -good34 = re.compile(r'''([\s\S]+|(a+)*$)''') +good34 = re.compile(r'''([\s\S]+|(a+)*$)''') # $ Alert # GOOD good35 = re.compile(r'''((;|^)a+)+$''') # NOT GOOD (a good prefix test) -bad65 = re.compile(r'''(^|;)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(e+)+f''') +bad65 = re.compile(r'''(^|;)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(e+)+f''') # $ Alert # NOT GOOD -bad66 = re.compile(r'''^ab(c+)+$''') +bad66 = re.compile(r'''^ab(c+)+$''') # $ Alert # NOT GOOD -bad67 = re.compile(r'''(\d(\s+)*){20}''') +bad67 = re.compile(r'''(\d(\s+)*){20}''') # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists. -good36 = re.compile(r'''(([^/]|X)+)(\/[\s\S]*)*$''') +good36 = re.compile(r'''(([^/]|X)+)(\/[\s\S]*)*$''') # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists. -good37 = re.compile(r'''^((x([^Y]+)?)*(Y|$))''') +good37 = re.compile(r'''^((x([^Y]+)?)*(Y|$))''') # $ Alert # NOT GOOD -bad68 = re.compile(r'''(a*)+b''') +bad68 = re.compile(r'''(a*)+b''') # $ Alert # NOT GOOD -bad69 = re.compile(r'''foo([\w-]*)+bar''') +bad69 = re.compile(r'''foo([\w-]*)+bar''') # $ Alert # NOT GOOD -bad70 = re.compile(r'''((ab)*)+c''') +bad70 = re.compile(r'''((ab)*)+c''') # $ Alert # NOT GOOD -bad71 = re.compile(r'''(a?a?)*b''') +bad71 = re.compile(r'''(a?a?)*b''') # $ Alert # GOOD good38 = re.compile(r'''(a?)*b''') @@ -331,44 +331,44 @@ bad72 = re.compile(r'''(c?a?)*b''') # NOT GOOD -bad73 = re.compile(r'''(?:a|a?)+b''') +bad73 = re.compile(r'''(?:a|a?)+b''') # $ Alert # NOT GOOD - but not detected. bad74 = re.compile(r'''(a?b?)*$''') # NOT GOOD -bad76 = re.compile(r'''PRE(([a-c]|[c-d])T(e?e?e?e?|X))+(cTcT|cTXcTX$)''') +bad76 = re.compile(r'''PRE(([a-c]|[c-d])T(e?e?e?e?|X))+(cTcT|cTXcTX$)''') # $ Alert # NOT GOOD - but not detected -bad77 = re.compile(r'''^((a)+\w)+$''') +bad77 = re.compile(r'''^((a)+\w)+$''') # $ Alert # NOT GOOD -bad78 = re.compile(r'''^(b+.)+$''') +bad78 = re.compile(r'''^(b+.)+$''') # $ Alert # GOOD good39 = re.compile(r'''a*b''') # All 4 bad combinations of nested * and + -bad79 = re.compile(r'''(a*)*b''') -bad80 = re.compile(r'''(a+)*b''') -bad81 = re.compile(r'''(a*)+b''') -bad82 = re.compile(r'''(a+)+b''') +bad79 = re.compile(r'''(a*)*b''') # $ Alert +bad80 = re.compile(r'''(a+)*b''') # $ Alert +bad81 = re.compile(r'''(a*)+b''') # $ Alert +bad82 = re.compile(r'''(a+)+b''') # $ Alert # GOOD good40 = re.compile(r'''(a|b)+''') good41 = re.compile(r'''(?:[\s;,"'<>(){}|[\]@=+*]|:(?![/\\]))+''') # parses wrongly, sees column 42 as a char set start # NOT GOOD -bad83 = re.compile(r'''^((?:a{|-)|\w\{)+X$''') -bad84 = re.compile(r'''^((?:a{0|-)|\w\{\d)+X$''') -bad85 = re.compile(r'''^((?:a{0,|-)|\w\{\d,)+X$''') -bad86 = re.compile(r'''^((?:a{0,2|-)|\w\{\d,\d)+X$''') +bad83 = re.compile(r'''^((?:a{|-)|\w\{)+X$''') # $ Alert +bad84 = re.compile(r'''^((?:a{0|-)|\w\{\d)+X$''') # $ Alert +bad85 = re.compile(r'''^((?:a{0,|-)|\w\{\d,)+X$''') # $ Alert +bad86 = re.compile(r'''^((?:a{0,2|-)|\w\{\d,\d)+X$''') # $ Alert # GOOD: good42 = re.compile(r'''^((?:a{0,2}|-)|\w\{\d,\d\})+X$''') # NOT GOOD -bad87 = re.compile(r'X(\u0061|a)*Y') +bad87 = re.compile(r'X(\u0061|a)*Y') # $ Alert # GOOD good43 = re.compile(r'X(\u0061|b)+Y') @@ -377,17 +377,17 @@ good44 = re.compile(r'("[^"]*?"|[^"\s]+)+(?=\s*|\s*$)') # BAD -bad88 = re.compile(r'/("[^"]*?"|[^"\s]+)+(?=\s*|\s*$)X') -bad89 = re.compile(r'/("[^"]*?"|[^"\s]+)+(?=X)') +bad88 = re.compile(r'/("[^"]*?"|[^"\s]+)+(?=\s*|\s*$)X') # $ Alert +bad89 = re.compile(r'/("[^"]*?"|[^"\s]+)+(?=X)') # $ Alert # BAD -bad90 = re.compile(r'\A(\d|0)*x') -bad91 = re.compile(r'(\d|0)*\Z') -bad92 = re.compile(r'\b(\d|0)*x') +bad90 = re.compile(r'\A(\d|0)*x') # $ Alert +bad91 = re.compile(r'(\d|0)*\Z') # $ Alert +bad92 = re.compile(r'\b(\d|0)*x') # $ Alert # GOOD stress1 = re.compile(r"(? 2) - self.assertTrue(1 in [1]) - self.assertFalse(0 is "") + self.assertTrue(1 == 1) # $ Alert + self.assertFalse(1 > 2) # $ Alert + self.assertTrue(1 in [1]) # $ Alert + self.assertFalse(0 is "") # $ Alert diff --git a/python/ql/test/query-tests/Variables/general/Global.qlref b/python/ql/test/query-tests/Variables/general/Global.qlref index c20333a006e4..9b2b8470e10d 100644 --- a/python/ql/test/query-tests/Variables/general/Global.qlref +++ b/python/ql/test/query-tests/Variables/general/Global.qlref @@ -1 +1,2 @@ -Variables/Global.ql \ No newline at end of file +query: Variables/Global.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/general/GlobalAtModuleLevel.qlref b/python/ql/test/query-tests/Variables/general/GlobalAtModuleLevel.qlref index f12469499b74..9c4da1043fd1 100644 --- a/python/ql/test/query-tests/Variables/general/GlobalAtModuleLevel.qlref +++ b/python/ql/test/query-tests/Variables/general/GlobalAtModuleLevel.qlref @@ -1 +1,2 @@ -Variables/GlobalAtModuleLevel.ql \ No newline at end of file +query: Variables/GlobalAtModuleLevel.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/general/ShadowBuiltin.qlref b/python/ql/test/query-tests/Variables/general/ShadowBuiltin.qlref index d732a539e5ff..83d2543e7470 100644 --- a/python/ql/test/query-tests/Variables/general/ShadowBuiltin.qlref +++ b/python/ql/test/query-tests/Variables/general/ShadowBuiltin.qlref @@ -1 +1,2 @@ -Variables/ShadowBuiltin.ql +query: Variables/ShadowBuiltin.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/general/ShadowGlobal.qlref b/python/ql/test/query-tests/Variables/general/ShadowGlobal.qlref index d3d632da035a..a7e7b3c4bad6 100644 --- a/python/ql/test/query-tests/Variables/general/ShadowGlobal.qlref +++ b/python/ql/test/query-tests/Variables/general/ShadowGlobal.qlref @@ -1 +1,2 @@ -Variables/ShadowGlobal.ql +query: Variables/ShadowGlobal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/general/variables_test.py b/python/ql/test/query-tests/Variables/general/variables_test.py index e623ee5244d6..d4d7e3aeb651 100644 --- a/python/ql/test/query-tests/Variables/general/variables_test.py +++ b/python/ql/test/query-tests/Variables/general/variables_test.py @@ -4,14 +4,14 @@ #Shadow Builtin def sh1(x): - len = x + 2 #Shadows + len = x + 2 # $ Alert[py/local-shadows-builtin] #Shadows len = x + 0 # no shadowing warning for 2nd def return len #Shadow Global def sh2(x): - sh1 = x + 1 #Shadows + sh1 = x + 1 # $ Alert[py/local-shadows-global] #Shadows sh1 = x + 0 # no shadowing warning for 2nd def return sh1 @@ -54,14 +54,14 @@ def func(): return is_used_var2 #Redundant global declaration -global g_x +global g_x # $ Alert[py/redundant-global-declaration] g_x = 0 #Use global def uses_global(arg): - global g_x + global g_x # $ Alert[py/use-of-global] g_x = arg use(g_x) diff --git a/python/ql/test/query-tests/Variables/multiple/MultiplyDefined.qlref b/python/ql/test/query-tests/Variables/multiple/MultiplyDefined.qlref index 293098be566b..406acf779df9 100644 --- a/python/ql/test/query-tests/Variables/multiple/MultiplyDefined.qlref +++ b/python/ql/test/query-tests/Variables/multiple/MultiplyDefined.qlref @@ -1 +1,2 @@ -Variables/MultiplyDefined.ql +query: Variables/MultiplyDefined.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/multiple/uselesscode_test.py b/python/ql/test/query-tests/Variables/multiple/uselesscode_test.py index 49f367d6db3e..4a73d87c7b0d 100644 --- a/python/ql/test/query-tests/Variables/multiple/uselesscode_test.py +++ b/python/ql/test/query-tests/Variables/multiple/uselesscode_test.py @@ -1,8 +1,8 @@ #Multiple declarations -def mult(a): - x = 1 +def mult(a): # $ Alert + x = 1 # $ Alert y = a x = 2 #Need to use x, otherwise it is ignored @@ -25,7 +25,7 @@ def _double_loop(seq): for i in seq: pass -class Mult(object): +class Mult(object): # $ Alert pass @@ -49,7 +49,7 @@ def isStr(s): # 'bad' actually *is* always redefined before being read. def have_nosmp(): try: - bad = os.environ['NPY_NOSMP'] + bad = os.environ['NPY_NOSMP'] # $ Alert bad = 1 except KeyError: bad = 0 @@ -64,7 +64,7 @@ def simple_try(foo): def try_with_else(foo): try: - bad = foo.bar + bad = foo.bar # $ Alert except AttributeError: raise else: @@ -114,7 +114,7 @@ def odasa4166(cond): def odasa5315(): x, y = foo() # OK as y is used use(y) - x, y = bar() # Not OK as neither x nor y are used. + x, y = bar() # $ Alert # Not OK as neither x nor y are used. x, y = baz() # OK as both used return x + y diff --git a/python/ql/test/query-tests/Variables/undefined/UndefinedExport.qlref b/python/ql/test/query-tests/Variables/undefined/UndefinedExport.qlref index 3e5d31e47488..d964148077e5 100644 --- a/python/ql/test/query-tests/Variables/undefined/UndefinedExport.qlref +++ b/python/ql/test/query-tests/Variables/undefined/UndefinedExport.qlref @@ -1 +1,2 @@ -Variables/UndefinedExport.ql +query: Variables/UndefinedExport.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.py b/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.py index 0438d8e84b3c..85d26ff76f13 100644 --- a/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.py +++ b/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.py @@ -19,12 +19,12 @@ def f(parameter): helper # Explicitly as import a # Imlicitly from ud_helper defined - ug2 # ERROR - e # ERROR Defined in ud_helper, but not in __all__ + ug2 # $ Alert[py/undefined-global-variable] # ERROR + e # $ Alert[py/undefined-global-variable] # ERROR Defined in ud_helper, but not in __all__ int float __file__ #OK all files have __file__ defined - __path__ #ERROR only modules have __path__ defined + __path__ # $ Alert[py/undefined-global-variable] #ERROR only modules have __path__ defined len #Ok defined in builtins monkey1 #Ok monkey-patched builtins @@ -120,7 +120,7 @@ def inner(): pfp3 += 1 def only_report_once(): - ug3 + ug3 # $ Alert[py/undefined-global-variable] ug3 ug3 ug3 diff --git a/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.qlref b/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.qlref index ea9f5a038426..e69631e746b9 100644 --- a/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.qlref +++ b/python/ql/test/query-tests/Variables/undefined/UndefinedGlobal.qlref @@ -1 +1,2 @@ -Variables/UndefinedGlobal.ql +query: Variables/UndefinedGlobal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py index 26e109af5a2a..24a09f1be336 100644 --- a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py +++ b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py @@ -2,7 +2,7 @@ class C: def m1(self): - y = ug1 + y = ug1 # $ Alert[py/undefined-global-variable] x = 1 return y @@ -10,16 +10,16 @@ def m2(self, p): return p def m3(self, x1): - return u2 + return u2 # $ Alert[py/uninitialized-local-variable] u2 = x1 def m4(self, x2): if x2: u3 = 1 - return u3 + return u3 # $ Alert[py/uninitialized-local-variable] def f(): - y = ug1 + y = ug1 # $ Alert[py/undefined-global-variable] x = 1 return y @@ -34,7 +34,7 @@ def h(): def j(u4): del u4 - return u4 + return u4 # $ Alert[py/uninitialized-local-variable] def k(x5): x5 + 1 @@ -43,7 +43,7 @@ def k(x5): def m(x6): if x6: u6 = 1 - u6 + u6 # $ Alert[py/uninitialized-local-variable] #The following are not uninitialized, but unreachable. u6 u6 @@ -66,13 +66,13 @@ def check_del(cond): del u8 else: pass - u8 + u8 # $ Alert[py/uninitialized-local-variable] if cond: u9 = 1 del u9 else: u9 = 2 - u9 + u9 # $ Alert[py/uninitialized-local-variable] if cond: x10 = 1 del x10 @@ -82,10 +82,10 @@ def check_del(cond): x10 u11 = 1 del u11 - u11 + u11 # $ Alert[py/uninitialized-local-variable] u12 = "hi" del u12 - del u12 + del u12 # $ Alert[py/uninitialized-local-variable] #x will always be defined. def const_range(): @@ -116,7 +116,7 @@ def use_def_conditional(cond4, cond5): u14 = 1 x16 = 2 if cond5: - return u14 + return u14 # $ Alert[py/uninitialized-local-variable] def init_and_set_flag_in_try(f): @@ -148,7 +148,7 @@ def split_not_OK(): except: cond = not False if not not cond: - return u19 + return u19 # $ Alert[py/uninitialized-local-variable] def double_is_none(x): if x is not None: @@ -160,7 +160,7 @@ def double_is_none(x): #ODASA-4241 def def_in_post_loop(seq): - j(x) + j(x) # $ Alert[py/uninitialized-local-variable] x = [] for p in seq: x = p @@ -173,9 +173,9 @@ def f(cond1, cond2): else: y = 1 if cond2: - return x + return x # $ Alert[py/uninitialized-local-variable] else: - return y + return y # $ Alert[py/uninitialized-local-variable] def needs_splitting(var): if var: diff --git a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.qlref b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.qlref index f2d0e603554a..90233ce61888 100644 --- a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.qlref +++ b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.qlref @@ -1 +1,2 @@ -Variables/UninitializedLocal.ql +query: Variables/UninitializedLocal.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/undefined/decorated_exports.py b/python/ql/test/query-tests/Variables/undefined/decorated_exports.py index aad8e347909b..137807a0e004 100644 --- a/python/ql/test/query-tests/Variables/undefined/decorated_exports.py +++ b/python/ql/test/query-tests/Variables/undefined/decorated_exports.py @@ -1,16 +1,16 @@ import dotted -__all__ = ["foo", "bar", "baz", "not_defined"] +__all__ = ["foo", "bar", "baz", "not_defined"] # $ Alert[py/undefined-export] @dotted.decorator def foo(): pass -@undotted_decorator +@undotted_decorator # $ Alert[py/undefined-global-variable] def bar(): pass -@not_imported.but_dotted +@not_imported.but_dotted # $ Alert[py/undefined-global-variable] def baz(): pass diff --git a/python/ql/test/query-tests/Variables/undefined/exports.py b/python/ql/test/query-tests/Variables/undefined/exports.py index b12a501710c7..cb59cc6958d2 100644 --- a/python/ql/test/query-tests/Variables/undefined/exports.py +++ b/python/ql/test/query-tests/Variables/undefined/exports.py @@ -1,4 +1,4 @@ -__all__ = ["foo", "bar", "baz", "quux", "blat", "frob", "nosuch", "i_got_it_elsewhere"] +__all__ = ["foo", "bar", "baz", "quux", "blat", "frob", "nosuch", "i_got_it_elsewhere"] # $ Alert[py/undefined-export] with open("foo.txt") as f: foo = f.read() diff --git a/python/ql/test/query-tests/Variables/undefined/odasa3987.py b/python/ql/test/query-tests/Variables/undefined/odasa3987.py index 9c3a5fa5b2f3..43444bb80cdb 100644 --- a/python/ql/test/query-tests/Variables/undefined/odasa3987.py +++ b/python/ql/test/query-tests/Variables/undefined/odasa3987.py @@ -8,7 +8,7 @@ def f(cond1, cond2): except Exception: if cond2: var = 7 - if var == 1: + if var == 1: # $ Alert[py/uninitialized-local-variable] var = var + 1 elif var == 2: var +- 3 diff --git a/python/ql/test/query-tests/Variables/unused/SuspiciousUnusedLoopIterationVariable.qlref b/python/ql/test/query-tests/Variables/unused/SuspiciousUnusedLoopIterationVariable.qlref index 4b9f136451eb..4931ceb29e85 100644 --- a/python/ql/test/query-tests/Variables/unused/SuspiciousUnusedLoopIterationVariable.qlref +++ b/python/ql/test/query-tests/Variables/unused/SuspiciousUnusedLoopIterationVariable.qlref @@ -1 +1,2 @@ -Variables/SuspiciousUnusedLoopIterationVariable.ql \ No newline at end of file +query: Variables/SuspiciousUnusedLoopIterationVariable.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.qlref b/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.qlref index bd6e5aaa069d..122b9d6456f6 100644 --- a/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.qlref +++ b/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.qlref @@ -1 +1,2 @@ -Variables/UnusedLocalVariable.ql +query: Variables/UnusedLocalVariable.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/unused/UnusedModuleVariable.qlref b/python/ql/test/query-tests/Variables/unused/UnusedModuleVariable.qlref index 587ad9510764..8709d1bd6045 100644 --- a/python/ql/test/query-tests/Variables/unused/UnusedModuleVariable.qlref +++ b/python/ql/test/query-tests/Variables/unused/UnusedModuleVariable.qlref @@ -1 +1,2 @@ -Variables/UnusedModuleVariable.ql \ No newline at end of file +query: Variables/UnusedModuleVariable.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/unused/UnusedParameter.qlref b/python/ql/test/query-tests/Variables/unused/UnusedParameter.qlref index b37e4859c1b0..1ab2f09ae4ff 100644 --- a/python/ql/test/query-tests/Variables/unused/UnusedParameter.qlref +++ b/python/ql/test/query-tests/Variables/unused/UnusedParameter.qlref @@ -1 +1,2 @@ -Variables/UnusedParameter.ql +query: Variables/UnusedParameter.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/unused/test.py b/python/ql/test/query-tests/Variables/unused/test.py index 18dd2020306e..2159bf86b6e5 100644 --- a/python/ql/test/query-tests/Variables/unused/test.py +++ b/python/ql/test/query-tests/Variables/unused/test.py @@ -1,7 +1,7 @@ #Unused def fail(): - for t in [TypeA, TypeB]: + for t in [TypeA, TypeB]: # $ Alert[py/unused-loop-variable] x = TypeA() run_test(x) @@ -63,19 +63,19 @@ def OK8(seq, output): #Not OK -- Use a constant, but also a variable def fail2(sequence): for x in sequence: - for y in sequence: + for y in sequence: # $ Alert[py/unused-loop-variable] do_something(x+1) def fail3(sequence): for x in sequence: do_something(x+1) - for y in sequence: + for y in sequence: # $ Alert[py/unused-loop-variable] do_something(x+1) def fail4(coll, sequence): while coll: x = coll.pop() - for s in sequence: + for s in sequence: # $ Alert[py/unused-loop-variable] do_something(x+1) #OK See ODASA-4153 and ODASA-4533 @@ -103,7 +103,7 @@ def kwargs_is_a_use(seq): #A deletion is a use, but this is almost certainly an error def cleanup(sessions): - for sess in sessions: + for sess in sessions: # $ Alert[py/unused-loop-variable] # Original code had some comment about deleting sessions del sess diff --git a/python/ql/test/query-tests/Variables/unused/variables_test.py b/python/ql/test/query-tests/Variables/unused/variables_test.py index 611b9fbd6b2a..9b29c1d0103c 100644 --- a/python/ql/test/query-tests/Variables/unused/variables_test.py +++ b/python/ql/test/query-tests/Variables/unused/variables_test.py @@ -22,11 +22,11 @@ #Unused parameter, local and global -def u1(x): +def u1(x): # $ Alert[py/unused-parameter] return 0 def u2(): - x = 1 + x = 1 # $ Alert[py/unused-local-variable] return 1 #These parameters are OK due to (potential overriding) @@ -45,8 +45,8 @@ def ok3(self, arg): pass #Unused module variable -not_used_var1 = 17 -not_used_var2 = 18 +not_used_var1 = 17 # $ Alert[py/unused-global-variable] +not_used_var2 = 18 # $ Alert[py/unused-global-variable] is_used_var1 = 19 is_used_var2 = 20 @@ -83,21 +83,21 @@ def f(t): # Entirely unused tuple -a,b,c = t +a,b,c = t # $ Alert[py/unused-global-variable] def f(t): - a,b,c = t + a,b,c = t # $ Alert[py/unused-local-variable] use(t) def second_def_undefined(): var = 0 use(var) - var = 1 # unused. + var = 1 # $ Alert[py/unused-local-variable] # unused. #And gloablly glob_var = 0 use(glob_var) -glob_var = 1 # unused +glob_var = 1 # $ Alert[py/unused-global-variable] # unused @@ -130,7 +130,7 @@ class C(object): #FP observed def test_dict_unpacking(queryset, field_name, value): #True positive - for tag in value.split(','): + for tag in value.split(','): # $ Alert[py/unused-loop-variable] queryset = queryset.filter(**{field_name + '__name': tag1}) return queryset #False positive diff --git a/python/ql/test/query-tests/Variables/unused_local_nonlocal/UnusedLocalVariable.qlref b/python/ql/test/query-tests/Variables/unused_local_nonlocal/UnusedLocalVariable.qlref index bd6e5aaa069d..122b9d6456f6 100644 --- a/python/ql/test/query-tests/Variables/unused_local_nonlocal/UnusedLocalVariable.qlref +++ b/python/ql/test/query-tests/Variables/unused_local_nonlocal/UnusedLocalVariable.qlref @@ -1 +1,2 @@ -Variables/UnusedLocalVariable.ql +query: Variables/UnusedLocalVariable.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/Variables/unused_local_nonlocal/variables_test.py b/python/ql/test/query-tests/Variables/unused_local_nonlocal/variables_test.py index 4986a6f4eb3f..da7f7dcf7e5e 100644 --- a/python/ql/test/query-tests/Variables/unused_local_nonlocal/variables_test.py +++ b/python/ql/test/query-tests/Variables/unused_local_nonlocal/variables_test.py @@ -29,7 +29,7 @@ def not_fp(): def nonlocal_test(): nonlocal test def set_test(): - test = True + test = True # $ Alert nonlocal_test() set_test() if test: diff --git a/python/ql/test/query-tests/analysis/Consistency/Consistency.qlref b/python/ql/test/query-tests/analysis/Consistency/Consistency.qlref index 6abbdd6dd64d..0343f08ebf44 100644 --- a/python/ql/test/query-tests/analysis/Consistency/Consistency.qlref +++ b/python/ql/test/query-tests/analysis/Consistency/Consistency.qlref @@ -1 +1 @@ -analysis/Consistency.ql +query: analysis/Consistency.ql diff --git a/python/ql/test/query-tests/analysis/jump_to_defn/Definitions.qlref b/python/ql/test/query-tests/analysis/jump_to_defn/Definitions.qlref index d4e89a35c97f..cb6af4ba5b57 100644 --- a/python/ql/test/query-tests/analysis/jump_to_defn/Definitions.qlref +++ b/python/ql/test/query-tests/analysis/jump_to_defn/Definitions.qlref @@ -1 +1 @@ -analysis/Definitions.ql +query: analysis/Definitions.ql diff --git a/python/ql/test/query-tests/analysis/pointsto/FailedInference.qlref b/python/ql/test/query-tests/analysis/pointsto/FailedInference.qlref index b08adfa00b57..991e596544b2 100644 --- a/python/ql/test/query-tests/analysis/pointsto/FailedInference.qlref +++ b/python/ql/test/query-tests/analysis/pointsto/FailedInference.qlref @@ -1 +1 @@ -analysis/FailedInference.ql +query: analysis/FailedInference.ql diff --git a/python/ql/test/query-tests/analysis/pointsto/KeyPointsToFailure.qlref b/python/ql/test/query-tests/analysis/pointsto/KeyPointsToFailure.qlref index db945187917b..bd2bce681851 100644 --- a/python/ql/test/query-tests/analysis/pointsto/KeyPointsToFailure.qlref +++ b/python/ql/test/query-tests/analysis/pointsto/KeyPointsToFailure.qlref @@ -1 +1,2 @@ -analysis/KeyPointsToFailure.ql \ No newline at end of file +query: analysis/KeyPointsToFailure.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/python/ql/test/query-tests/analysis/pointsto/Pruned.qlref b/python/ql/test/query-tests/analysis/pointsto/Pruned.qlref index 2d2c28dbc261..ab448a5dfe67 100644 --- a/python/ql/test/query-tests/analysis/pointsto/Pruned.qlref +++ b/python/ql/test/query-tests/analysis/pointsto/Pruned.qlref @@ -1 +1 @@ -analysis/Pruned.ql +query: analysis/Pruned.ql diff --git a/python/ql/test/query-tests/analysis/suppression/AlertSuppression.qlref b/python/ql/test/query-tests/analysis/suppression/AlertSuppression.qlref index 9d7833eccae7..dc898fca718c 100644 --- a/python/ql/test/query-tests/analysis/suppression/AlertSuppression.qlref +++ b/python/ql/test/query-tests/analysis/suppression/AlertSuppression.qlref @@ -1 +1 @@ -AlertSuppression.ql +query: AlertSuppression.ql diff --git a/shared/util/codeql/util/test/InlineExpectationsTest.qll b/shared/util/codeql/util/test/InlineExpectationsTest.qll index e785adda4566..4e0b2f678449 100644 --- a/shared/util/codeql/util/test/InlineExpectationsTest.qll +++ b/shared/util/codeql/util/test/InlineExpectationsTest.qll @@ -513,10 +513,10 @@ module Make { /** * RegEx pattern to match a comment containing one or more expected results. The comment must have * `$` as its first non-whitespace character. Any subsequent character - * is treated as part of the expected results, except that the comment may contain a `//` sequence - * to treat the remainder of the line as a regular (non-interpreted) comment. + * is treated as part of the expected results, except that the comment may contain a `//` or `#` + * sequence to treat the remainder of the line as a regular (non-interpreted) comment. */ -private string expectationCommentPattern() { result = "\\s*\\$ ((?:[^/]|/[^/])*)(?://.*)?" } +private string expectationCommentPattern() { result = "\\s*\\$ ((?:[^/]|/[^/])*)(?:(//|#).*)?" } /** * The possible columns in an expectation comment. The `TDefaultColumn` branch represents the first