2

多くのファイル戦術を選択する
と、ディレクトリ
トラバーサルのセキュリティの問題が発生しますか?

ログインシステムを書く必要があり
、多くのファイル戦術は

多くの id ファイルを作成し、scandir を使用します。

したがって、ディレクトリには

aaa.txt (内容はaaa_pass)
bbb.txt (内容はbbb_pass)
ccc.txt (内容はccc_pass)

誰かが自分のIDを入力すると
、システムはディレクトリをスキャンし
、IDファイルを見つけます。

しかしねえ、もし彼が

"../../important.txt" ?

その後、彼は ../../important.txt にアクセスできましたか?

4

3 に答える 3

2

一見すると、ログイン システムを作成するために、やや奇妙な道をたどっているように見えます。ファイルシステムのディレクトリにあるプレーンテキストファイルが、それが異常であり、より一般的な認証ですでに考え抜かれた多くの微妙な点を見落としている可能性があるという以外の理由がない場合、取るべき賢明なパスであるかどうかはわかりませんシステム。たとえば、ハッシュ化およびソルト化されたパスワードを保存したい場合、それをスキームに実装する方法を熟考する必要があり、セキュリティ上の問題につながる間違いを犯す可能性があります。ただし、優れた PEAR ライブラリまたは Zend Framework の Zend_Auth コンポーネントを使用すると、明確で十分に文書化された出発点が得られます。

とにかく、質問で説明した配置の理由があると仮定すると、 basename() 関数は、この場合に必要なものである可能性があります。質問で説明したようなディレクトリトラバーサル攻撃を実行できないように、ファイル名自体以外のすべてを削除します。

したがって、ユーザーからの入力が次の場合:

../../重要

以下を実行できます。

$cleanUsername = basename($input);
$filename      = '/path/to/password/files/' . $cleanUsername . '.txt';

if (file_exists($filename)) {
    [...]
}

わかる?

于 2009-06-11T15:40:51.153 に答える
1

パスの一部として使用する前に、ユーザー名の検証を実行できます。たとえば、文字と数字のみを許可するには、正規表現を使用して次のようなことを実行できます。

if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) {
    //username is not valid
} else {
    //username is ok to use
}

これを行う別の方法は、ユーザー名を読み書きする前にハッシュすることです。次に例を示します。

$hash = sha1($username);

このように、ユーザーはユーザー名として何でも持つことができ、ファイルルックアップの動作を操作する危険はありません。のユーザー名は"../../important.txt"、のハッシュを提供します"48fc9e70df592ccde3a0dc969ba159415c62658d"。これは、ソース文字列が厄介であるにもかかわらず安全です。

于 2009-06-11T15:46:33.120 に答える
1

このファイルパスワードシステムを使用する以外に選択肢がない場合 (何らかの理由でそうしなければならない場合)、ある種の難読化されたファイル名を作成することに加えて、サーバーと同じ拡張子を持つファイルを作成することもできます。念のためサイド言語 - たとえば、PHP を使用している場合、ファイル名は john.php (または難読化された「john」) になり、内容は次のようになります。

<?php
    exit; // or maybe even a header redirect --
    /*password goes here*/
?>

もちろん、ファイル読み取りルーチンは、コメント ブロック内のフレーズを解析する必要があります。

このように、誰かが何らかの方法でそのファイルに到達した場合、それは決してレンダリングされません。

于 2009-06-11T18:06:20.210 に答える