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

To delete a directory, you should be using rmdir() instead of 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...
}

Although, there is a serious security risk here! If your check_input() does not properly sanitize $secret, you could rmdir('/intl/codes/../') which is the same as deleting /intl/. Try something like this:

$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. You can use just if (!empty($secret)) - empty() returns TRUE for NULL value as well.

  2. Use if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret)) to check if your file is not a directory and get rid of that warning. If you still wanna remove the directory, use rmdir() function.

  3. file_exists() returns TRUE for directories as well. So, you should also check if the argument is a directory with is_dir() , as i said before.

于 2012-01-08T08:38:31.683 に答える
1

に関するphpドキュメントで述べられているようにfile_exists()

Checks whether a file or directory exists

あなたの質問#3に対する私の唯一の推測は、ファイルが存在するかどうかを確認し、存在することです。ただ、それはファイルではなく、ディレクトリです。

#2に関しては、エラーメッセージにも記載されているように、次のようなことができます:

$file_to_check = ROOT . '/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';
}

そして、あなたの一番の質問については、次のようなことをするかもしれません:

$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. 何をするかわからないので、 calledcheck_input()のラッパー関数を作成しました。これにより、実行する必要がなくなり、デフォルト値も入力されます。$_GET[]input_get()isset()
  2. 何度も入力する必要がないように、ROOT . '/intl/codes/' . $secret;変数に入れました。$file_to_check
于 2012-01-08T08:48:31.513 に答える
1
    if (file_exists(ROOT . '/intl/codes/' . $secret)) {
        unlink(ROOT . '/intl/codes/' . $secret);
        $trusted = 'yes';
    } else {
        $trusted = 'no';
    }

それを行う別の方法はありますか(より簡単な方法など)?

いいえ、唯一の方法は使用することですfile_exists

$secret が /codes/ フォルダーに存在しない場合、警告: unlink Is a directory が生成されます。

$secretディレクトリを指しているようです。部分が true を返すunlinkため、実行パスは に到達します。ifだから存在します。ディレクトリを削除するにはrmdir()

ファイルが存在しない場合でも $trusted が常に yes を返すのはなぜですか?

それunlinkを削除して に設定$trustedするためyesです。削除後に検索すると、存在しないが$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 に答える