3

ここにアイデアがあります。PHPスクリプトからファイルを作成しようとしています。ファイルは、サーバー上の任意のパブリックな場所(パブリックルートまたはそのサブディレクトリ)に作成できます。結論として、私はこのような関数を書きたいと思っています(UNIXサーバーとWindowsサーバーの両方で機能する必要があります)。

function create_file($path, $filename, $content, $overwrite=false) {
  # body
  ...

  }

パラメーター:

  • $ path -file-path(空またはで終わる/
  • $ filename-任意の有効なファイル名(ドット+拡張子が必要)
  • $ content -file-content(何でも)
  • $ override - trueに設定すると、既存のファイルが上書きされます(デフォルト。false)。

結果:

関数はTRUE、コンテンツを含むファイルを返し、作成します。またはFALSE、何らかの理由でファイルを作成できなかった場合。

問題の説明:

この関数がパス$pathにファイル$filenametrueを返し、作成することを期待しています。または、何らかの理由でそれが不可能だった場合。また、ファイルが書き込み用に正常に開かれた場合は、その中に$contentを入れる必要があります。false

引数$pathはパブリックディレクトリへの相対パスであり、$filenameは任意の有効なファイル名です。もちろん、パスがパブリックディレクトリの外部を指している場合は、ファイルの作成を避けたいと思います。関数はサブディレクトリから呼び出すことができます-この例のようなスクリプト

# php script: /scripts/test.php
create_file('../data/', 'test.info', 'some contents');
# result file: /data/test.info

これまでに何を試しましたか?

fopen()関数とfwrite()関数を使用してこれを実行しようとしましたが、一部のサーバーでは機能しますが、一部のサーバーでは機能しません。特権とchmod()の記述には問題があると思いますが、正直なところ、chmod属性についてはあまり詳しくありません。また、 $pathがサーバーのパブリックディレクトリの外を指しているかどうかを確認できませんでした。

つまり、この関数でファイルを作成TRUEし、ファイルが存在しない場合、またはファイルが存在する場合に返すようにします$owerwrite=true。それ以外の場合は何も起こらず、関数はを返しますFALSE

さらに、(理論上)あるパスでファイルを作成できない理由を知りたいです。間違ったパス/ファイル名は私が頭に浮かぶことだけであり、この問題についてはもっとあると確信しています。

サンプル/例/提案を事前に感謝します。

コードを更新

これまでのところ、私はこのコードを持っています...

  function create_file($path, $filename, $content, $overwrite=false) {
    $reldir = explode('/', trim(str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])), '/'));
    $dirdepth = sizeof($reldir);
    $rpadd = $dirdepth > 0 ? '(\.\./){0,' . $dirdepth . '}' : '';
    $ptpath = '#^/?' . $rpadd . '([a-z0-9]\w*/)*$#i';
    $ptname = '/^[a-z]\w*\.[a-z0-9]+$/i'; 
    if ($res = preg_match($ptpath, $path) && preg_match($ptname, $filename)) {
      $res = false;
      if ($overwrite === true || !file_exists($path.$filename)) {
        if ($f = @fopen($path.$filename, 'w')) {
          fwrite($f, $content);
          fclose($f);
          $res = true;
          }
        }
      }
    return $res;
    }
4

2 に答える 2

2

いくつかの提案:

  1. Webサーバーのドキュメントルートの所有者を設定します:chown -R apache:apache / var / www(/ var / wwwがドキュメントルートであり、Webサーバーのapacheがユーザーapacheで実行されていると仮定します)。ドキュメント内のすべてのディレクトリが特権755で表示されるように、ドキュメントルートの特権をこのように設定します(ユーザーapacheである所有者のみがフォルダー/ var / wwwおよびサブフォルダーに書き込むことができます)
  2. / var / wwwドキュメントルートを指すパスをブロックします。http://en.wikipedia.org/wiki/Directory_traversal_attackとして知られている問題が発生しています。$ pathが/var/www/../../../etc/passwdのようなものである場合はどうでしょうか?Basename php関数は、この種の悪意のあるパスを識別するのに役立ちます。この投稿を見てください:phpディレクトリトラバーサルの問題
  3. ファイルがすでに存在するかどうかを確認するには:http://php.net/manual/en/function.file-exists.php
于 2012-04-07T09:24:52.600 に答える
0

phpのすべてのファイル関数は2つの状況で正しく機能しません

  1. アプリケーションに十分なユーザー権限がない場合は、

  2. 引数/パラメータを正しく使用/渡していない可能性があります。

于 2012-04-07T09:59:15.517 に答える