web-dev-qa-db-ja.com

インジェクションの脆弱性は設計上の欠陥ですか、それとも実装上の欠陥ですか?

インジェクションの脆弱性は主に設計または実装の問題ですか? SQLインジェクションを例として使用しています。他のインジェクションの脆弱性にも興味があります。

私はそれが遅延プログラミングの直接的な帰結だと信じています。

  • 入力サニタイズの欠如
  • パラメータ化の欠如(APIを使用せず、代わりに文字列を使用してコードで直接SQLコマンドを構築する)

一部の人々は、それが主に設計上の欠陥であると言いますが、私は理由を理解できません。

2
justatester

これは両方になる可能性がありますが、そのような問題の主な責任は設計です。

設計に依存せず、開発者がforcedでSQLインジェクションに対して脆弱なコードを作成しなくても作成できる場合、それは実装の問題です。これは、開発者が問題を理解していないか、理解しているが、それに耐性のあるコードを作成したくないことを意味します。

準備されたステートメント(Java)の代わりにネイティブSQLまたはHQLまたはJPQLなどを使用する設計上の決定がある場合、またはDSLまたは類似の技法を使用する場合、そのような決定により、コードでSQLインジェクションの問題が発生しやすくなります。 SQLインジェクションへの抵抗は、準備済みステートメントの主な目的ではなく、むしろ肯定的な副作用です。それでも、ネイティブSQLを許可するという設計上の決定は設計の問題を意味します。

ネイティブSQLに関する明確な設計上の決定がない場合、開発者はデータアクセスレイヤーの実装に関する明確なガイドラインを持っていません。十分な経験がない場合、簡単にそのような間違いを犯し、SQLインジェクションに対して脆弱なコードを作成します。つまり、プレーンSQLについての決定は、このような重要な側面に対応していないため、再び悪い設計になります。

4
mentallurg

SQLインジェクション、XSSなどのインジェクションは、同じ文字列内のコードとデータの可能な組み合わせにより、また開発者が信頼されていない十分に検証されていないユーザー入力を使用してそのような文字列を構築するために可能です。

同じ文字列内にコードとデータを混在させる可能性は、SQL、HTML + Javascript、...の設計に深くあります。これは、コンピューターのメモリページが同時に読み取り、書き込み、実行可能であることに似ています。長い間、今ではメモリ内のコード(実行可能)とデータ(読み取り可能、書き込み可能)を明確に分離しようとしています。したがって、文字列内のコードとデータの混合は既に設計上の問題であると言えます。特に、多くの場合、コードとデータを明確に分離した設計を作成することができたためです。

しかし、多くの場合、SQLステートメントのパラメーターバインディングなど、コードとデータを入力として明確に分離した関数を使用して安全なコード+データ文字列を作成する方法が存在することも指摘できます。したがって、そのような関数を使用しないことは、アプリケーションの設計上の問題であると主張するかもしれません。場合によってはそのような機能を提供しないことは、代わりに使用されるフレームワークの設計上の問題になります。

このような設計上の問題は、実装上の問題につながります。理論的には、適切なエスケープと引用を「行う」だけでよいので、パラメータバインディングなどの安全関数を使用せずに安全なコード+データ文字列を構築することが可能です。したがって、これを不適切に行うと、実装エラーになります。

3
Steffen Ullrich

有能なソフトウェアアーキテクトを考えると、最大の問題は実装であり、具体的には、安全なコーディングのベストプラクティスに関する知識とトレーニングが不足している個人であると言えます。

この短い答えを修飾するために、私はデザインと対比し、デザインが広い空間をカバーすることを示します。一部のデザインは他のユーザーによって規定および定義され、残りは定義できます。

以下は、コーダーの最後から検討するすべてのレイヤーです。

  1. 実装
  2. 設計
  3. システムアーキテクチャー
  4. フレームワークとライブラリ
  5. 業界の期待

業界の期待は、ソフトウェア開発者とその顧客の両方に影響を与える習慣、真実、誤解、誇大宣伝、および顧客の認識です。これは主に処方された設計です。

Frameworks [4]は通常、業界の期待と規範の影響を受けますが、時間の経過とともに別の方法でフィードバックされます。新しいフレームワークは、業界の期待を向上させるために、新しいアイデア(時にはセキュリティ中心)で構築されますと規範[5]。新しいフレームワークの1つの例:Google Firebase FireStoreを使用すると、モバイルアプリでクライアント側でクエリを直接定義でき、フレームワークがデータベースでのシリアル化とリモート実行を処理します。セキュリティは、サーバー上にある非常に柔軟なJavaScriptセキュリティファイルで発生します。セキュリティアナリストは、それらを確認して問題を迅速に発見できます。これも処方設計です。

システムアーキテクチャ [3]は、[4]と[5]を念頭に置いて準備されることがよくあります。 RESTFul APIサービス(フレームワーク)を構築するかどうかの決定は、ソフトウェアアーキテクチャの決定[3]に基づいており、フレームワーク[4]が機能するように設計されている方法に制限されています。 RESTFul APIは通常の人為的エラーの問題でより多くの手動コーディングを必要とするため、より安全なシステムアーキテクチャの選択はGraphQLかもしれません。

システムアーキテクチャ [3]も、ソフトウェアアーキテクチャだけではありません。ソリューションを構築するために、適切なフレームワーク[4]、ソフトウェアスタック、ホスティングシステムを選択します。小規模な開発者コミュニティであまり知られていないフレームワークを選択するということは、精査が少なく、長年試されてきた成熟度がないということです。セキュリティプラクティスが公開されていない小規模な仮想マシンホスティングプロバイダーを選択することは、大きな責任となります。

私は設計を扱います [2]をシステムアーキテクチャ[3]、フレームワーク[4]、および業界の期待[5]とは異なるアイテムとして扱います。設計はシステムではなく、通常はデータ中心の方法で、顧客の要件についてより重要です。セキュリティは最終的にauthorizationと特定のデータへのアクセスを中心に実装されるため、データ中心のデータと言えます。データモデルの承認を意識した設計により、セキュリティの結果を改善できます。したがって、実装は重要かもしれませんが、このレベルの設計はユーザーが制御でき、失敗する可能性があります。

最後に、implementation [1]は、ここの回答ですでに十分に表現されています。ソフトウェアプログラマーは自分の技術を理解し、デザインを採用して[2]、安全なパターンを使用してコードを作成する必要があります。上記のすべてを試しても、まだセキュリティ障害がある場合、おそらくそれは知識とtrainingの問題です。なぜなら、ソフトウェアプログラマーは、フリースタイリングではなくベストプラクティスの方法で「計画」に従っている必要があるためです。

2
Todd