public static function isSecretTaintSource($expr) { if ($expr instanceof PhpParser\Node\Expr\MethodCall || $expr instanceof PhpParser\Node\Expr\FuncCall || $expr instanceof PhpParser\Node\Expr\StaticCall) { // Check if it's an invocation of a tainting function. if (isset(TaintSource::$SecretTaintedFunctions[(string) $expr->name])) { return True; } // Check if any arguments is tainted. foreach ($expr->args as $arg) { if (TaintSource::isSecretTaintSource($arg)) { return True; } } } return False; }
function isTainted($expr, $tainted_variables, $user_taint) { print "Analyzing expression for taint.\n"; //print "The class is " . get_class($expr) . "\n"; if ($expr == null) { return False; } // Check if it's a pre-defined source of taint. if ($user_taint && TaintSource::isUserTaintSource($expr)) { return True; } else { if (!$user_taint && TaintSource::isSecretTaintSource($expr)) { return True; } } // For now, checking that the expression is either a function call of 'postGetSession' or a variable already in the tainted set. if ($expr instanceof PhpParser\Node\Expr\StaticCall || $expr instanceof PhpParser\Node\Expr\FuncCall || $expr instanceof PhpParser\Node\Expr\MethodCall) { print "Analyzing static call, function call or method call for taint\n"; $function_name = $expr->name; // The expression is tainted if it invokes a basic user input extraction function. if ($user_taint && (strcmp($function_name, 'postGetSessionInt') == 0 || strcmp($function_name, 'postGetSessionString') == 0)) { return true; } else { if (!$user_taint && strcmp($function_name, 'search') == 0) { // The expression is tainted if it invokes the secret-tainting function in openclinic. return true; } else { if (!$user_taint && strcmp($function_name, 'mysql_query') == 0) { // TODO: Fix this to only taint select statements. // The expression is tainted if it invokes the mysql_query predefined function. return true; } } } // The expression is tainted if one of the arguments is tainted. foreach ($expr->args as $arg) { if (isTainted($arg->value, $tainted_variables, $user_taint)) { return true; } } // The expression is tainted if it is a method call over a tainted expression. if ($expr instanceof PhpParser\Node\Expr\MethodCall && isTainted($expr->var, $tainted_variables, $user_taint)) { return true; } } else { if ($expr instanceof PhpParser\Node\Expr\Variable) { print "Analyzing variable for taint : " . $expr->name . "\n"; return $tainted_variables->contains($expr->name); } else { if ($expr instanceof PhpParser\Node\Expr\BinaryOp) { print "Analyzing binary op for taint.\n"; return isTainted($expr->left, $tainted_variables, $user_taint) || isTainted($expr->right, $tainted_variables, $user_taint); } else { if ($expr instanceof PhpParser\Node\Expr\ArrayDimFetch) { print "Analyzing array fetch expression for taint.\n"; // The expression is user tainted if it invokes a basic predefined extraction // from the '_GET' or '_POST' arrays. if ($user_taint && (strcmp($expr->var->name, '_GET') == 0 || strcmp($expr->var->name, '_POST') == 0)) { return true; } return isTainted($expr->var, $tainted_variables, $user_taint) || isTainted($expr->dim, $tainted_variables, $user_taint); } } } } return false; }