2012-01-08 10 views
4

マイスクリプト:チェックファイルがフォルダ内に存在する場合

$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. はそれを行うための別の方法(simplierは、など)はありますか?
  2. /codes/フォルダに$secretが存在しない場合は、Warning: unlink Is a directoryが生成されます。
  3. なぜ$trustedはファイルが存在しない場合でも常にyesを与えますか?

答えて

6

ディレクトリを削除するには、unlink()の代わりにrmdir()を使用する必要があります。

$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 /の削除と同じです。 - 同様NULL値をempty()戻っTRUEあなただけif (!empty($secret))を使用することができます

$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"; 
} 
1
  1. : このような何かを試してみてください。

  2. if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret))を使用して、ファイルがディレクトリではないことを確認し、その警告を取り除きます。それでもディレクトリを削除したい場合は、rmdir()機能を使用してください。

  3. file_exists()は、ディレクトリの場合もTRUEを返します。だから、前にも述べたように、引数がis_dir()のディレクトリであるかどうかを確認する必要があります。

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

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

いいえ、唯一の方法は$秘密は中/コード/フォルダが存在しない場合は、警告を生成file_exists

を使用することです:リンク解除は、そののを取り除く方法ディレクトリですか?

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

ファイルが存在しない場合でも、常に信頼できるのはなぜですか?

unlinkはそれを削除し、yesから$trustedを設定するので。あなたが削除した後に検索するとき、あなたはそれが存在していませんが、見01​​が明らかyes

1

含まれているあなたの$secretは空の文字列ですが、それはあなたのisset()テストに合格しています。 ディレクトリROOT . '/intl/codes/'が存在します(したがって、file_exists()チェックに合格します)。ただし、unlink()ディレクトリは使用できません(ここでもあなたの意図はありません)。

$_GET['secret']に空でないものがあることを確認して、check_input()の機能を確認してください。

P.S.おそらくisset($secret)の部分を削除する必要があります。 !empty($secret)ここで十分ですし、あなたのスクリプトを修正します。 PHPのドキュメントで述べたように

1

file_exists():あなたの質問#3の

Checks whether a file or directory exists 

私の唯一の推測では、次のとおりです。ファイルが存在し、それがない場合は、確認してください。ただ、それはファイルではなく、ディレクトリです。

$ file_to_check = ROOT:エラーメッセージで述べたように#2用として

は、また、あなたはこのような何かを行うことができます。 '/ intl/codes /'。 $ secret;

  1. 私はcheck_input()が何をするか分からないが:説明の

    $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]; 
        } 
    } 
    

    少し:

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

    とあなたの#1の質問には

    は、1つのこのような何かをするかもしれませんだから$_GET[]のラッパー関数をinput_get()という名前で作成しました。 isset()を実行する必要がなくなり、デフォルト値も入力されます。
  2. を変数$file_to_checkに入れて、何度も繰り返し入力する必要はありません。
-1

この

<?php 
    echo file_exists("test.txt"); 
?> 
をお試しください
関連する問題