web-dev-qa-db-ja.com

単一のfopenはTOCTOUの脆弱性をもたらしますか?

Linuxで実際にドライバーを修正しています。 Klokworkはそのようなコードを言った:

_file = fopen(fileName, "w+"); // w+,r,a and any mix of those is used here
if (file != NULL) { /* do things*/ }
else { /* throw error */ }
fclose(file);
_

チェック・オブ・チェックからタイム・オブ・ユースの脆弱性として終了する可能性があります。

しかし、私が読む限り、それを実現するには、fopenの前にif(access())のようなことを行う必要があります。

そして質問があります:私が示すそのコード例には弱点がありますか?または私は気にする必要はありませんか?

23
user209896

fopenの呼び出し自体は、TOCTOUの脆弱性ではありません。定義により、TOCTOUには、「チェック」と「使用」の2つの操作が含まれます。

TOCTOUの脆弱性の一般的な例は、ファイルを開く前にaccessでアクセス許可をチェックすることです。チェックとオープンの間に権限が変わる可能性があるため、これはバグ(競合状態)であり、ファイルの権限はセキュリティにとって重要であるため、通常は脆弱性です。

accessシステムコールは、TOCTOUを導入しない多くの使用方法がないため、非常に疑わしいです。 fopenの呼び出し自体は、安全である多くの使用方法があるため、特に疑わしいわけではありません。ただし、これはaccessfopenでTOCTOUを作成する唯一の方法であることを意味するものではありません。

ファイルを開くときに発生する可能性のある競合状態の例は、外部ソースからファイル名を取得し、その名前を想定している場合です。たとえば、ディレクトリ名とファイル名を連結してfopenへの引数を作成し、そのディレクトリでいくつかのチェックを行った場合も、TOCTOUの脆弱性です。ディレクトリを使用してファイルを開くまでに、ディレクトリのチェックが無効になる場合があります。 Linuxにopenatシステムコールがあるのはそのためです。つまり、ディレクトリでopendirを呼び出し、ディレクトリでチェックを実行してから、openatを呼び出してそのディレクトリ内のファイルを開くことができます(一方、openは名前が連結されているため、-nowにこの名前が付いているディレクトリでファイルを開きますが、チェックした名前ではない可能性があります)。

だからはい、あなたは気にする必要があります。コードには脆弱性がある場合とない場合があります。私の非常に限られた経験では、Klocworkには多くの誤検知がありますが、すべてが誤検知であるとは限りません。 completeメッセージを注意深く読むことから始めます。書き留めたセキュリティ対策方針を使用してコードを注意深く確認し、これらのセキュリティ対策方針がどのように満たされているか(または満たされていないか)を追跡します。奇跡はありません。正しい安全なコードを書くことは、チェックリストを適用することよりも困難です。