예제 #1
0
파일: util.php 프로젝트: nikic/phan
function var_taint_check($file, $node, string $current_scope) : bool
{
    global $scope, $tainted_by;
    static $tainted = ['_GET' => '*', '_POST' => '*', '_COOKIE' => '*', '_REQUEST' => '*', '_FILES' => '*', '_SERVER' => ['QUERY_STRING', 'HTTP_HOST', 'HTTP_USER_AGENT', 'HTTP_ACCEPT_ENCODING', 'HTTP_ACCEPT_LANGUAGE', 'REQUEST_URI', 'PHP_SELF', 'argv']];
    if (!$node instanceof \ast\Node) {
        return false;
    }
    $parent = $node;
    while ($node instanceof \ast\Node && $node->kind != \ast\AST_VAR && $node->kind != \ast\AST_MAGIC_CONST) {
        $parent = $node;
        if (empty($node->children[0])) {
            break;
        }
        $node = $node->children[0];
    }
    if ($parent->kind == \ast\AST_DIM) {
        if ($node->children[0] instanceof \ast\Node) {
            // $$var or something else dynamic is going on, not direct access to a suspivious var
            return false;
        }
        foreach ($tainted as $name => $index) {
            if ($node->children[0] === $name) {
                if ($index == '*') {
                    return true;
                }
                if ($parent->children[1] instanceof \ast\Node) {
                    // Dynamic index, give up
                    return false;
                }
                if (in_array($parent->children[1], $index, true)) {
                    return true;
                }
            }
        }
    } else {
        if ($parent->kind == \ast\AST_VAR && !$parent->children[0] instanceof \ast\Node) {
            if (empty($scope[$current_scope]['vars'][$parent->children[0]])) {
                if (!superglobal($parent->children[0])) {
                    Log::err(Log::EVAR, "Variable \${$parent->children[0]} is not defined", $file, $parent->lineno);
                }
            } else {
                if (!empty($scope[$current_scope]['vars'][$parent->children[0]]['tainted'])) {
                    $tainted_by = $scope[$current_scope]['vars'][$parent->children[0]]['tainted_by'];
                    return true;
                }
            }
        }
    }
    return false;
}
예제 #2
0
function var_type($file, $node, $current_scope, &$taint, $check_var_exists = true)
{
    global $scope, $tainted_by;
    // Check for $$var or ${...} (whose idea was that anyway?)
    if ($node->children[0] instanceof \ast\Node && ($node->children[0]->kind == \ast\AST_VAR || $node->children[0]->kind == \ast\AST_BINARY_OP)) {
        return "mixed";
    }
    if (empty($scope[$current_scope]['vars'][$node->children[0]])) {
        if ($check_var_exists) {
            if (!superglobal($node->children[0])) {
                Log::err(Log::EVAR, "Variable \${$node->children[0]} is not defined", $file, $node->lineno);
            }
        }
    } else {
        if (!empty($scope[$current_scope]['vars'][$node->children[0]]['tainted'])) {
            $tainted_by = $scope[$current_scope]['vars'][$node->children[0]]['tainted_by'];
            $taint = true;
        }
        return $scope[$current_scope]['vars'][$node->children[0]]['type'] ?? '';
    }
    return '';
}