1

コマンドを使用してopen、HTTP アドレスまたはファイルシステム上のファイルを開きます。このコマンドを特定のディレクトリに制限することは可能ですか? o のようなパスを渡すこと../../etc/passwdはできませんか?

open_basedirPHPでは、ディレクティブを使用してユーザーをディレクトリに投獄できることを知っています。openコマンドを保護するために似たようなものはありますか?

4

1 に答える 1

1

それは可能ですが、パスをチェックして、目的のサンドボックスの外を指していないことを確認する必要があります。openあなたのためにそれをしません。

を見てくださいFile.realpath。パス内のコンポーネントを解決..し、要求されている実際のパスを残します。そのパスは存在する必要があり、存在しないrealpathと例外が発生します。これは、ファイルを提供できないという最初のヒントです。あなたはレスキューする必要がありますErrno::ENOENT

File.realpath('/usr/bin') # => "/usr/bin"
File.realpath('/tmp') # => "/private/tmp"

File.realpath('/foobar') 
Errno::ENOENT: No such file or directory - /foobar

次に、単純な正規表現を使用して、結果のパスが許可した領域に固定されていることを確認できます。コードの例を次に示します。

SHARED_PATH_REGEXP = /\A#{ Regexp.escape(File.realpath('/path/to/shared/content')) }/i

def is_shared_path?(requested_path)
  real_requested_path = File.realpath(requested_path)
  !!real_requested_path[SHARED_PATH_REGEXP]
rescue Errno::ENOENT
  false
end

path_received('/etc/passwd') # => false
path_received(SHARED_PATH_REGEXP + '/foo.html') # => true

Regexp.escape正規表現エンジンがリテラル チェックを行うように、ファイル文字列を前処理するのに役立ちます。

Regexp.escape('/usr/bin')  # => "/usr/bin"
Regexp.escape('../../public')  # => "\\.\\./\\.\\./public"
于 2013-06-02T18:23:16.697 に答える