2

私はシェルの作成を行ってきましたがaccess()、ファイルが存在するかどうか、読み取り可能かどうかなどを確認するための推奨事項に出会いました。実装が非常に簡単で、stat(). そのマニュアルページを見始めたとき、セキュリティホールにつながる可能性があるため、使用が推奨されていないことに気付きました。マニュアルページには次のように書かれています:

open(2) を使用して実際にファイルを開く前に、ユーザーがファイルを開く権限を持っているかどうかを確認するために access() を使用すると、セキュリティ ホールが作成されます。

これがどのように悪用されるか、またはopen()ファイルをチェックした後にのみ使用することに関連するかどうかを知っている人はいますか? stat()多くの人が代わりに使用すると言っていることは知っていますaccess()が、特に私が使用したシェルでは、実装が非常に簡単です。

4

3 に答える 3

4

それがTOCTOUレース(Time of Check to Time of Update)です。access()悪意のあるユーザーは、と のopen()呼び出しの間で、アクセスできるファイルを、アクセスできないものへのシンボリック リンクに置き換えることができます。faccessat()またはを使用しfstat()ます。一般に、ファイルを 1 回開き、そのファイルに対してf*()関数を使用します (例: fchown()、...)。

于 2011-10-28T07:10:24.697 に答える
0

このパターンは、ファイルを呼び出すaccess()stat()、ファイルを開くことができるかどうかを判断し、許可を得ている場合はファイルを開くように見えます。

代わりに、通常は、先に進んでそれを開こうとし、その試みが成功したかどうかを確認することをお勧めします(成功しなかった場合は、その理由)。これにより、チェックからファイルを開こうとするまでの時間間隔が回避されます。

于 2011-10-28T08:39:36.137 に答える
0

考えられることの 1 つは、弱いように見えますが、access() は有効な uid と gid ではなく、実際の uid を使用することです。これにより、setuid プログラム (通常のユーザーが実行するが、所有者のアクセス許可を取得するプログラム) が、呼び出し元のユーザーがファイルを読み取ることができるかどうかを確認できるようになり、読み取れないはずのファイルへのアクセスを誤ってそのユーザーに与えることを防ぐことができます。おそらく、シンボリックリンクまたはハードリンクのトリックを使用して. これが可能である、または stat() では不可能であるという証拠は見つかりませんが、次のシナリオを想像してください。

user executes program
program is setuid, immediately gets all privs of root
program checks file1 to ensure that user has access
file1 is a hardlink to file2, which user has access to
user changes file1 to hardlink to file3 (/etc/shadow or something like that)
program reads file1 and does something to it (print, convert, whatever)
user now has access to a file they shouldn't
于 2011-10-28T04:48:34.567 に答える