Handle "backward" flows in loops (slice 10)
Closed this issue · 0 comments
diogocp commented
Here is slice 10 (simplified):
$tainted = $_POST['nis'];
while ($indarg == "") {
$query = $arg3;
$arg3 = $arg2;
$arg2 = $arg1;
$arg1 = $tainted;
$indarg = substr($indarg, 1);
}
$q=mysql_query($query);
There is a flow from $tainted
to $query
, but it is hard to detect because it takes 4 iterations of the loop for the information to propagate.
How can we solve this? One idea would be to evaluate the loop as many times as the number of statements in the body. That would work for this slice, but it is unsound, because a different loop could do the opposite trick: a tainted variable becomes untainted if you loop 4 times.
A safer (and sound?) approach would be as follows:
- Evaluate the loop test (they can have side effects).
- Make a copy of the environment (
env_loop = copy.deepcopy(env)
). - Evaluate the loop body (just once) in environment
env_loop
. - Evaluate the loop condition in environment
env_loop
. - Make
env
equal to the union ofenv
andenv_loop
(i.e. anything tainted in eitherenv
orenv_loop
becomes tainted inenv
). - Repeat steps 3-5 as many times as the number of statements in the body of the loop.