2009-06-11 1 views
3

私は小さな読み取り専用FTPのようなサーバーを書いています。クライアントは「私にそのファイルを渡す」と言って、私のサーバはそれを送信します。C++でのパスサニタイズ

要求されたファイルが "../../../../../etc/passwd"または他の悪いものでないことを確認する標準的な方法(ライブラリ関数?!?)はありますか?もの?すべてのクエリをディレクトリ(およびそのサブディレクトリ)に限定することができれば幸いです。

ありがとうございました!

答えて

1

を見てみましょう、とサービングディレクトリ(たとえば/ FTP /パブ)のこと。彼らが要求するファイルについては、以下を確認してください。

  1. ファイルが存在します。
  2. ファイルパス上で複数の "/ .."を使用してアクセスされたファイルの親ディレクトリは、ルートディレクトリのinodeにヒットする前に、サービスディレクトリinodeをヒットします。

statを使用すると、任意のディレクトリのiノードを見つけることができます。これを1つの関数に入れ、ファイルを提供する前に呼び出します。

もちろん、適切な特権を持つユーザー/グループを使用することもできます。Windowsので

+0

チャットはあなたが望むものを達成するための良い方法だとは思いますが、私の提案を受け入れてくれてうれしいです。 –

+1

Inodeは1つのファイルシステム内でユニークです。あなたの解決策はそれを説明しません。 – dragonroot

3

これは完璧ではありませんが、特定のユーザ/グループの下でftpサーバを実行できます。しかし、これは正確にあなたが探しているものではないかもしれません。

ユーザーが移動できるディレクトリと移動しようとするディレクトリのホワイトリストを持つこともできます。単純に許可しない(したがって、基本的には独自のアクセス許可を作成します)。

私は個人的には、作業がすでにOSによって完了しているので、前者を優先します。

1

私はこれを達成するための標準ライブラリについて知らない。

あなたは試みることができる:だけにサーバーを実行しているUNIXユーザーのアクセス権を設定し

  1. は、特定のディレクトリへの読み取り/書き込み権限を持っています。

  2. 絶対パス(UNIXでは「/」で始まるパス)のみを受け入れるようにプログラムを設計することができます。これは、PAM、chrooted環境、または標準UNIXユーザー/グループのアクセス許可を使用している可能性があります。そのように、あなたはそれが有効なパスであることを確認するためにチェックすることができます - たとえば、文字列を持っている任意のパスを許可しない「..」

編集:Peterから

は:そこにあるように見えますライブラリ関数、realpath()は#2を上から助けます。

5

また、ルート(/)ディレクトリのinodeを取得chroot

+0

私はこれがより好きです。 –

1

、私は(まだかかわらず、任意のOSに適用される)のようなものだろう:/ SomeFolderWithFiles:

  • ユーザー要求が
  • Serverはpath_to_fileはC」で始まる場合
  • サーバーのチェックを提出見つけたファイル

      を/」
    1. 終了処理
  • +1

    いいえこれは '..'トラバーサルをブロックしません。 Windowsでは 'GetFullPathName'を使います。 – rwallace

    16

    chrootが、おそらく行くには最高の方法ですが、を使用することができますを使用して、指定されたファイル名への標準パスを特定します。 manページから:

    char *realpath(const char *file_name, char *resolved_name); 
    

    のrealpath()関数は、結果の絶対パス名すべてのシンボリックリンク、余分な「/」文字、ファイル名に/./と/../への参照、およびコピーを解決します解決された名前で参照されるメモリに格納します。 resolved_name引数は、少なくともPATH_MAX文字を格納できるバッファを参照する必要があります。

    ここから、任意の追加の方法でリクエストを制限できます。

    +0

    +1クール、私はそのような機能を探していた! – poundifdef