Skip to content

Commit d245db5

Browse files
committed
Python: Model file threat-model
1 parent 66f389a commit d245db5

File tree

4 files changed

+31
-12
lines changed

4 files changed

+31
-12
lines changed

python/ql/lib/semmle/python/frameworks/Stdlib.model.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ extensions:
1717

1818
# if no argument is given, the default is to use sys.argv[1:]
1919
- ['argparse.ArgumentParser', 'Member[parse_args,parse_known_args].WithArity[0].ReturnValue', 'commandargs']
20+
21+
- ['os', 'Member[read].ReturnValue', 'file']
2022
- addsTo:
2123
pack: codeql/python-all
2224
extensible: summaryModel

python/ql/lib/semmle/python/frameworks/Stdlib.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,13 +1499,17 @@ module StdlibPrivate {
14991499
* See https://docs.python.org/3/library/functions.html#open
15001500
*/
15011501
private class OpenCall extends FileSystemAccess::Range, Stdlib::FileLikeObject::InstanceSource,
1502-
DataFlow::CallCfgNode
1502+
ThreatModelSource::Range, DataFlow::CallCfgNode
15031503
{
15041504
OpenCall() { this = getOpenFunctionRef().getACall() }
15051505

15061506
override DataFlow::Node getAPathArgument() {
15071507
result in [this.getArg(0), this.getArgByName("file")]
15081508
}
1509+
1510+
override string getThreatModel() { result = "file" }
1511+
1512+
override string getSourceType() { result = "open()" }
15091513
}
15101514

15111515
/**

python/ql/test/library-tests/frameworks/stdlib/FileSystemAccess.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@
55
import tempfile
66
import shutil
77

8-
open("file") # $ getAPathArgument="file"
9-
open(file="file") # $ getAPathArgument="file"
8+
open("file") # $ getAPathArgument="file" threatModelSource[file]=open(..)
9+
open(file="file") # $ getAPathArgument="file" threatModelSource[file]=open(..)
1010

1111
o = open
1212

13-
o("file") # $ getAPathArgument="file"
14-
o(file="file") # $ getAPathArgument="file"
13+
o("file") # $ getAPathArgument="file" threatModelSource[file]=o(..)
14+
o(file="file") # $ getAPathArgument="file" threatModelSource[file]=o(..)
1515

1616

17-
builtins.open("file") # $ getAPathArgument="file"
18-
builtins.open(file="file") # $ getAPathArgument="file"
17+
builtins.open("file") # $ getAPathArgument="file" threatModelSource[file]=builtins.open(..)
18+
builtins.open(file="file") # $ getAPathArgument="file" threatModelSource[file]=builtins.open(..)
1919

2020

21-
io.open("file") # $ getAPathArgument="file"
22-
io.open(file="file") # $ getAPathArgument="file"
21+
io.open("file") # $ getAPathArgument="file" threatModelSource[file]=io.open(..)
22+
io.open(file="file") # $ getAPathArgument="file" threatModelSource[file]=io.open(..)
2323
io.open_code("file") # $ getAPathArgument="file"
2424
io.FileIO("file") # $ getAPathArgument="file"
2525

26-
f = open("path") # $ getAPathArgument="path"
26+
f = open("path") # $ getAPathArgument="path" threatModelSource[file]=open(..)
2727
f.write("foo") # $ getAPathArgument="path" fileWriteData="foo"
2828
lines = ["foo"]
2929
f.writelines(lines) # $ getAPathArgument="path" fileWriteData=lines
@@ -87,8 +87,8 @@ def test_fspath():
8787
os.fspath(path=TAINTED_STRING), # $ tainted
8888
)
8989

90-
os.open("path", os.O_RDONLY) # $ getAPathArgument="path"
91-
os.open(path="path", flags=os.O_RDONLY) # $ getAPathArgument="path"
90+
os.open("path", os.O_RDONLY) # $ getAPathArgument="path" SPURIOUS: threatModelSource[file]=os.open(..)
91+
os.open(path="path", flags=os.O_RDONLY) # $ getAPathArgument="path" SPURIOUS: threatModelSource[file]=os.open(..)
9292

9393
os.access("path", os.R_OK) # $ getAPathArgument="path"
9494
os.access(path="path", mode=os.R_OK) # $ getAPathArgument="path"

python/ql/test/library-tests/frameworks/stdlib/threat_models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@
4848
input(), # $ tainted threatModelSource[stdin]=input()
4949
)
5050

51+
########################################
52+
# reading data from files
53+
########################################
54+
55+
ensure_tainted(
56+
open("foo"), # $ tainted threatModelSource[file]=open(..) getAPathArgument="foo"
57+
open("foo").read(), # $ tainted threatModelSource[file]=open(..) getAPathArgument="foo"
58+
open("foo").readline(), # $ tainted threatModelSource[file]=open(..) getAPathArgument="foo"
59+
open("foo").readlines(), # $ tainted threatModelSource[file]=open(..) getAPathArgument="foo"
60+
61+
os.read(os.open("foo"), 1024), # $ tainted threatModelSource[file]=os.read(..) SPURIOUS: threatModelSource[file]=os.open(..) getAPathArgument="foo"
62+
)
63+
5164
########################################
5265
# socket
5366
########################################

0 commit comments

Comments
 (0)