Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0a589be

Browse files
committed
Python: Add inline test of MaD sinks
This enables us to keep the framework modeling tests under `/frameworks` folder I had hoped to use `mad-sink[<kind>]` syntax, but that was not allowed :( Maybe it oculd be allowed in the future, but for now I'll stick with the more ugly solution of `mad-sink__<kind>`
1 parent 6ae5ef9 commit 0a589be

4 files changed

Lines changed: 79 additions & 27 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import python
2+
private import semmle.python.dataflow.new.DataFlow
3+
private import semmle.python.dataflow.new.internal.PrintNode
4+
private import semmle.python.frameworks.data.ModelsAsData
5+
// need to import Frameworks to get the actual modeling imported
6+
private import semmle.python.Frameworks
7+
// this improt needs to be public to get the query predicates propagated to the actual test files
8+
import TestUtilities.InlineExpectationsTest
9+
10+
class MadSinkTest extends InlineExpectationsTest {
11+
MadSinkTest() { this = "MadSinkTest" }
12+
13+
override string getARelevantTag() {
14+
exists(string kind | exists(ModelOutput::getASinkNode(kind)) |
15+
result = "mad-sink__" + kind
16+
)
17+
}
18+
19+
override predicate hasActualResult(Location location, string element, string tag, string value) {
20+
exists(location.getFile().getRelativePath()) and
21+
exists(DataFlow::Node sink, string kind |
22+
sink = ModelOutput::getASinkNode(kind).getARhs() and
23+
location = sink.getLocation() and
24+
element = sink.toString() and
25+
value = prettyNodeForInlineTest(sink) and
26+
tag = "mad-sink__" + kind
27+
)
28+
}
29+
}
30+
31+
class MadSourceTest extends InlineExpectationsTest {
32+
MadSourceTest() { this = "MadSourceTest" }
33+
34+
override string getARelevantTag() {
35+
exists(string kind | exists(ModelOutput::getASourceNode(kind)) |
36+
result = "mad-source__" + kind
37+
)
38+
}
39+
40+
override predicate hasActualResult(Location location, string element, string tag, string value) {
41+
exists(location.getFile().getRelativePath()) and
42+
exists(DataFlow::Node source, string kind |
43+
source = ModelOutput::getASourceNode(kind).getAnImmediateUse() and
44+
location = source.getLocation() and
45+
element = source.toString() and
46+
value = prettyNodeForInlineTest(source) and
47+
tag = "mad-source__" + kind
48+
)
49+
}
50+
}

python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected

Whitespace-only changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import python
2+
import experimental.meta.MaDTest

python/ql/test/library-tests/frameworks/asyncpg/test.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ async def test_connection():
77
try:
88
# The file-like object is passed in as a keyword-only argument.
99
# See https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.copy_from_query
10-
await conn.copy_from_query("sql", output="filepath") # $ getSql="sql" getAPathArgument="filepath"
11-
await conn.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ getSql="sql" getAPathArgument="filepath"
10+
await conn.copy_from_query("sql", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__file-access="filepath" getAPathArgument="filepath"
11+
await conn.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__file-access="filepath" getAPathArgument="filepath"
1212

13-
await conn.copy_from_table("table", output="filepath") # $ getAPathArgument="filepath"
14-
await conn.copy_to_table("table", source="filepath") # $ getAPathArgument="filepath"
13+
await conn.copy_from_table("table", output="filepath") # $ mad-sink__file-access="filepath" getAPathArgument="filepath"
14+
await conn.copy_to_table("table", source="filepath") # $ mad-sink__file-access="filepath" getAPathArgument="filepath"
1515

16-
await conn.execute("sql") # $ getSql="sql"
17-
await conn.executemany("sql") # $ getSql="sql"
18-
await conn.fetch("sql") # $ getSql="sql"
19-
await conn.fetchrow("sql") # $ getSql="sql"
20-
await conn.fetchval("sql") # $ getSql="sql"
16+
await conn.execute("sql") # $ mad-sink__sql-injection="sql"
17+
await conn.executemany("sql") # $ mad-sink__sql-injection="sql"
18+
await conn.fetch("sql") # $ mad-sink__sql-injection="sql"
19+
await conn.fetchrow("sql") # $ mad-sink__sql-injection="sql"
20+
await conn.fetchval("sql") # $ mad-sink__sql-injection="sql"
2121

2222
finally:
2323
await conn.close()
@@ -27,9 +27,9 @@ async def test_prepared_statement():
2727
conn = await asyncpg.connect()
2828

2929
try:
30-
pstmt = await conn.prepare("psql") # $ getSql="psql"
31-
pstmt.executemany()
32-
pstmt.fetch()
30+
pstmt = await conn.prepare("psql") # $ mad-sink__sql-injection="psql"
31+
pstmt.executemany()
32+
pstmt.fetch()
3333
pstmt.fetchrow()
3434
pstmt.fetchval()
3535

@@ -46,7 +46,7 @@ async def test_cursor():
4646
cursor = await conn.cursor("sql") # $ getSql="sql" constructedSql="sql"
4747
await cursor.fetch()
4848

49-
pstmt = await conn.prepare("psql") # $ getSql="psql"
49+
pstmt = await conn.prepare("psql") # $ mad-sink__sql-injection="psql"
5050
pcursor = await pstmt.cursor() # $ getSql="psql"
5151
await pcursor.fetch()
5252

@@ -69,37 +69,37 @@ async def test_connection_pool():
6969
pool = await asyncpg.create_pool()
7070

7171
try:
72-
await pool.copy_from_query("sql", output="filepath") # $ getSql="sql" getAPathArgument="filepath"
73-
await pool.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ getSql="sql" getAPathArgument="filepath"
74-
await pool.copy_from_table("table", output="filepath") # $ getAPathArgument="filepath"
75-
await pool.copy_to_table("table", source="filepath") # $ getAPathArgument="filepath"
72+
await pool.copy_from_query("sql", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__file-access="filepath" getAPathArgument="filepath"
73+
await pool.copy_from_query("sql", "arg1", "arg2", output="filepath") # $ mad-sink__sql-injection="sql" mad-sink__file-access="filepath" getAPathArgument="filepath"
74+
await pool.copy_from_table("table", output="filepath") # $ mad-sink__file-access="filepath" getAPathArgument="filepath"
75+
await pool.copy_to_table("table", source="filepath") # $ mad-sink__file-access="filepath" getAPathArgument="filepath"
7676

77-
await pool.execute("sql") # $ getSql="sql"
78-
await pool.executemany("sql") # $ getSql="sql"
79-
await pool.fetch("sql") # $ getSql="sql"
80-
await pool.fetchrow("sql") # $ getSql="sql"
81-
await pool.fetchval("sql") # $ getSql="sql"
77+
await pool.execute("sql") # $ mad-sink__sql-injection="sql"
78+
await pool.executemany("sql") # $ mad-sink__sql-injection="sql"
79+
await pool.fetch("sql") # $ mad-sink__sql-injection="sql"
80+
await pool.fetchrow("sql") # $ mad-sink__sql-injection="sql"
81+
await pool.fetchval("sql") # $ mad-sink__sql-injection="sql"
8282

8383
async with pool.acquire() as conn:
84-
await conn.execute("sql") # $ getSql="sql"
84+
await conn.execute("sql") # $ mad-sink__sql-injection="sql"
8585

8686
conn = await pool.acquire()
8787
try:
88-
await conn.fetch("sql") # $ getSql="sql"
88+
await conn.fetch("sql") # $ mad-sink__sql-injection="sql"
8989
finally:
9090
await pool.release(conn)
9191

9292
finally:
9393
await pool.close()
9494

9595
async with asyncpg.create_pool() as pool:
96-
await pool.execute("sql") # $ getSql="sql"
96+
await pool.execute("sql") # $ mad-sink__sql-injection="sql"
9797

9898
async with pool.acquire() as conn:
99-
await conn.execute("sql") # $ getSql="sql"
99+
await conn.execute("sql") # $ mad-sink__sql-injection="sql"
100100

101101
conn = await pool.acquire()
102102
try:
103-
await conn.fetch("sql") # $ getSql="sql"
103+
await conn.fetch("sql") # $ mad-sink__sql-injection="sql"
104104
finally:
105105
await pool.release(conn)

0 commit comments

Comments
 (0)