バッファオーバーフローは大きなものです。Cでは何もデフォルトで範囲チェックされないため、バッファを簡単に上書きできます。gets()
バッファのオーバーフローを止めることのできない標準ライブラリ関数があり、ほとんど使用しないでください。
ヒープブロックのスクランブルなど、悪用を妨げる実装レベルの手法がいくつかありますが、ローカルバッファーでのバッファーオーバーフローを防ぐことはできません。
Cには適切な一般的な解決策はありません。多くのライブラリ関数には、書き込む量を制限するバージョンがあります。計算は不器用になることがありますが。適切なテストが実行されている限り、テストでヒープバッファオーバーフローを検出できるソフトウェアがあり、スタックオーバーフローは多くの場合、テストでクラッシュとして表示されます。それ以外は、注意深いコーディングとコードレビューの問題です。
関連する問題は、1文字だけ小さすぎるバッファへの書き込みの問題です。n文字の長さのC文字列は、'\0'
ターミネータのためにメモリ内にn + 1文字を必要とすることを忘れます。攻撃者がターミネータなしで文字列を保存できる場合、文字列を想定しているC関数は、ゼロバイトに達するまで処理を続行します。その結果、必要以上の情報をコピーまたは出力する可能性があります)。解決策は、認識、注意、およびコードレビューです。
printf()
家族には別のリスクがあります。を書く場合、印刷時に '%'が含まれていると、char * str; ... printf(str);
問題が発生しますstr
。%n
フォーマットディレクティブは可能にprintf()
メモリに書き込みます。解決策はprintf("%s", str);
またはputs(str);
です。(また、snprintf()
代わりにC99 を使用してくださいsprintf()
。)
特にループインデックスとして符号なし整数を使用すると、問題が発生する可能性があります。小さい負の値を符号なしに割り当てると、大きな正の値が得られます。これは、何かのNインスタンスのみを処理したり、のような制限された機能を処理したりするようなものを損なう可能性がありますstrncpy()
。すべての符号なし整数を調べます。あなたは避けたいかもしれないunsigned short
それらのいずれかで、大きな値は、大きな正の値に変換されますから、int
。
Cの文字定数は実際にはであることを忘れないでくださいint
。のようなものを書くことchar c; while((c = getchar()) != EOF) ...
は簡単に失敗する可能性EOF
がありますchar
。
私が考えることができるより特徴的なCの間違いがありますが、これらはセキュリティの問題を引き起こす可能性があります。