5

我的脚本:

$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
    if (isset($secret) || !empty($secret)) {
        if (file_exists(ROOT . '/intl/codes/' . $secret)) {
            unlink(ROOT . '/intl/codes/' . $secret);
            $trusted = 'yes';
        } else {
            $trusted = 'no';
        }
    }
//$_POST['register'] register details...
}
  1. 还有另一种方法(更简单等)吗?
  2. 如果文件夹$secret中不存在,它会产生如何摆脱它?/codes/Warning: unlink Is a directory
  3. 为什么即使文件不存在也$trusted总是给出?yes
4

5 回答 5

6

要删除目录,您应该使用rmdir()而不是unlink().

$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
    if (!empty($secret)) {
        if(file_exists(ROOT . '/intl/codes/' . $secret)) {
            rmdir(ROOT . '/intl/codes/' . $secret);
            $trusted = 'yes';
        } else {
            $trusted = 'no';
        }
    }
    //$_POST['register'] register details...
}

虽然,这里存在严重的安全隐患!如果你check_input()没有正确清理$secret,你可以rmdir('/intl/codes/../')删除 /intl/。尝试这样的事情:

$allowed = ROOT. '/intl/codes/';
$path = realpath($allowed . check_input($_GET['secret']));

if(strpos($path, $allowed) === 0) {  //Check that $path is within allowed directory
    if(is_dir($path)) {
        rmdir($path);
    } else if(file_exists($path)) {
        unlink($path);
    } else {
        echo "File/folder not found";
    }
} else {
    echo "Untrusted user tried to delete outside of allowed directory";
}
于 2012-01-08T08:35:46.567 回答
1
  1. 您也可以使用 just if (!empty($secret))- empty()returnTRUE作为NULL价值。

  2. 用于if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret))检查您的文件是否不是目录并消除该警告。如果您仍想删除目录,请使用rmdir()函数。

  3. file_exists()也返回TRUE目录。is_dir()因此,正如我之前所说,您还应该检查参数是否是带有 的目录。

于 2012-01-08T08:38:31.683 回答
1
    if (file_exists(ROOT . '/intl/codes/' . $secret)) {
        unlink(ROOT . '/intl/codes/' . $secret);
        $trusted = 'yes';
    } else {
        $trusted = 'no';
    }

还有另一种方法(更简单等)吗?

不,唯一的方法是使用file_exists

如果 /codes/ 文件夹中不存在 $secret,则会产生警告:unlink Is a directory 如何摆脱它?

它似乎$secret指向一个目录。执行路径到达,unlink因为if部分返回true。所以它存在。要删除目录,请使用rmdir()

为什么即使文件不存在 $trusted 总是给出肯定的?

因为unlink删除它并设置$trustedyes. 当您在删除后搜索时,您会看到它不存在但$trusted包含yes

于 2012-01-08T08:40:08.950 回答
1

显然你$secret是一个空字符串,但它通过了你的isset()测试。所以目录 ROOT . '/intl/codes/'确实存在(因此通过了file_exists()检查),但你不能unlink()目录(这也不是你的意图)。

确保你有一些非空的东西$_GET['secret']并验证你的check_input()功能。

PS您可能应该删除isset($secret)部分条件。!empty($secret)在这里就足够了,它将修复您的脚本。

于 2012-01-08T08:40:15.830 回答
1

如php文档所述file_exists()

Checks whether a file or directory exists

我对您的问题 #3 的唯一猜测是:您检查文件是否存在并且确实存在。只是,它不是文件,它是目录。

至于#2,也如错误消息所述,您可以执行以下操作:

$file_to_check = 根。'/intl/codes/' 。$秘密;

if (file_exists($file_to_check)) {
    if( !is_dir( $file_to_check ) )
        unlink($file_to_check);
    else
        rmdir( $file_to_check );
    $trusted = 'yes';
}

对于你的#1问题,你可能会做这样的事情:

$secret = input_get($_GET['secret']);
if(isset($_POST['register']) && !empty($secret)) {

    $file_to_check = ROOT . '/intl/codes/' . $secret;
    if (file_exists($file_to_check)) {
        if( !is_dir( $file_to_check ) )
            unlink($file_to_check);
        else
            rmdir( $file_to_check );
        $trusted = 'yes';
    } else {
        $trusted = 'no';
    }
}

function input_get($key, $default = ""){

    if(!isset($_GET[$key])){
        return $default;
    } else {
        //do input cleanup first, if you want
        return $_GET[$key];
    }
}

一点解释:

  1. 我不知道是什么check_input(),所以我为$_GET[]被调用创建了包装函数input_get()。它消除了需要做的事情isset(),也不需要填写默认值。
  2. 我将ROOT . '/intl/codes/' . $secret;变量放入变量$file_to_check中,这样您就不必一次又一次地键入它。
于 2012-01-08T08:48:31.513 回答