diogocp/ssoft-project

Handle "backward" flows in loops (slice 10)

Closed this issue · 0 comments

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:

  1. Evaluate the loop test (they can have side effects).
  2. Make a copy of the environment (env_loop = copy.deepcopy(env)).
  3. Evaluate the loop body (just once) in environment env_loop.
  4. Evaluate the loop condition in environment env_loop.
  5. Make env equal to the union of env and env_loop (i.e. anything tainted in either env or env_loop becomes tainted in env).
  6. Repeat steps 3-5 as many times as the number of statements in the body of the loop.