-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathtest.py
More file actions
136 lines (98 loc) · 4.2 KB
/
test.py
File metadata and controls
136 lines (98 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from not_found import get_passwd # $ SensitiveDataSource=password
from not_found import account_id # $ SensitiveDataSource=id
def get_password():
pass
def get_secret():
pass
def fetch_certificate():
pass
def encrypt_password(pwd):
pass
get_password() # $ SensitiveDataSource=password
get_passwd() # $ SensitiveDataSource=password
get_secret() # $ SensitiveDataSource=secret
fetch_certificate() # $ SensitiveDataSource=certificate
account_id() # $ SensitiveDataSource=id
safe_to_store = encrypt_password(pwd)
f = get_password
f() # $ SensitiveDataSource=password
# more tests of functions we don't have definition for
x = unkown_func_not_even_imported_get_password() # $ SensitiveDataSource=password
print(x) # $ SensitiveUse=password
f = get_passwd
x = f()
print(x) # $ SensitiveUse=password
import not_found
f = not_found.get_passwd # $ SensitiveDataSource=password
x = f()
print(x) # $ SensitiveUse=password
# some prefixes makes us ignore it as a source
not_found.isSecret
not_found.is_secret
def my_func(non_sensitive_name):
x = non_sensitive_name()
print(x) # $ SensitiveUse=password
f = not_found.get_passwd # $ SensitiveDataSource=password
my_func(f)
# attributes
foo = ObjectFromDatabase()
foo.secret # $ SensitiveDataSource=secret
foo.username # $ SensitiveDataSource=id
getattr(foo, "password") # $ SensitiveDataSource=password
x = "password"
getattr(foo, x) # $ SensitiveDataSource=password
# based on variable/parameter names
def my_func(password): # $ SensitiveDataSource=password
print(password) # $ SensitiveUse=password
# FP where the `cert` in `uncertainty` makes us treat it like a certificate
# https://github.com/github/codeql/issues/9632
def my_other_func(uncertainty):
print(uncertainty)
password = some_function() # $ SensitiveDataSource=password
print(password) # $ SensitiveUse=password
for password in some_function2(): # $ SensitiveDataSource=password
print(password) # $ SensitiveUse=password
with some_function3() as password: # $ SensitiveDataSource=password
print(password) # $ SensitiveUse=password
# Special handling of lookups of sensitive properties
request.args["password"], # $ SensitiveDataSource=password
request.args.get("password") # $ SensitiveDataSource=password
x = "password"
request.args.get(x) # $ SensitiveDataSource=password
# I don't think handling `getlist` is super important, just included it to show what we don't handle
request.args.getlist("password")[0] # $ MISSING: SensitiveDataSource=password
from not_found import password2 as foo # $ SensitiveDataSource=password
print(foo) # $ SensitiveUse=password
# ------------------------------------------------------------------------------
# cross-talk between different calls
# ------------------------------------------------------------------------------
# Case 1: providing name as argument
_configuration = {"sleep_timer": 5, "mysql_password": "1234"}
def get_config(key):
# Treating this as a SensitiveDataSource is questionable, since that will result in
# _all_ calls to `get_config` being treated as giving sensitive data
return _configuration[key]
foo = get_config("mysql_password")
print(foo) # $ MISSING: SensitiveUse=password
bar = get_config("sleep_timer")
print(bar)
# Case 2: Providing function as argument
def call_wrapper(func):
print("Will call", func)
# Treating this as a SensitiveDataSource is questionable, since that will result in
# _all_ calls to `call_wrapper` being treated as giving sensitive data
return func() # $ SensitiveDataSource=password
foo = call_wrapper(get_password)
print(foo) # $ SensitiveUse=password
harmless = lambda: "bar"
bar = call_wrapper(harmless)
print(bar) # $ SPURIOUS: SensitiveUse=password
# ------------------------------------------------------------------------------
# cross-talk in dictionary.
# ------------------------------------------------------------------------------
from unknown_settings import password # $ SensitiveDataSource=password
print(password) # $ SensitiveUse=password
_config = {"sleep_timer": 5, "mysql_password": password}
# since we have taint-step from store of `password`, we will consider any item in the
# dictionary to be a password :(
print(_config["sleep_timer"]) # $ SPURIOUS: SensitiveUse=password