11

コードを書くとき、高いプログラム品質を確保し、バッファ オーバーフロー エクスプロイトやコード インジェクションなどによってコードが悪用される可能性を回避するために、意識的に防御的にプログラムしますか?

コードに常に適用する「最低」レベルの品質は?

4

14 に答える 14

12

私の仕事では、コードは最高品質でなければなりません。
そのため、主に次の 2 つの点に焦点を当てています。

  1. テスト
  2. コードレビュー

それらはお金を家に持ち帰ります。

于 2008-08-09T18:00:26.907 に答える
4

abyx と同様に、私が所属している開発チームでは、常に単体テストとコード レビューを使用しています。それに加えて、人々が使用する可能性のあるコードを組み込んでいないことを確認することも目指しています。私は、手元のオブジェクトが仕様どおりに機能するために必要なメソッドの基本セットのみのコードを書く傾向があります。 . 使用されることはないかもしれないが機能を提供するメソッドを組み込むと、意図せずに「バックドア」または意図しない/予期しない使用がシステムに導入される可能性があることがわかりました。

後で戻ってメソッド、属性、およびプロパティを導入する方がはるかに簡単です。

于 2008-08-09T18:05:09.363 に答える
1

「コンポーネント」またはフレームワークに入るデータに対して防御することをお勧めします。「コンポーネント」またはフレームワーク内では、データが「正しい」と考える必要があります。

このように考えています。正しいパラメーターを提供するのは呼び出し元次第です。それ以外の場合、すべての関数とメソッドはすべての着信パラメーターをチェックする必要があります。ただし、チェックが呼び出し元に対してのみ行われる場合、チェックは一度だけ必要です。したがって、パラメーターは「正しい」必要があり、下位レベルに渡すことができます。

  1. 常に外部ソース、ユーザーなどからのデータを確認してください
  2. 「コンポーネント」またはフレームワークは、着信呼び出しを常にチェックする必要があります。

バグがあり、呼び出しで間違った値が使用されている場合。本当に正しいtodoとは?プログラムが作業している「データ」が間違っているという兆候があるだけで、ASSERTS のようなものもあれば、高度なエラー報告と可能なエラー回復を使用したいものもあります。いずれにせよ、データに欠陥があることが判明し、ほとんどの場合、作業を続けた方がよい場合があります。(少なくともサーバーが死ななければ良いことに注意してください)

衛星から送信された画像は、エラー アイコンを表示するためにインターネットからダウンロードした画像で高度なエラー リカバリを試行する場合に使用できます...

于 2008-08-10T09:26:45.617 に答える
1

開発環境ではファシストで、本番環境では慈悲深いコードを書くことをお勧めします。

開発中は、問題が見過ごされたり、根本原因を追跡するのが困難な後で問題が発生したりするのを防ぐために、不良なデータ/ロジック/コードをできるだけ早くキャッ​​チする必要があります。

本番環境では、問題を可能な限り適切に処理します。何かが本当に回復不可能なエラーである場合は、それを処理し、その情報をユーザーに提示します。

例として、ベクトルを正規化するコードを次に示します。開発中に悪いデータを入力すると悲鳴が上がり、本番環境では安全値が返されます。

inline const Vector3 Normalize( Vector3arg vec )
{
    const float len = Length(vec);
    ASSERTMSG(len > 0.0f "Invalid Normalization");
    return len == 0.0f ? vec : vec / len;
}
于 2008-08-13T18:15:11.803 に答える
0

私の経験では、防御的なプログラミングを積極的に採用することは、必ずしもコードの品質を向上させることを意味するわけではありません。誤解しないでください。ユーザーが遭遇するような問題をキャッチするために防御的にプログラムする必要があります。ユーザーは、プログラムがクラッシュしたときにそれを気に入らないのですが、これによってコードの保守が容易になる可能性はほとんどありません。テストなど。

数年前、ソフトウェアのすべてのレベルでアサーションを使用することをポリシーにしました。これは、単体テスト、コードレビューなどに加えて、既存のアプリケーションテストスイートとともに、コードの品質に大きなプラスの効果をもたらしました。

于 2008-08-13T17:36:12.633 に答える
0

インジェクション攻撃などを防ぐために常に取り組んでいます。ただし、内部イントラネット サイトで作業する場合、ほとんどのセキュリティ機能は無駄な労力のように感じられます。私はまだそれらをやっていますが、多分そうではありません。

于 2008-08-09T17:09:25.853 に答える
0

セキュリティには、一定のベスト プラクティスがあります。少なくとも、データベース アプリケーションの場合は、SQL インジェクションに注意する必要があります。

パスワードのハッシュ化、接続文字列の暗号化などの他の機能も標準です。

ここから先は、実際のアプリケーションに依存します。

幸いなことに、.Net などのフレームワークを使用している場合は、多くのセキュリティ保護が組み込まれています。

于 2008-08-09T17:47:10.223 に答える
0

内部アプリの場合でも、常に防御的にプログラミングする必要があります。ユーザーは運が良ければ、アプリを壊すようなものを書くことができるからです。確かに、お金を騙し取ろうとすることを心配する必要はないかもしれませんが、それでも. 常に防御的にプログラムし、アプリが失敗することを想定してください。

于 2008-08-09T17:54:50.303 に答える
0

場合によります。

私が本当に自分で何かをハッキングしているのであれば、考える必要のない最高のコードを書きます。コンパイラを警告などの味方にしましょう。しかし、型を自動的に作成するつもりはまったくありません。

コードが使用される可能性が高いほど、場合によっては、チェックのレベルを上げます。

  • 最小限のマジックナンバー
  • より良い変数名
  • 完全にチェックおよび定義された配列/文字列の長さ
  • コントラクト アサーションによるプログラミング
  • null 値チェック
  • 例外 (コードのコンテキストによる)
  • 基本的な説明コメント
  • アクセス可能な使用法ドキュメント (perl などの場合)
于 2008-08-10T08:13:50.303 に答える
0

Josh Blochによる効果的な Javaで提唱されているものとして、防御的プログラミングの別の定義を使用します。この本の中で彼は、呼び出し元がコードに渡す可変オブジェクト (セッターなど) と、呼び出し元に渡す可変オブジェクト (ゲッターなど) の処理方法について語っています。

  • セッターの場合は、変更可能なオブジェクトをすべて複製し、その複製を保存してください。このように、呼び出し元は、渡されたオブジェクトを事後に変更して、プログラムの不変条件を破ることはできません。
  • ゲッターの場合、インターフェイスで許可されている場合は、内部データの不変ビューを返します。そうでなければ、内部データのクローンを返します。
  • 内部データを使用してユーザー指定のコールバックを呼び出す場合は、必要に応じて不変のビューまたはクローンを送信します。ただし、コールバックでデータを変更することを意図している場合を除きます。データを変更する場合は、後で検証する必要があります。

持ち帰り用のメッセージは、内部で使用する変更可能なオブジェクトへのエイリアスを外部コードが保持できないようにすることです。これにより、不変条件を維持できます。

于 2008-08-10T08:26:46.703 に答える
0

Java、署名付き JAR、および JAAS。

Java を使用して、バッファ オーバーフローとポインタ/スタック ワッキング エクスプロイトを防止します。

JNI を使用しないでください。(Java Native Interface) DLL/共有ライブラリに公開します。

セキュリティ上の問題であるクラスのロードを停止するために JAR に署名しました。

JAAS を使用すると、アプリケーション自体を含め、誰も信頼しないようにすることができます。

J2EE には、ロール ベースのセキュリティのサポートが組み込まれています (確かに制限があります)。

これにはいくらかのオーバーヘッドがありますが、セキュリティ ホールはなくなります。

于 2008-09-05T05:31:09.540 に答える
0

私は、正しいプログラミングによってこれらのリスクを防ぐことができると強く信じています。(少なくとも Microsoft C++ ライブラリでは) セキュリティの脆弱性のために一般的に非推奨になっている非推奨の関数を回避したり、外部境界を越えるすべてのものを検証したりするなどのことです。

コードからのみ呼び出される関数は、呼び出し元を制御するため、つまり、外部境界を越えないため、過度のパラメーター検証を必要としません。他の人のコードによって呼び出される関数は、受信パラメーターがある時点で無効および/または悪意のあるものになると想定する必要があります。

公開された関数を処理するための私のアプローチは、可能であれば役立つメッセージを表示して、単純にクラッシュすることです。呼び出し元がパラメーターを正しく取得できない場合、問題はコードにあり、あなたではなく、呼び出し元が修正する必要があります。(公開されているため、関数のドキュメントを提供したことは明らかです。)

コード インジェクションは、アプリケーションが現在のユーザーを昇格できる場合にのみ問題になります。プロセスがアプリケーションにコードを挿入できる場合、コードを簡単にメモリに書き込んで実行することができます。システムへのフル アクセスを取得できなければ、コード インジェクション攻撃は無意味です。(これが、管理者が使用するアプリケーションを下位ユーザーが書き込み可能にすべきではない理由です。)

于 2008-08-10T11:27:30.960 に答える
0

テスト駆動開発を使用すると、確かに役立ちます。一度に 1 つのコンポーネントを作成し、コードを作成する前に (テストを介して) 入力の潜在的なケースをすべて列挙します。これにより、すべての基本をカバーし、誰も使用しないが壊れる可能性のあるクールなコードを作成していないことが保証されます。

私は正式なことは何もしませんが、通常、各クラスを調べて次のことを確認するのに時間を費やします。

  1. それらが有効な状態にある場合、有効な状態にとどまる
  2. それらを無効な状態で構築する方法はありません
  3. 例外的な状況では、可能な限り適切に失敗します (多くの場合、これはクリーンアップとスローです)。
于 2008-08-10T00:53:35.183 に答える
0

簡単な答え:場合によります防御的なコーディングが多すぎると、重大なパフォーマンスの問題が発生する可能性があります。

于 2009-09-07T11:28:38.657 に答える