-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathunprotected_setter.py
71 lines (63 loc) · 2.78 KB
/
unprotected_setter.py
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
from slither.core.cfg.node import NodeType
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
class UnprotectedSetter(AbstractDetector):
"""
Sees if contract contains a setter, that changes contract paramater without modifier protection or access control inside the function
"""
ARGUMENT = "pess-unprotected-setter" # slither will launch the detector with slither.py --detect mydetector
HELP = "Contract critical storage parameters might be changed by anyone"
IMPACT = DetectorClassification.HIGH
CONFIDENCE = DetectorClassification.MEDIUM
WIKI = "https://github.com/pessimistic-io/slitherin/blob/master/docs/unprotected_setter.md"
WIKI_TITLE = "Unprotected Setter"
WIKI_DESCRIPTION = "Usually all setters must be protected with access control"
WIKI_EXPLOIT_SCENARIO = "-"
WIKI_RECOMMENDATION = "Add access control"
def is_setter(self, fun, params=None):
if not params:
params = fun.parameters
for n in fun.nodes:
if n.type == NodeType.EXPRESSION:
for v in n.state_variables_written:
lr = str(n.expression).split(" = ")
if len(lr) > 1:
left = lr[0]
right = lr[1]
for p in params:
if p.name:
if "." in left:
continue
if "[" in left:
continue
if right == str(p):
return left
return None
def has_access_control(self, fun):
for m in fun.modifiers:
if m.name in ["initializer", "onlyOwner"] or m.name.startswith("only"):
return True
if fun.visibility in ["internal", "private"]:
return True
return fun.is_protected()
def _detect(self):
res = []
for contract in self.compilation_unit.contracts_derived:
if contract.is_interface:
continue
for f in contract.functions:
if not self.has_access_control(f):
x = self.is_setter(f)
if x != None:
res.append(
self.generate_result(
[
"Function",
" ",
f,
" is a non-protected setter ",
x,
" is written" "\n",
]
)
)
return res