すべてのCプログラマーが認識しなければならないセキュリティリスク/脆弱性は何ですか?[閉まっている]


13

高度なプログラミング言語の十分にテストされ、実証されたAPIを使用するのではなく、ハードウェアに密接に接触することから生じる多くのセキュリティリスクがあります。Javaなどの言語よりもCでバッファオーバーフローを引き起こす方がはるかに簡単です。

すべてのCプログラマが知っておくべきリスクまたは脆弱性(バッファオーバーフローなど)とは何ですか(Cプログラマに関連するIEの脆弱性)。これらはどのような問題につながる可能性がありますか?それらを回避する方法、およびプログラムでこれらを発生させる一般的な間違いは何ですか?


このリスト はどうですか:owasp.org/index.php/Category : OWASP_Top_Ten_Projectこれ以上のものが必要ですか?
-S.Lott

2
@ S.Lott:Web開発のセキュリティ問題が非常に重要なようです。一般的に、私が実際に求めているものよりも多くのリソースがあるようです。
アント

@Anto:質問を更新して、セキュリティに関するすべてのリソースと、質問しているセキュリティを区別してください。
-S.ロット

@ S.Lott:どういう意味かわかりません。ほとんどのCプログラマにとって重要なセキュリティ、つまり、バッファオーバーフローなど、Cで可能なその他のことをお願いします。
Anto

@Anto:「私が実際に求めているものよりも、その[Webセキュリティ?]に多くのリソースがあるようです」Webセキュリティではないセキュリティについて質問していると言っているようです。本当?その場合は、質問を更新して、探しているものを説明してください。間違ってる?次に、Webセキュリティについて尋ねています、その場合、OWASPリストが質問に記載されていないのはなぜですか?
-S.ロット

回答:


13

バッファオーバーフローは大きなものです。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の間違いがありますが、これらはセキュリティの問題を引き起こす可能性があります。


同じ仕事をするprintf("%s", str)ときに、裸の文字列に使用する必要はありませんputs(str)
Blrfl

@Blrfl putsは改行文字を追加しますが、追加しprintfません。
右折

することもできますがfputs(str, stdout)、そうではありません。
Blrfl

整数オーバーフローについて:オーバーフローが発生するとUBが発生するため、符号付き整数を使用しても解決策にはなりません。唯一の(痛みを伴う)解決策は、オーバーフローしないことを正式に証明するか、実行時にチェックすることです(ただし、チェックでオーバーフローせずに正しくチェックすることもできます)。
-sleske

@DavidThornley:C11およびC ++ 14標準は、その危険性のために標準ライブラリからgets()関数を削除しました。
デストラクタ

5

1
バッファオーバーフローについてC固有のことは何もありません-ポインタを使用する言語はこれを保持できます。整数オーバーフローはほぼすべての言語に適用され、マネージコードでも簡単に発生します。
スティーブ

1
@Steve、その問題を引き起こす実際のポインタではなく、言語が配列境界を強制しない方法。
ダグT.

2
@Steveは、Cだけに関係するものについて質問するのではなく、Cプログラマが知っておくべきことについて質問していました。
AttackingHobo

1
@Steve:Cは、範囲チェックのサポートが不足していることや、バッファを喜んでオーバーフローさせるライブラリ関数の数の一部が原因で、バッファオーバーフローの影響を非常に受けやすくなっています。
デビッドソーンリー

私は質問が特にCについて尋ねていることを理解していますが、これらのリスクがより一般的であるという文脈から答えが読み取られる場合、明確にする価値があると思います。特に、マネージコードの開発者は(IMHO)セキュリティについてあまりにも無頓着であり、特に整数オーバーフローはほとんどの言語に影響します。
スティーブ

4

これは、修正に数時間かかる問題を引き起こす可能性がある、見落としやすいリスクです。

問題なくコンパイルされる次のコードを検討してください。

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

にあるかどうかを確認するlpstr_current_stateと、CONST_EMERGENCY_STATE_HOLY_CRAP実際に割り当てています。定数変数は常に左側に配置することをお勧めします。定数を左側に置くと、変数に値を割り当てることができないため、コンパイラは失敗します。

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

そうすれば、コードを修正して読みながら、「ひどいことだったかもしれない」と簡単に自分に言うことができます...

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

7
コンパイラーは、他の問題とは異なり、警告としてキャッチしてフラグを立てるのは簡単です。残念ながら、すべてのコンパイラーで簡単にできるわけではありません。
デビッドソーンリー

2
これは、C以外の言語、=およびand を使用する言語で発生する可能性があり==ます。
FrustratedWithFormsDesigner

3
これは実際にはセキュリティの脆弱性ではなく、バグです。
クリスピットマン

1
これらはヨーダ条件と呼ばれます。

2
@Kristofer Hoch:Cのバグの可能性をリスクと呼び、ここでそれを検討する場合、もっと大きなフォーラムが必要になります。
デイヴィッド

0

セキュリティリスクは1つだけです。外部の人が、ソフトウェアの脆弱性をキャッチし、それを悪用して自分の利益を得るために最善を尽くすという事実です。そこから他のすべてが続きます。

だから、「彼らの正しい心に誰もいないだろう」と思うとき、あなたはすぐに考える必要があります。

最大の結果は、外部のイベントに(たとえば、外部から配信されたデータを処理することで)反応するときはいつでも、このデータが最悪の敵の制御下にあると想定しなければならないことです。


私はパラグラフ2と3に同意しますが、攻撃者にすべての責任を負わせることは私の目には少し厚くなります。攻撃を成功させるには、常に2つかかります。攻撃を仕掛けるプログラマーと、プログラマーを捕まえる攻撃者です。ただし、攻撃者が悪用する前にセキュリティの脆弱性が存在します。そしてそのために、プログラマは非難されるべきです。
cmaster-モニカの復元16年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.