アクセス制御層の前に検証層を持つことは問題ありませんか


24

私はAPI構造のWebアプリケーションを作成していますが、このアプリケーションには独自の仕事をしているさまざまなレイヤーがあります。

最初のレイヤーはユーザー入力を検証する検証レイヤーであり、検証に合格した場合は2番目のレイヤー(アクセス制御レイヤー)に移動します。そうでない場合はエラーメッセージを返します

2番目の層は、ユーザーが実行したいタスクを実行する許可を持っているかどうかを確認するアクセス制御です。ユーザーが許可を持っている場合、要求を次の層に移動します。

3番目のレイヤーは、アプリケーションのロジックがあるコントローラーレイヤーです。

私の質問は、アクセス制御の前に検証レイヤーを持つことはOKですか?ユーザーが許可されていないタスクを実行しようとしており、検証エラーメッセージを送信している場合はどうなりますか?ユーザーはリクエストをエンドポイントに送信し、検証レイヤーと話します。検証に合格すると、メッセージが表示されます。You can't access this!

私には奇妙に感じますが、このようにうまくいくのでしょうか、それともインフラストラクチャの他の選択肢は何でしょうか?


10
また、検証を行うには、多くの場合、データベースまたはジョブを実行するためにデータベースにアクセスする必要があることに注意してください。アクセス制御違反をチェックする前にこれを行うと、その特定のURLで大量のトラフィックをスローすることにより、攻撃者がデータベースまたはファイルシステムをDDoSできるようになります。
グレッグブルクハルト

リソースの種類は、ユーザがアクセス可能であるならば、それは私がそれ以外のアクセスを許可していないアクセス可能な場合は、私の場合、同じアクセス制御ミドルウェアのために行くには、それがリソースをチェックし、参照
ムハンマド

それは本当だ。DDoS中、そのレイヤーは引き続きデータストアにヒットします。最初にそのレイヤーを実行すると、検証とアクセス制御のためにデータストアにアクセスすることはありません。アクセスコントロールのためにデータストアにアクセスするだけです。津波の大きさは小さくなりますが、津波が浜辺に当たるのを防ぐことはできません。システム全体が行き詰まる前に、あなたまたはあなたのサーバーチームが攻撃に対応する格好のチャンスを与えます。
グレッグブルクハルト

5
実用的な観点から、とにかく検証の前にアクセス制御を行う必要があります。ユーザーが最初にリクエストにアクセスできない場合、ユーザーのリクエストの正確性をどのように検証しますか?
ジボブズ

@Zibbobz検証は、ユーザーが正しいスキーマを送信している場合は、整数でなければなりませんパラメータが整数または何か他のものであるように、チェックのように簡単です
ムハンマド

回答:


57

許可されていないタスクの入力の有効性を知ることがセキュリティリークであるかどうかによって異なります。もしそうなら、あなたは本当に逆にそれをするべきです。

許可されていないユーザーに対する唯一の安全な応答は「アクセス拒否」です。応答が「不正な要求」である場合と「アクセス拒否」である場合、権限のないユーザーに情報を送信しています。

例として、名前付きドキュメントが存在することを「ドキュメントの削除」タスクの検証でチェックすることができます。権限のない人は、削除しようとするものと、受け取ったエラーを比較することで、何かが存在するかどうかを識別できます。特に決意のある攻撃者は、(特定の長さで)すべてのドキュメント名を列挙して、存在するものを確認する可能性があります。


7
+1、絶対に。データが何らかの方法で個人を特定できる、または他の方法で機密性がある場合、セキュリティの影響は、ユーザビリティの影響よりもはるかに深刻です。
キリアンフォス

4
@calethは、特定のドキュメントがシステム内にあるかどうかを実際に知らせません。このタイプの情報は、コントローラー層に到達したときにのみ提供されます。検証はスキーマをチェックするだけで、データベースにはアクセスしません-データベースへのアクセスはアクセス制御とより深い層のみが行います。また、アクセス制御レイヤーは、リソースが存在するかどうかにかかわらず、同じもののみを表示します。唯一の妥協の事は大丈夫ですかない場合、私は思っていたスキーマである
ムハンマド

@Caleth最後のコメントについて詳しく教えてください。OPにコメントが与えられた場合、どのようになるかわかりません。スキーマが公開されている場合、送り返される情報は非特権情報のみであるように見えます。
ロテム

11
@Rotem攻撃者が利用できる情報を事前に判断することは本質的に不可能です。すべきでないことを学ぶ方法を見つけられなかったからといって、そのような方法がないという意味ではありません。極端な例として、任意の脆弱性は存在しない可能性があります、将来誰かに検証層にチェックを追加することができます、彼らはそれが保護されていなかった知らなかったので、リーク情報を。
カミルドラカリ

4
@KamilDrakariは極端な例ではなく、完全に合理的な例です。別の言い方をすれば、アクセス制御の前に検証を行う場合、開発者が検証ステップを追加したいときはいつでも、その検証が機密情報を公開するかどうかを判断する必要があります。すべての開発者がその呼び出しを正しく行う可能性はごくわずかです。
mfrankli

24

さて、検証には複数のタイプがあります。

  1. 要求が明らかに不正な形式ではないことを検証する安価な基本的な健全性チェック。

    これは通常、無駄な往復を避けるために、少なくとも部分的にクライアント側で複製されます。

    とにかく、情報漏えいのリスクがないため、物事を簡単にし、エラーを起こしにくくするために、アクセス制御の前に行う必要があります。

  2. 保護されたアプリケーションデータに依存しない、より高価な検証。

    このような余分な検証がある場合は、データの漏洩を避けるためではなく、DOS攻撃を妨げるために、アクセス制御の後である可能性があります。
    リクエストを実行するだけで、その検証の一部が暗黙的に低コストまたは無料で実行される場合があるため、ここでは省略します。

    最初のステップのすべての検証が複製される場合、このクライアント側の部分も複製することは理にかなっているかもしれません。

  3. 保護されたアプリケーションデータに応じた追加の検証。

    アクセス制御の前にそれを行うと、明らかに情報漏えいのリスクがあります。したがって、最初にアクセス制御を行います。


3
APIに到達する前であっても、インフラストラクチャのポリシー実施ポイントでアクセス制御を実行することが理想的です。検証の基本的な静的セット(例:OpenAPI)が最初になり、その後により深いビジネス検証が続きます。一部の静的検証でさえ、アプリのReDOS攻撃の可用性に影響を与える可能性があります。
felickz

@felickz:はい、DOS攻撃は認証が完了するまで検証を延期する正当な理由です。それはバランス行為です。とにかく、それを適切に考慮するために、最初のポイントを分割しました。
デュプリケータ

アクセス制御の前に高価な検証を行うと、タイミング攻撃により情報が漏洩するリスクもあります。システムがリソースに応じて短くまたは長くかかる場合、攻撃者は要求されているリソースの側面を推測できます。
ライライアン

@LieRyan:これは、アクセス制御の前に潜在的に行われるすべての検証が、保護されたアプリケーションデータにまったく依存しない理由です。
デュプリケータ

13

アクセス制御の前にいくつかの検証が必要です。SOのAPIにはエンドポイント「回答の編集」があり、ユーザーが特定の回答を編集できるかどうかは回答に依存するとします(特定の評判の下では、ユーザーは自分の回答のみを編集できます)。したがって、アクセスコントロールレイヤーが機能する前に、整形式の「応答ID」パラメーターを検証する必要があります。おそらく答えが存在することも。

CalethとGregが言及しているように、アクセス制御の前により広範な検証を行うOTOHは、潜在的なセキュリティリスクです。

厳しいルールは

  1. ユーザーが他の方法で見つけることができないはずであるという検証を通じて情報を開示してはなりません。
  2. アクセス制御が必要とする範囲でアクセス制御が使用できるようにするには、データを検証する必要があります。

これらの両方のルールに従うことは、アクセス制御の前と後にいくつかの検証が必要になることを意味する場合があります。


3
これが現実的な答えです。単純で単純な入力データ構造の検証の場合、それを最初に置くことのqual責があってはなりません。さらに、特別に設計された入力/パケットからアクセス制御層を保護します。安全な情報漏洩または推測を実際に伴う検証は、アクセスチェックの後に配置する必要があります。
SD

これは、回答が公開されていることを前提としています。私は、多くのAPIが認証なしでデータを表示することさえしないと言っています。
トムトム

6

入力検証した後に「アクセス拒否」を受信するというフラストレーションに加えて、また、Validationレイヤーは、非常にシンプルなものでない限り、常にControllerからの情報を必要とする可能性があることに注意してください。これを念頭に置いて、ValidationAccess Controlの背後に配置し、Controllerの近くに置く方が理にかなっていると思います。


2

それは検証レイヤーの意味に依存します-もしリクエストの構文をチェックするだけなら、それは安全で、とにかくやらなければならないことです。「検証」で非特権ユーザーがアクセスできない情報を使用すると、安全ではなくなります。

アクセス制御を試みる前に、間違いなく健全性チェッカーを持っている必要がありますが、この部分特権情報を使用してはならないことをすべてのメンテナー(現在および将来)に明確に伝えるよう注意してください。そのようなチェックは認証、別の検証手順で実行する必要があります。

健全性チェッカーの健全性チェックとして、パイプラインの下位のコードのどの部分にもコード依存性を実際に持たせてはならず、問題なく公開できるはずの独自のパッケージに分離する必要があります(法的な問題以外) 。それができない場合、「検証レイヤー」がやりすぎです(またはコードベースが混乱しています)。


1

いいえ。大丈夫ではありません。

検証レイヤーにバグがある場合、セキュリティレイヤーをバイパスする可能性があります。

ビジネス要件の一部としてセキュリティを考慮することはよくある間違いです。「役割がsalesのユーザーのみが四半期ごとの数値を見ることができるはずです」はビジネスルールのようです。

しかし、セキュリティを確保したい場合は、「セールスロールのユーザーのみ、このエンドポイントでコードを実行できるようにする」などのルールを読む必要があります。サーバーは、アクセスする前に常に「アクセス拒否」を返すようにします。作成したあらゆる種類のコードまたはサーバー上のファイル。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.