mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge remote-tracking branch 'upstream/main' into better-syntax-for-false-positives-and-negatives-inline-expectation
Required fixing up semantic conflicts in tests. Conflicts: python/ql/test/experimental/library-tests/frameworks/stdlib/Decoding.py
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
/**
|
||||
* A configuration to find all flows.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node fromNode, DataFlow::Node toNode
|
||||
where DataFlow::localFlow(fromNode, toNode)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node fromNode, DataFlow::Node toNode
|
||||
where DataFlow::localFlowStep(fromNode, toNode)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A configuration to find all "maximal" flows.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import python
|
||||
import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A configuration to find the call graph edges.
|
||||
|
||||
@@ -1 +1 @@
|
||||
import experimental.dataflow.internal.DataFlowImplConsistency::Consistency
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
private import experimental.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A configuration to check routing of arguments through magic methods.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A configuration to find the call graph edges.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
|
||||
where
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
|
||||
where
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
|
||||
where
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class GlobalReadTest extends InlineExpectationsTest {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
query predicate importNode(DataFlow::Node res, string name) { res = DataFlow::importNode(name) }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
class CustomTestConfiguration extends DataFlow::Configuration {
|
||||
CustomTestConfiguration() { this = "CustomTestConfiguration" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/** Gets the EssaNode that holds the module imported by the fully qualified module name `name` */
|
||||
DataFlow::EssaNode module_import(string name) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.TaintTracking
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.TaintTracking
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.TaintTracking
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
|
||||
where TaintTracking::localTaintStep(nodeFrom, nodeTo)
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
| test_string.py:17 | ok | str_methods | ts.casefold() |
|
||||
| test_string.py:19 | ok | str_methods | ts.format_map(..) |
|
||||
| test_string.py:20 | ok | str_methods | "{unsafe}".format_map(..) |
|
||||
| test_string.py:31 | fail | binary_decode_encode | base64.a85encode(..) |
|
||||
| test_string.py:32 | fail | binary_decode_encode | base64.a85decode(..) |
|
||||
| test_string.py:35 | fail | binary_decode_encode | base64.b85encode(..) |
|
||||
| test_string.py:36 | fail | binary_decode_encode | base64.b85decode(..) |
|
||||
| test_string.py:39 | fail | binary_decode_encode | base64.encodebytes(..) |
|
||||
| test_string.py:40 | fail | binary_decode_encode | base64.decodebytes(..) |
|
||||
| test_string.py:31 | ok | binary_decode_encode | base64.a85encode(..) |
|
||||
| test_string.py:32 | ok | binary_decode_encode | base64.a85decode(..) |
|
||||
| test_string.py:35 | ok | binary_decode_encode | base64.b85encode(..) |
|
||||
| test_string.py:36 | ok | binary_decode_encode | base64.b85decode(..) |
|
||||
| test_string.py:39 | ok | binary_decode_encode | base64.encodebytes(..) |
|
||||
| test_string.py:40 | ok | binary_decode_encode | base64.decodebytes(..) |
|
||||
| test_string.py:48 | ok | f_strings | Fstring |
|
||||
| test_unpacking.py:18 | ok | extended_unpacking | first |
|
||||
| test_unpacking.py:18 | ok | extended_unpacking | last |
|
||||
|
||||
@@ -123,18 +123,18 @@
|
||||
| test_string.py:114 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:115 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:116 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:126 | fail | binary_decode_encode | base64.b64encode(..) |
|
||||
| test_string.py:127 | fail | binary_decode_encode | base64.b64decode(..) |
|
||||
| test_string.py:129 | fail | binary_decode_encode | base64.standard_b64encode(..) |
|
||||
| test_string.py:130 | fail | binary_decode_encode | base64.standard_b64decode(..) |
|
||||
| test_string.py:132 | fail | binary_decode_encode | base64.urlsafe_b64encode(..) |
|
||||
| test_string.py:133 | fail | binary_decode_encode | base64.urlsafe_b64decode(..) |
|
||||
| test_string.py:135 | fail | binary_decode_encode | base64.b32encode(..) |
|
||||
| test_string.py:136 | fail | binary_decode_encode | base64.b32decode(..) |
|
||||
| test_string.py:138 | fail | binary_decode_encode | base64.b16encode(..) |
|
||||
| test_string.py:139 | fail | binary_decode_encode | base64.b16decode(..) |
|
||||
| test_string.py:142 | fail | binary_decode_encode | base64.encodestring(..) |
|
||||
| test_string.py:143 | fail | binary_decode_encode | base64.decodestring(..) |
|
||||
| test_string.py:126 | ok | binary_decode_encode | base64.b64encode(..) |
|
||||
| test_string.py:127 | ok | binary_decode_encode | base64.b64decode(..) |
|
||||
| test_string.py:129 | ok | binary_decode_encode | base64.standard_b64encode(..) |
|
||||
| test_string.py:130 | ok | binary_decode_encode | base64.standard_b64decode(..) |
|
||||
| test_string.py:132 | ok | binary_decode_encode | base64.urlsafe_b64encode(..) |
|
||||
| test_string.py:133 | ok | binary_decode_encode | base64.urlsafe_b64decode(..) |
|
||||
| test_string.py:135 | ok | binary_decode_encode | base64.b32encode(..) |
|
||||
| test_string.py:136 | ok | binary_decode_encode | base64.b32decode(..) |
|
||||
| test_string.py:138 | ok | binary_decode_encode | base64.b16encode(..) |
|
||||
| test_string.py:139 | ok | binary_decode_encode | base64.b16decode(..) |
|
||||
| test_string.py:142 | ok | binary_decode_encode | base64.encodestring(..) |
|
||||
| test_string.py:143 | ok | binary_decode_encode | base64.decodestring(..) |
|
||||
| test_string.py:148 | fail | binary_decode_encode | quopri.encodestring(..) |
|
||||
| test_string.py:149 | fail | binary_decode_encode | quopri.decodestring(..) |
|
||||
| test_string.py:159 | ok | test_os_path_join | os.path.join(..) |
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
private import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
class TestConfiguration extends DataFlow::Configuration {
|
||||
TestConfiguration() { this = "TestConfiguration" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import experimental.dataflow.TypeTracker
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TypeTracker
|
||||
|
||||
DataFlow::Node module_tracker(TypeTracker t) {
|
||||
t.start() and
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import experimental.dataflow.TypeTracker
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TypeTracker
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
DataFlow::Node tracked(TypeTracker t) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import experimental.dataflow.tainttracking.TestTaintLib
|
||||
import experimental.dataflow.RemoteFlowSources
|
||||
import semmle.python.dataflow.new.RemoteFlowSources
|
||||
|
||||
class RemoteFlowTestTaintConfiguration extends TestTaintTrackingConfiguration {
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
@@ -78,7 +78,7 @@ urlpatterns = [
|
||||
def page_number(request, page_number=1): # $routeHandler routedParameter=page_number
|
||||
return HttpResponse('page_number: {}'.format(page_number)) # $HttpResponse
|
||||
|
||||
def foo_bar_baz(request, foo, bar, baz): # $routeHandler $routedParameter=foo routedParameter=bar routedParameter=baz
|
||||
def foo_bar_baz(request, foo, bar, baz): # $routeHandler routedParameter=foo routedParameter=bar routedParameter=baz
|
||||
return HttpResponse('foo_bar_baz: {} {} {}'.format(foo, bar, baz)) # $HttpResponse
|
||||
|
||||
def path_kwargs(request, foo, bar): # $routeHandler routedParameter=foo routedParameter=bar
|
||||
|
||||
@@ -20,7 +20,7 @@ class User(models.Model):
|
||||
def test_model():
|
||||
User.objects.raw("some sql") # $getSql="some sql"
|
||||
User.objects.annotate(RawSQL("some sql")) # $getSql="some sql"
|
||||
User.objects.annotate(RawSQL("foo"), RawSQL("bar")) # $getSql="foo" $getSql="bar"
|
||||
User.objects.annotate(RawSQL("foo"), RawSQL("bar")) # $getSql="foo" getSql="bar"
|
||||
User.objects.annotate(val=RawSQL("some sql")) # $getSql="some sql"
|
||||
User.objects.extra("some sql") # $getSql="some sql"
|
||||
User.objects.extra(select="select", where="where", tables="tables", order_by="order_by") # $getSql="select" getSql="where" getSql="tables" getSql="order_by"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import experimental.dataflow.tainttracking.TestTaintLib
|
||||
import experimental.dataflow.RemoteFlowSources
|
||||
import semmle.python.dataflow.new.RemoteFlowSources
|
||||
|
||||
class RemoteFlowTestTaintConfiguration extends TestTaintTrackingConfiguration {
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.TaintTracking
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
import SharedCode
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.TaintTracking
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
import SharedCode
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import python
|
||||
private import experimental.dataflow.DataFlow
|
||||
private import experimental.dataflow.TaintTracking
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
|
||||
// Helpers modeling MyClass
|
||||
/** A data-flow Node representing an instance of MyClass. */
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,37 @@
|
||||
# taken from https://dev.mysql.com/doc/connector-python/en/connector-python-example-cursor-transaction.html
|
||||
from __future__ import print_function
|
||||
from datetime import date, datetime, timedelta
|
||||
import mysql.connector
|
||||
|
||||
cnx = mysql.connector.connect(user='scott', database='employees')
|
||||
cursor = cnx.cursor()
|
||||
|
||||
tomorrow = datetime.now().date() + timedelta(days=1)
|
||||
|
||||
add_employee = ("INSERT INTO employees "
|
||||
"(first_name, last_name, hire_date, gender, birth_date) "
|
||||
"VALUES (%s, %s, %s, %s, %s)")
|
||||
add_salary = ("INSERT INTO salaries "
|
||||
"(emp_no, salary, from_date, to_date) "
|
||||
"VALUES (%(emp_no)s, %(salary)s, %(from_date)s, %(to_date)s)")
|
||||
|
||||
data_employee = ('Geert', 'Vanderkelen', tomorrow, 'M', date(1977, 6, 14))
|
||||
|
||||
# Insert new employee
|
||||
cursor.execute(add_employee, data_employee) # $getSql=add_employee
|
||||
emp_no = cursor.lastrowid
|
||||
|
||||
# Insert salary information
|
||||
data_salary = {
|
||||
'emp_no': emp_no,
|
||||
'salary': 50000,
|
||||
'from_date': tomorrow,
|
||||
'to_date': date(9999, 1, 1),
|
||||
}
|
||||
cursor.execute(add_salary, data_salary) # $getSql=add_salary
|
||||
|
||||
# Make sure data is committed to the database
|
||||
cnx.commit()
|
||||
|
||||
cursor.close()
|
||||
cnx.close()
|
||||
@@ -0,0 +1,2 @@
|
||||
import python
|
||||
import experimental.meta.ConceptsTest
|
||||
@@ -0,0 +1,7 @@
|
||||
# taken from https://mysqlclient.readthedocs.io/user_guide.html#some-examples
|
||||
import MySQLdb
|
||||
db=MySQLdb.connect(passwd="moonpie",db="thangs")
|
||||
|
||||
c=db.cursor()
|
||||
max_price=5
|
||||
c.execute("some sql", (max_price,)) # $getSql="some sql"
|
||||
@@ -0,0 +1,6 @@
|
||||
import base64
|
||||
|
||||
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py
|
||||
base64.a85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Ascii85
|
||||
base64.b85decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base85
|
||||
base64.decodebytes(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
|
||||
@@ -0,0 +1,6 @@
|
||||
import base64
|
||||
|
||||
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/test_string.py
|
||||
base64.a85encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Ascii85
|
||||
base64.b85encode(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base85
|
||||
base64.encodebytes(bs)# $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
|
||||
@@ -1,5 +1,15 @@
|
||||
import pickle
|
||||
import marshal
|
||||
import base64
|
||||
|
||||
pickle.loads(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=pickle decodeMayExecuteInput
|
||||
marshal.loads(payload) # $decodeInput=payload decodeOutput=Attribute() decodeFormat=marshal decodeMayExecuteInput
|
||||
pickle.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=pickle decodeMayExecuteInput
|
||||
marshal.loads(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=marshal decodeMayExecuteInput
|
||||
|
||||
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
|
||||
base64.b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
|
||||
base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
|
||||
base64.urlsafe_b64decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
|
||||
base64.b32decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base32
|
||||
base64.b16decode(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base16
|
||||
# deprecated since Python 3.1, but still works
|
||||
base64.decodestring(payload) # $ decodeInput=payload decodeOutput=Attribute() decodeFormat=Base64
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import pickle
|
||||
import marshal
|
||||
import base64
|
||||
|
||||
pickle.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=pickle f-:encodeMayExecuteInput
|
||||
marshal.dumps(obj) # $ MISSING: f-:encodeInput=obj f-:encodeOutput=Attribute() f-:encodeFormat=marshal f-:encodeMayExecuteInput
|
||||
|
||||
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
|
||||
base64.b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
|
||||
base64.standard_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
|
||||
base64.urlsafe_b64encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
|
||||
base64.b32encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base32
|
||||
base64.b16encode(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base16
|
||||
# deprecated since Python 3.1, but still works
|
||||
base64.encodestring(bs) # $ encodeInput=bs encodeOutput=Attribute() encodeFormat=Base64
|
||||
@@ -1,2 +1,2 @@
|
||||
import experimental.dataflow.tainttracking.TestTaintLib
|
||||
import experimental.dataflow.RemoteFlowSources
|
||||
import semmle.python.dataflow.new.RemoteFlowSources
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import python
|
||||
import experimental.dataflow.DataFlow
|
||||
import experimental.semmle.python.Concepts
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.Concepts
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
string value_from_expr(Expr e) {
|
||||
@@ -73,6 +73,38 @@ class DecodingTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class EncodingTest extends InlineExpectationsTest {
|
||||
EncodingTest() { this = "EncodingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(Encoding e |
|
||||
exists(DataFlow::Node data |
|
||||
location = data.getLocation() and
|
||||
element = data.toString() and
|
||||
value = value_from_expr(data.asExpr()) and
|
||||
(
|
||||
data = e.getAnInput() and
|
||||
tag = "encodeInput"
|
||||
or
|
||||
data = e.getOutput() and
|
||||
tag = "encodeOutput"
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(string format |
|
||||
location = e.getLocation() and
|
||||
element = format and
|
||||
value = format and
|
||||
format = e.getFormat() and
|
||||
tag = "encodeFormat"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExecutionTest extends InlineExpectationsTest {
|
||||
CodeExecutionTest() { this = "CodeExecutionTest" }
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
edges
|
||||
| path_injection.py:9:12:9:23 | ControlFlowNode for Attribute | path_injection.py:10:14:10:44 | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:15:12:15:23 | ControlFlowNode for Attribute | path_injection.py:16:13:16:61 | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:16:13:16:61 | ControlFlowNode for Attribute() | path_injection.py:17:14:17:18 | ControlFlowNode for npath |
|
||||
| path_injection.py:24:12:24:23 | ControlFlowNode for Attribute | path_injection.py:25:13:25:61 | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:25:13:25:61 | ControlFlowNode for Attribute() | path_injection.py:28:14:28:18 | ControlFlowNode for npath |
|
||||
| path_injection.py:33:12:33:23 | ControlFlowNode for Attribute | path_injection.py:34:13:34:61 | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:24:9:24:16 | ControlFlowNode for source() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:31:9:31:16 | ControlFlowNode for source() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:38:9:38:16 | ControlFlowNode for source() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:46:9:46:16 | ControlFlowNode for source() |
|
||||
| test.py:12:15:12:15 | SSA variable x | test.py:13:12:13:30 | ControlFlowNode for Attribute() |
|
||||
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() |
|
||||
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() |
|
||||
| test.py:18:9:18:16 | ControlFlowNode for source() | test.py:19:10:19:10 | ControlFlowNode for x |
|
||||
| test.py:24:9:24:16 | ControlFlowNode for source() | test.py:25:19:25:19 | ControlFlowNode for x |
|
||||
| test.py:25:9:25:20 | ControlFlowNode for normalize() | test.py:26:10:26:10 | ControlFlowNode for y |
|
||||
| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | SSA variable x |
|
||||
| test.py:31:9:31:16 | ControlFlowNode for source() | test.py:33:14:33:14 | ControlFlowNode for x |
|
||||
| test.py:38:9:38:16 | ControlFlowNode for source() | test.py:39:19:39:19 | ControlFlowNode for x |
|
||||
| test.py:39:19:39:19 | ControlFlowNode for x | test.py:12:15:12:15 | SSA variable x |
|
||||
| test.py:46:9:46:16 | ControlFlowNode for source() | test.py:48:23:48:23 | ControlFlowNode for x |
|
||||
| test.py:48:13:48:24 | ControlFlowNode for normalize() | test.py:49:14:49:14 | ControlFlowNode for y |
|
||||
| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | SSA variable x |
|
||||
| test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() |
|
||||
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:20:9:20:16 | ControlFlowNode for source() |
|
||||
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:28:9:28:16 | ControlFlowNode for source() |
|
||||
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:41:9:41:16 | ControlFlowNode for source() |
|
||||
| test_chaining.py:14:15:14:15 | SSA variable x | test_chaining.py:15:12:15:30 | ControlFlowNode for Attribute() |
|
||||
| test_chaining.py:15:12:15:30 | ControlFlowNode for Attribute() | test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() |
|
||||
| test_chaining.py:20:9:20:16 | ControlFlowNode for source() | test_chaining.py:21:19:21:19 | ControlFlowNode for x |
|
||||
| test_chaining.py:21:19:21:19 | ControlFlowNode for x | test_chaining.py:14:15:14:15 | SSA variable x |
|
||||
| test_chaining.py:28:9:28:16 | ControlFlowNode for source() | test_chaining.py:29:19:29:19 | ControlFlowNode for x |
|
||||
| test_chaining.py:29:19:29:19 | ControlFlowNode for x | test_chaining.py:14:15:14:15 | SSA variable x |
|
||||
| test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() | test_chaining.py:32:14:32:14 | ControlFlowNode for z |
|
||||
| test_chaining.py:41:9:41:16 | ControlFlowNode for source() | test_chaining.py:42:9:42:19 | ControlFlowNode for normpath() |
|
||||
| test_chaining.py:44:13:44:23 | ControlFlowNode for normpath() | test_chaining.py:45:14:45:14 | ControlFlowNode for z |
|
||||
nodes
|
||||
| path_injection.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| path_injection.py:10:14:10:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:15:12:15:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| path_injection.py:16:13:16:61 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:17:14:17:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
|
||||
| path_injection.py:24:12:24:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| path_injection.py:25:13:25:61 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| path_injection.py:28:14:28:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
|
||||
| path_injection.py:33:12:33:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| path_injection.py:34:13:34:61 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:12:15:12:15 | SSA variable x | semmle.label | SSA variable x |
|
||||
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:18:9:18:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test.py:19:10:19:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:24:9:24:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test.py:25:9:25:20 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
|
||||
| test.py:25:19:25:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:26:10:26:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:31:9:31:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test.py:33:14:33:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:38:9:38:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test.py:39:19:39:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:46:9:46:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test.py:48:13:48:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
|
||||
| test.py:48:23:48:23 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:49:14:49:14 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test_chaining.py:14:15:14:15 | SSA variable x | semmle.label | SSA variable x |
|
||||
| test_chaining.py:15:12:15:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test_chaining.py:20:9:20:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test_chaining.py:21:19:21:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test_chaining.py:28:9:28:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test_chaining.py:29:19:29:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
|
||||
| test_chaining.py:32:14:32:14 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
|
||||
| test_chaining.py:41:9:41:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
|
||||
| test_chaining.py:42:9:42:19 | ControlFlowNode for normpath() | semmle.label | ControlFlowNode for normpath() |
|
||||
| test_chaining.py:44:13:44:23 | ControlFlowNode for normpath() | semmle.label | ControlFlowNode for normpath() |
|
||||
| test_chaining.py:45:14:45:14 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
|
||||
#select
|
||||
| path_injection.py:10:14:10:44 | ControlFlowNode for Attribute() | path_injection.py:9:12:9:23 | ControlFlowNode for Attribute | path_injection.py:10:14:10:44 | ControlFlowNode for Attribute() | This path depends on $@. | path_injection.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| path_injection.py:17:14:17:18 | ControlFlowNode for npath | path_injection.py:15:12:15:23 | ControlFlowNode for Attribute | path_injection.py:17:14:17:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:15:12:15:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| path_injection.py:28:14:28:18 | ControlFlowNode for npath | path_injection.py:24:12:24:23 | ControlFlowNode for Attribute | path_injection.py:28:14:28:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:24:12:24:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| test.py:19:10:19:10 | ControlFlowNode for x | test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| test.py:26:10:26:10 | ControlFlowNode for y | test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| test.py:33:14:33:14 | ControlFlowNode for x | test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| test.py:49:14:49:14 | ControlFlowNode for y | test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| test_chaining.py:32:14:32:14 | ControlFlowNode for z | test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | test_chaining.py:32:14:32:14 | ControlFlowNode for z | This path depends on $@. | test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-022/PathInjection.ql
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
import os.path
|
||||
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/path1")
|
||||
def path_injection():
|
||||
path = request.args.get('path', '')
|
||||
f = open(os.path.join(os.getcwd(), path))
|
||||
|
||||
@app.route("/path2")
|
||||
def path_injection():
|
||||
# Normalized, but not checked
|
||||
path = request.args.get('path', '')
|
||||
npath = os.path.normpath(os.path.join(os.getcwd(), path))
|
||||
f = open(npath) # Path not found
|
||||
|
||||
SAFE = "/tmp/scratch_area/"
|
||||
|
||||
@app.route("/path3")
|
||||
def safe_path():
|
||||
# Normalized, but check doesn't reach open().
|
||||
path = request.args.get('path', '')
|
||||
npath = os.path.normpath(os.path.join(os.getcwd(), path))
|
||||
if npath.startswith(SAFE):
|
||||
pass
|
||||
f = open(npath) # Path not found
|
||||
|
||||
@app.route("/path4")
|
||||
def safe_path():
|
||||
# Normalized, and checked properly
|
||||
path = request.args.get('path', '')
|
||||
npath = os.path.normpath(os.path.join(os.getcwd(), path))
|
||||
if npath.startswith(SAFE):
|
||||
f = open(npath)
|
||||
@@ -1,49 +0,0 @@
|
||||
import os.path
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
def source():
|
||||
return request.args.get("path", "")
|
||||
|
||||
|
||||
def normalize(x):
|
||||
return os.path.normpath(x)
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def simple():
|
||||
x = source()
|
||||
open(x) # NOT OK
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def normalization():
|
||||
x = source()
|
||||
y = normalize(x)
|
||||
open(y) # NOT OK
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def check():
|
||||
x = source()
|
||||
if x.startswith("subfolder/"):
|
||||
open(x) # NOT OK
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def normalize_then_check():
|
||||
x = source()
|
||||
y = normalize(x)
|
||||
if y.startswith("subfolder/"):
|
||||
open(y) # OK
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def check_then_normalize():
|
||||
x = source()
|
||||
if x.startswith("subfolder/"):
|
||||
y = normalize(x)
|
||||
open(y) # NOT OK
|
||||
@@ -1,45 +0,0 @@
|
||||
import os.path
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
def source():
|
||||
return request.args.get("path", "")
|
||||
|
||||
|
||||
# Wrap normalization, so we can fool the chained configurations.
|
||||
# (Call context is lost at cross-over nodes.)
|
||||
def normalize(x):
|
||||
return os.path.normpath(x)
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def normalize_then_check():
|
||||
x = source()
|
||||
y = normalize(x) # <--- this call...
|
||||
if y.startswith("subfolder/"):
|
||||
open(y) # OK
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def normalize_check_normalize():
|
||||
x = source()
|
||||
y = normalize(x) # (...or this call...)
|
||||
if y.startswith("subfolder/"):
|
||||
z = normalize(y) # <--- ...can jump to here, resulting in FP
|
||||
open(z) # OK
|
||||
|
||||
|
||||
# The problem does not manifest if we simply define an alias
|
||||
normpath = os.path.normpath
|
||||
|
||||
|
||||
@app.route("/path")
|
||||
def normalize_check_normalize_alias():
|
||||
x = source()
|
||||
y = normpath(x)
|
||||
if y.startswith("subfolder/"):
|
||||
z = normpath(y)
|
||||
open(z) # OK
|
||||
@@ -1,31 +0,0 @@
|
||||
edges
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr |
|
||||
nodes
|
||||
| command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
#select
|
||||
| command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-078/CommandInjection.ql
|
||||
@@ -1,29 +0,0 @@
|
||||
import os
|
||||
import platform
|
||||
import popen2
|
||||
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/python2-specific")
|
||||
def python2_specific():
|
||||
"""
|
||||
These tests are mostly included to check for extra paths that can be generated if
|
||||
we can track flow into the implementation of a stdlib function, and then to another sink.
|
||||
See comment in query for more details.
|
||||
"""
|
||||
|
||||
files = request.args.get("files", "")
|
||||
os.popen2("ls " + files)
|
||||
os.popen3("ls " + files)
|
||||
os.popen4("ls " + files)
|
||||
|
||||
platform.popen("ls " + files)
|
||||
|
||||
popen2.popen2("ls " + files)
|
||||
popen2.popen3("ls " + files)
|
||||
popen2.popen4("ls " + files)
|
||||
popen2.Popen3("ls " + files)
|
||||
popen2.Popen4("ls " + files)
|
||||
@@ -1 +0,0 @@
|
||||
semmle-extractor-options: --max-import-depth=1 --lang=2
|
||||
@@ -1,42 +0,0 @@
|
||||
edges
|
||||
| command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | command_injection.py:25:23:25:25 | ControlFlowNode for cmd |
|
||||
| command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:39:15:39:21 | ControlFlowNode for command |
|
||||
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:40:15:40:21 | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:53:15:53:21 | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:54:14:54:20 | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:55:21:55:27 | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:56:27:56:33 | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:57:20:57:26 | ControlFlowNode for command |
|
||||
nodes
|
||||
| command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:25:23:25:25 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
|
||||
| command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:39:15:39:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:40:15:40:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| command_injection.py:53:15:53:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:54:14:54:20 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:55:21:55:27 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:56:27:56:33 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
| command_injection.py:57:20:57:26 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
|
||||
#select
|
||||
| command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:25:23:25:25 | ControlFlowNode for cmd | command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | command_injection.py:25:23:25:25 | ControlFlowNode for cmd | This command depends on $@. | command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:39:15:39:21 | ControlFlowNode for command | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:39:15:39:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:40:15:40:21 | ControlFlowNode for command | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:40:15:40:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:53:15:53:21 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:53:15:53:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:54:14:54:20 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:54:14:54:20 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:55:21:55:27 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:55:21:55:27 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:56:27:56:33 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:56:27:56:33 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
| command_injection.py:57:20:57:26 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:57:20:57:26 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-078/CommandInjection.ql
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/command1")
|
||||
def command_injection1():
|
||||
files = request.args.get('files', '')
|
||||
# Don't let files be `; rm -rf /`
|
||||
os.system("ls " + files)
|
||||
|
||||
|
||||
@app.route("/command2")
|
||||
def command_injection2():
|
||||
files = request.args.get('files', '')
|
||||
# Don't let files be `; rm -rf /`
|
||||
subprocess.Popen("ls " + files, shell=True)
|
||||
|
||||
|
||||
@app.route("/command3")
|
||||
def first_arg_injection():
|
||||
cmd = request.args.get('cmd', '')
|
||||
subprocess.Popen([cmd, "param1"])
|
||||
|
||||
|
||||
@app.route("/other_cases")
|
||||
def others():
|
||||
files = request.args.get('files', '')
|
||||
# Don't let files be `; rm -rf /`
|
||||
os.popen("ls " + files)
|
||||
|
||||
@app.route("/multiple")
|
||||
def multiple():
|
||||
command = request.args.get('command', '')
|
||||
# We should mark flow to both calls here, which conflicts with removing flow out of
|
||||
# a sink due to use-use flow.
|
||||
os.system(command)
|
||||
os.system(command)
|
||||
|
||||
|
||||
@app.route("/not-into-sink-impl")
|
||||
def not_into_sink_impl():
|
||||
"""When there is flow to a sink such as `os.popen(cmd)`, we don't want to highlight that there is also
|
||||
flow through the actual `popen` function to the internal call to `subprocess.Popen` -- we would usually
|
||||
see that flow since we extract the `os.py` file from the standard library.
|
||||
|
||||
os.popen implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/os.py#L974
|
||||
subprocess.call implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/subprocess.py#L341
|
||||
"""
|
||||
command = request.args.get('command', '')
|
||||
os.system(command)
|
||||
os.popen(command)
|
||||
subprocess.call(command)
|
||||
subprocess.check_call(command)
|
||||
subprocess.run(command)
|
||||
@@ -1,7 +0,0 @@
|
||||
edges
|
||||
| reflected_xss.py:8:18:8:29 | ControlFlowNode for Attribute | reflected_xss.py:9:26:9:53 | ControlFlowNode for BinaryExpr |
|
||||
nodes
|
||||
| reflected_xss.py:8:18:8:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| reflected_xss.py:9:26:9:53 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
#select
|
||||
| reflected_xss.py:9:26:9:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:8:18:8:29 | ControlFlowNode for Attribute | reflected_xss.py:9:26:9:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to $@. | reflected_xss.py:8:18:8:29 | ControlFlowNode for Attribute | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-079/ReflectedXss.ql
|
||||
@@ -1,15 +0,0 @@
|
||||
from flask import Flask, request, make_response, escape
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/unsafe")
|
||||
def unsafe():
|
||||
first_name = request.args.get("name", "")
|
||||
return make_response("Your name is " + first_name) # NOT OK
|
||||
|
||||
|
||||
@app.route("/safe")
|
||||
def safe():
|
||||
first_name = request.args.get("name", "")
|
||||
return make_response("Your name is " + escape(first_name)) # OK
|
||||
@@ -1,16 +0,0 @@
|
||||
edges
|
||||
| sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr |
|
||||
nodes
|
||||
| sql_injection.py:14:15:14:22 | SSA variable username | semmle.label | SSA variable username |
|
||||
| sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
| sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
|
||||
#select
|
||||
| sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | SSA variable username | a user-provided value |
|
||||
| sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | SSA variable username | a user-provided value |
|
||||
| sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | SSA variable username | a user-provided value |
|
||||
| sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | SSA variable username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | SSA variable username | a user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-089/SqlInjection.ql
|
||||
@@ -1,40 +0,0 @@
|
||||
"""This is adapted from ql/python/ql/test/query-tests\Security\CWE-089
|
||||
we now prefer to setup routing by flask
|
||||
"""
|
||||
|
||||
from django.db import connection, models
|
||||
from django.db.models.expressions import RawSQL
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
@app.route("/users/<username>")
|
||||
def show_user(username):
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
# BAD (but currently no custom query to find this)
|
||||
#
|
||||
# It is exposed to SQL injection (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#extra)
|
||||
# For example, using name = "; DROP ALL TABLES -- "
|
||||
# will result in SQL: SELECT * FROM name WHERE name = ''; DROP ALL TABLES -- ''
|
||||
#
|
||||
# This shouldn't be very widespread, since using a normal string will result in invalid SQL
|
||||
# Using name = "example", will result in SQL: SELECT * FROM name WHERE name = ''example''
|
||||
# which in MySQL will give a syntax error
|
||||
#
|
||||
# When testing this out locally, none of the queries worked against SQLite3, but I could use
|
||||
# the SQL injection against MySQL.
|
||||
User.objects.raw("SELECT * FROM users WHERE username = '%s'", (username,))
|
||||
@@ -1,13 +0,0 @@
|
||||
edges
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code |
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code |
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:10:10:10:12 | ControlFlowNode for cmd |
|
||||
nodes
|
||||
| code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| code_injection.py:7:10:7:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code |
|
||||
| code_injection.py:8:10:8:13 | ControlFlowNode for code | semmle.label | ControlFlowNode for code |
|
||||
| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
|
||||
#select
|
||||
| code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:7:10:7:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:8:10:8:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:23 | ControlFlowNode for Attribute | A user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-094/CodeInjection.ql
|
||||
@@ -1,10 +0,0 @@
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/code-execution")
|
||||
def code_execution():
|
||||
code = request.args.get("code")
|
||||
exec(code)
|
||||
eval(code)
|
||||
cmd = compile(code, "<filename>", "exec")
|
||||
exec(cmd)
|
||||
@@ -1,16 +0,0 @@
|
||||
edges
|
||||
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload |
|
||||
nodes
|
||||
| unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
|
||||
| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload |
|
||||
#select
|
||||
| unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | untrusted input |
|
||||
| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | untrusted input |
|
||||
| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | untrusted input |
|
||||
| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:26 | ControlFlowNode for Attribute | untrusted input |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security-new-dataflow/CWE-502/UnsafeDeserialization.ql
|
||||
@@ -1,21 +0,0 @@
|
||||
import flask
|
||||
import pickle
|
||||
import yaml
|
||||
import marshal
|
||||
|
||||
from yaml import SafeLoader
|
||||
|
||||
from flask import Flask, request
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
payload = request.args.get("payload")
|
||||
pickle.loads(payload) # NOT OK
|
||||
yaml.load(payload) # NOT OK
|
||||
yaml.load(payload, Loader=SafeLoader) # OK
|
||||
marshal.loads(payload) # NOT OK
|
||||
|
||||
import dill
|
||||
dill.loads(payload) # NOT OK
|
||||
Reference in New Issue
Block a user