API taint changes:

- Change taint.state_variables -> all_variables (track also slithIR variables)
 - Remove taint.calls (include in all_variables)
pull/81/head
Josselin 6 years ago
parent 62d73f212d
commit dabffe3630
  1. 24
      slither/analyses/taint/all_variables.py
  2. 58
      slither/analyses/taint/calls.py

@ -10,10 +10,10 @@ from slither.core.declarations.solidity_variables import \
SolidityVariableComposed SolidityVariableComposed
from slither.core.variables.state_variable import StateVariable from slither.core.variables.state_variable import StateVariable
from slither.slithir.operations import Index, Member, OperationWithLValue from slither.slithir.operations import Index, Member, OperationWithLValue
from slither.slithir.variables import ReferenceVariable, TemporaryVariable from slither.slithir.variables import ReferenceVariable#, TemporaryVariable
from .common import iterate_over_irs from .common import iterate_over_irs
KEY = 'TAINT_STATE_VARIABLES' KEY = 'TAINT_ALL_VARIABLES'
def _transfer_func(ir, read, refs, taints): def _transfer_func(ir, read, refs, taints):
if isinstance(ir, OperationWithLValue) and any(var_read in taints for var_read in read): if isinstance(ir, OperationWithLValue) and any(var_read in taints for var_read in read):
@ -33,7 +33,7 @@ def _visit_node(node, visited):
taints = iterate_over_irs(node.irs, _transfer_func, taints) taints = iterate_over_irs(node.irs, _transfer_func, taints)
taints = [v for v in taints if not isinstance(v, (TemporaryVariable, ReferenceVariable))] # taints = [v for v in taints if not isinstance(v, (TemporaryVariable, ReferenceVariable))]
node.function.slither.context[KEY] = list(set(taints)) node.function.slither.context[KEY] = list(set(taints))
@ -59,12 +59,14 @@ def _run_taint(slither, initial_taint):
slither.context[KEY] = list(set(slither.context[KEY] + function.parameters)) slither.context[KEY] = list(set(slither.context[KEY] + function.parameters))
_visit_node(function.entry_point, []) _visit_node(function.entry_point, [])
slither.context[KEY] = [v for v in prev_taints if isinstance(v, StateVariable)] slither.context[KEY] = prev_taints # [v for v in prev_taints if isinstance(v, StateVariable)]
def run_taint(slither, initial_taint=None): def run_taint(slither, initial_taint=None):
if initial_taint is None: if initial_taint is None:
initial_taint = [SolidityVariableComposed('msg.sender')] initial_taint = [SolidityVariableComposed('msg.sender')]
initial_taint += [SolidityVariableComposed('msg.value')] initial_taint += [SolidityVariableComposed('msg.value')]
initial_taint += [SolidityVariableComposed('msg.data')]
initial_taint += [SolidityVariableComposed('tx.origin')]
if KEY not in slither.context: if KEY not in slither.context:
_run_taint(slither, initial_taint) _run_taint(slither, initial_taint)
@ -80,3 +82,17 @@ def get_taint(slither, initial_taint=None):
""" """
run_taint(slither, initial_taint) run_taint(slither, initial_taint)
return slither.context[KEY] return slither.context[KEY]
def is_tainted(slither, variable):
"""
Returns if the variable is tainted by inputs
Args:
slither
variable (Variable)
Returns:
bool
"""
if KEY not in slither.context:
run_taint(slither)
return variable in slither.context[KEY]

@ -1,58 +0,0 @@
"""
Compute taint on call
use taint from state_variable
call from slithIR with a taint set to yes means its destination is tainted
"""
from slither.analyses.taint.state_variables import get_taint as get_taint_state
from slither.core.declarations import SolidityVariableComposed
from slither.slithir.operations import (HighLevelCall, Index, LowLevelCall,
Member, OperationWithLValue, Send,
Transfer)
from slither.slithir.variables import ReferenceVariable
from .common import iterate_over_irs
KEY = 'TAINT_CALL_DESTINATION'
def _transfer_func(ir, read, refs, taints):
if isinstance(ir, OperationWithLValue) and any(var_read in taints for var_read in read):
taints += [ir.lvalue]
lvalue = ir.lvalue
while isinstance(lvalue, ReferenceVariable):
taints += [refs[lvalue]]
lvalue = refs[lvalue]
if isinstance(ir, (HighLevelCall, LowLevelCall, Transfer, Send)):
if ir.destination in taints:
ir.context[KEY] = True
return taints
def _visit_node(node, visited, taints):
if node in visited:
return
visited += [node]
taints = iterate_over_irs(node.irs, _transfer_func, taints)
for son in node.sons:
_visit_node(son, visited, taints)
def _run_taint(slither, initial_taint):
if KEY in slither.context:
return
for contract in slither.contracts:
for function in contract.functions:
if not function.is_implemented:
continue
_visit_node(function.entry_point, [], initial_taint + function.parameters)
def run_taint(slither):
initial_taint = get_taint_state(slither)
initial_taint += [SolidityVariableComposed('msg.sender')]
if KEY not in slither.context:
_run_taint(slither, initial_taint)
Loading…
Cancel
Save