これは馬鹿げた考えだと確信していますが、理由を知りたいので、しばらくお待ちください。
バックエンド開発者が行う多くの作業は、HTTP経由で顧客にCRUDアクセスを提供し、基本的に内部データベースとの間でデータをマッピングします。顧客は、暗号化された接続を介してある種の資格情報を使用してWebサービスを承認し、Webサービスはデータを検証してバックエンドデータベースに対してクエリを実行し、結果をクライアントに返します。
全体として、これはデータベースと直接やり取りするためのより悪い方法にすぎません:REST仕様を完全に実装する人はほとんどいません。遅かれ早かれ、いつでも自家製の一般的なフィルタリング、ソートが行われますまたはページネーション-SQLはすでにこれらすべてをサポートしています。
それで不思議に思いました。SQLポートを公開し、HTTP APIを完全にスキップして、顧客がデータベースにアクセスできるようにしてはどうでしょうか。これには多くの利点があります:
不利な点には、複数のスキーマバージョンをサポートできないことも含まれているようですが、慎重に非推奨にすると(おそらくクライアントSDKも)、影響は最小限に抑えられるはずです。
誰もこれを行っていないようで、見落としているセキュリティリスクがあるはずです。なぜ顧客にパブリックSQLアクセスを提供できないのですか?何がうまくいかないのでしょうか? (これは好奇心から生まれた単なる思考実験であることに注意してください)
TL、DR:しないでください。
(My-)SQLアクセス許可はかなり細かいので、明らかなセキュリティ問題はないはずです。
レコードレベルの許可があっても、簡単に拡張できます。ユーザーがテーブルに対して無制限のSELECT
を持っている場合、ユーザーは自分が属していないレコードも含め、そのテーブル上の任意のレコードを選択できます。給与表は悪いものになるでしょう。ユーザーがDELETE
またはUPDATE
を持っている場合、WHERE
句を忘れて、テーブルに移動します。それはDBAにも起こりますが、なぜユーザーに起こらないのでしょうか。
HTTP通信とWebアプリのコード全体をスキップするので、パフォーマンスはかなり良くなるはずです。
また、アプリケーションを使用してアクセスの検証、フィルタリング、付与、拒否を行うことから、セキュリティ、監査、フィルタリング、および本当に細かい権限制御をすべて破棄します。そして通常、トランザクションに費やされる時間のほとんどは、データベースがクエリを処理することです。アプリケーションコードはそれより少なく、HTTP通信は削除せず、SQL通信に置き換えるだけです。
新機能はデータベースの移行の問題であり、すべてがスキーマに反映されます
そのため、多くの人々が「データベースとしてスプレッドシート」を使用しています。そして、複数のソースからのデータを調整する必要がある場合、それは悪夢です。
追加の作業なしで、強力なクエリ機能がユーザーに提供されます
強力なエンジンをスケルトンシャーシに取り付け、シートにボルトで固定し、レースに持ち込むようなものです。車を減速させる余分な重量はないので、非常に高速です!
ここも同じです。確かに、それは高速で強力ですが、アプリケーションによって提供されるセキュリティ対策、セッション、レコードレベルのアクセス制御、「ユーザーが許可されていることを実行する」、または監査なしではありません。
Webアプリケーションの最も一般的な脆弱性の1つはSQLインジェクションであり、SQLコンソールをユーザーに提供しています。あなたは彼らに多種多様な銃、たくさんの弾丸、そしてあなたの足、あなたの手、あなたの頭を与えています...そして、それらのいくつかはあなたを好きではありません。
興味深い質問です。理論的には、これは安全に行うことができます。 MS-SQLは、暗号化を使用して接続を保護し、ユーザーを認証し、詳細な権限と監査などのその他のセキュリティ機能を提供します。
実際、イントラネット環境ではシッククライアントがデータベースに直接アクセスするのが一般的でした。そのため、データベースのセキュリティコントロールが主要なセキュリティメカニズムでした。これは不適切に行われる傾向があり、たとえば、すべてのユーザーがアプリにハードコードされたパスワードを使用して管理者として接続しました。しかし、それはうまく行うことができます。
主な問題は、権限昇格の欠陥です。データベースAPIは非常に複雑であり、巨大な攻撃面を提示します。プロトコルは速度を重視して設計されているだけでなく、古く、インターネットが強化されていません。たとえば、Oracleには何百もの特権昇格の欠陥がありました。ただし、MS-SQLはこの点で優れたデータベースの1つです。また、ユーザーのアクセス許可を制限することで、攻撃の対象を減らすこともできます。
アーキテクチャ的には、一般的なクエリを許可し、セキュリティ制限を適用するインターフェースを公開することは、非常に理にかなっています。 REST APIがカスタムクエリのような機能を獲得するにつれて、人々はある程度ホイールを再発明しています。
これを実行できるかどうかは、ユーザーとの関係に大きく依存します。これらが契約上の関係で顧客に支払っている場合、ランダムなインターネットユーザーよりもある程度信頼できるので、このアーキテクチャを使用するのが適切な場合があります。特に、異なるクライアントが別々のデータベースにサイロ化されている場合。細心の注意を払って踏んでください。リスクとベネフィットを慎重に検討しているにもかかわらず、違反に直面した場合に非難される可能性があるのです。匿名サインアップでWebスケールサービスを実行している場合、これは避けます。ほとんどのクラウドプラットフォームプロバイダーがデータベースポートをクライアントに公開する機能を提供していることは注目に値しますが。
RESTfulなインターフェースの両方を構築し、お客様に直接SQLアクセスを提供しました。
ここでの問題は、質問に根本的な欠陥があるということです。
バックエンド開発者が行う多くの作業は、HTTPを介して顧客にCRUDアクセスを提供し、基本的に内部データベースとの間でデータをマッピングします。
これは、私の経験では、私がすることの重要な部分ではありません。それを4つのタスクREデータアクセスに簡略化しましょう。
通常、DBには、これらのタスクで必要に応じてこれを行うためのツールはありません。たとえば、次のような場合があります。
これらのシナリオのそれぞれに対していくつかの機能を備えたDBがあると確信していますが、通常、ほとんどのDBはdatabasesであり、設計されていないため、これらのシナリオのほとんどをサポートしませんビジネスロジックを処理します。
そうは言っても、クライアントがwantデータベースレベルでアクセスするシナリオがあります。その場合、will直接アクセスを提供するソリューションを見つけます。これが発生するのを妨げるものは何もありません-それは単に典型的ではありません。
悪質なアクターにDBのパフォーマンスを破壊する完全な権限を与えただけだということを除いて、パフォーマンスは「はるかに優れている」はずです。もちろん、彼らは認証を受ける必要がありますが、「悪意のある」俳優は「素朴で無能な」正当なユーザーである可能性もあります。ユーザーが見つけることができるすべてのテーブルで外部結合の実行を開始した場合、DB内のすべての非インデックスフィールドのwhere句、および計算コストが高い計算フィールドを使用して何をしますか? DBがごくわずかでない限り、このリスクにさらされます。
私の推測では、DBの前にあるWebアプリケーションが行うべき大きなことの1つは最も一般的な結果をキャッシュするであるため、DBはごくわずかです。すべてのサービスがこれを実行できるわけではありません。完全に一貫した読み取り/書き込みアクセスを提供するように明示的に設計されているサービスもあります。ただし、多くは読み取り専用であり、ある程度のレイテンシを許容できます。一貫性を更新します。これらのサービスは、mecachedやredisなどのメモリ内キャッシュを使用する場合、直接DBアクセスよりも文字通り数千倍高速になります。
なんらかのビジネスルール検証を必要とするすべてのテーブルに更新トリガーがある場合を除き、直接アクセスは整合性を壊すための良い方法です。ああ、それは誰かがちょうどアルファ文字を書き込んだ郵便番号フィールドですか?問題ない。電話番号フィールドに英字が含まれていますか?いいね通貨フィールドにカンマとセミコロンが含まれていますか?たぶん誰かがいくつかのロジックハッキングで彼ら自身に無料のボーナスを与えようとしています。すべての単一ユーザーがWebアプリケーションと同じレベルの検証を実行することを本当に信頼していますか?あなたの信仰のレベルは信じられないほどなので、あなたはコーディングをやめて司祭になるべきです。
大規模なメンテナンスを行うために、DBをオフラインにする必要がある場合があります。これが発生している間、キャッシングWebアプリケーションは少なくとも読み取りを処理し続けることができますが、ユーザーコミュニティ全体に直接アクセスできます。 DBをより強力なサーバーに移行したい場合があります。あれは何でしょう?すべてのユーザーが同時に接続文字列を切り替えるのに問題がありますか?場合によっては、クラスタリングに切り替えたいことがあります。ああ、ハードコーディングされたこれらの接続文字列は、今あなたを@ $$で本当に噛んでいますね?ファイアウォールルールが更新されたため、セキュリティでポートの切り替えを要求されただけですか?うーん...接続文字列を更新する必要があることをすべての顧客に通知する時間。
少数の顧客または数千を超える行を決して持たないつもりであり、DB /アプリがこのおもちゃのサイズを超えてスケーリングしないことが確実である場合、直接アクセスはJust Fine(TM)です。一方、DBが現在のインカネーションを超える可能性がある場合、または再構築、再スケーリング、またはリホーミングを含む大規模な移行を実行する場合、保存するための間接層を持っているラッキースターに感謝します。あなたのベーコンとスケーラブルな高性能ソリューションのすべての良さをもたらします。
これは、特定の状況では合理的なアプローチになる可能性があります。
顧客は読み取り専用アクセスを取得します。
彼らは、データベース全体への読み取りアクセス権を取得します。これは、すべての顧客に対する準公開データであるか、独自のデータのみが含まれています。特に、ユーザーのPIIや規制管理の対象となるデータが含まれていてはなりません。
彼らが好きなだけ読んだり、コピーを作ったりしてもかまいません。たとえば、リークして完全に公開されたとしても、少し煩わしいだけです。
ライブプロダクションシステムにアクセスするのではなく、後書きミラーまたはデータウェアハウスにアクセスします。
機密データまたは顧客固有のデータが倉庫に漏洩するリスクを適切に検討して対処しました。
システムは、実際の本番システムから技術的に分離されています。データのミラーを使用して Google BigQuery サービスを作成し、それにアクセスを許可することを検討します。
失効、不正使用の検出、顧客に許可されたアクセスの内部委任の管理を顧客に許可することなど、アクセス許可を管理する良い方法があります。繰り返しますが、BQのIAMのようなIaaSプロバイダーへのアウトソーシングは、自分で行うよりもはるかに簡単です。
顧客は、SQLで簡単に表現できるデータに対して複雑な操作をしたい必要があり、SQLの記述方法を知っています。
エクスポートしたスキーマが十分に安定しているか、顧客が十分に寛容であるため、スキーマの変更とクエリの破損は大きな問題ではありません。
これらの条件は完全に白黒ではありませんが、他の回答が述べているように、多くのユーザーからの情報を含むライブデータベースへの直接アクセスは危険性を増しています。
これが妥当である可能性のある架空のシナリオは次のとおりです:販売するアイテムの複雑なパーツカタログがあります。あなたが持っている部品とその価格についての情報は商業的に重要ではなく、人々がそのコピーを保管することについてあまり心配していません。そしてそれは単純なリストよりも複雑です:おそらく価格設定やどの部品が連携するかについて複雑な関係があるでしょう
これらの条件がすべて当てはまる場合、開始点は、CSVまたはJSONとしてデータのダウンロードを提供することです。それを行うのが適切でない場合は、SQLアクセスを許可することもおそらく正しくありません。ただし、BQへのアクセスを許可する方がダウンロードを提供するよりも良い場合がいくつかあります。
非常に多くのテーブルがあるため、インポートの管理は顧客にとって煩わしいものになります。
データは非常に大きい(TBですか?)ため、ユーザーのクエリが読み取るデータはほとんどありません。
データは頻繁にエクスポートされるため、繰り返しになりますが、バッチダウンロードを最新の状態に保つことは困難です。
興味深いクエリの缶詰の例を提供し、クエリエンジンを制御する必要があります。
あなたの顧客はSQLを書くのに十分な技術を持っていますが、独自のインポートシステムとデータベースを実行する面倒を望まないでしょう。
スキーマは頻繁に変更されるため、インポートの自動化が機能しなくなりますが、クエリが機能しなくなるわけではありません。
このパターンの良い例は BigQueryのGitHubからのこの3 + TBデータセット です。このすべての情報はGitHub APIを介して利用できますが、一部のクエリはSQLでははるかに簡単または高速になります。 他のデータセットには、Googleでの政治広告、サンフランシスコでの映画のロケなど 。
これがベイジアンのような答えです...
私たちは業界として集合的に、3層のユーザー向けアプリケーションの設計に約30年の経験があり、それを適切に行う方法に関する豊富な知識を蓄積してきました。他のいくつかの回答が示すように、このパターンから逸脱することは必要に応じて間違いではありませんが、疎領域にあり、根本的な誤りを犯すリスクが高くなります。
時々行われます。特により良いオプションがなく、かなり制御された環境(の試み)の場合。成功率は低いです。
RDBMSはHTTPサーバーの背後でセキュリティに大きな遅れを取っています。これらは、さまざまな目標を念頭に置いて開発および最適化されています。彼らの一般的なユースケースは、通常のHTTPサーバーよりもはるかに使いやすい環境に直面しています。リスニングDBポートを意図せずにインターネットに公開しても、セキュリティ障害と見なされます。
行レベルのアクセス制御は重要ですが、データベースのビジネスロジックに適合することはめったになく、データベースがより正規化され、許可システムが複雑になるほど、適合しなくなります。また、(開発者の観点から)パフォーマンスへの影響が何らかの形で隠されています。
相互運用性:DBアクセスプロトコルとそれに対応するドライバーの深刻な混乱を考慮して、ユーザーを特定の開発スタックまたはプラットフォームに制限したくない場合。誰もがHTTPまたはSOAPクライアントが利用可能、SQLサーバークライアントが選択できます-本当によろしいですか?データベースソフトウェアを変更することを考えてもよいでしょう。OracleからMySQLへの移行または長い-PostgreSQL 9.2から12への期限切れのアップグレード?HTTPインターフェースを使用すると、クライアントに通知することなくそれを行うことができます。
HTTPで動作するセキュリティおよびネットワーク管理ツール(ファイアウォール、プロキシ、ロードバランサーなど)が利用可能で多様です。 TDSプロトコルを理解する侵入検知システムを見つけてください。
tl; dr:サイバークリープは大きな攻撃面を好むため、DBMSをパブリックネットワークに公開しないでください。
情報システムを運営する私たちは、サイバークリープとの戦いにいます。彼らは私たちに対してあらゆる利点を持っています:彼らは賢く、彼らは非常にやる気があり、そして私たちを攻撃するために私たちのシステムで1つの穴を見つけるだけを必要とします。
私たちはシステムを守っています。 すべての穴を塞ぐする必要があります。良い出発点は、穴の数を制限することです。
Webサーバーはホールです。パブリックネットワークに公開されているWebサーバーの攻撃面を制限するために、多くの作業が行われ、現在も進行中です。サイバークリープが新しいWebサーバーのエクスプロイトを見つけた場合、ベンダーは通常、パッチをすばやくプッシュします。そして、それらのパッチは、私たちがすぐに適用することは難しくありません。
公開されているDBMSもホールです。確かに、それらのいくつかは、優れた列、行、ビュー、およびテーブルの粒度のアクセス制御を備えています。したがって、理論的には、セキュリティを維持しながらパブリックネットへのアクセスを許可することが可能かもしれません。
しかし、サイバークリープがDBMSに対して何らかのエクスプロイトを仕掛けるとどうなりますか?
さらに、DBMSをパブリックネットワークに公開すると、セキュリティ監査人は気に入らなくなります。どういたしまして。そして、正当な理由があります。
これを行わないでください。
誰もこれをしているようには見えないので、見落としているセキュリティ上のリスクがあるに違いありません。
人為的エラー誤った認証を付与データベースレベルのクライアントに劇的な結果をもたらす可能性があります。
お客様にパブリックSQLアクセスを提供できないのはなぜですか?何がうまくいかないのでしょうか?
あなたの顧客のシステムに不必要な不便を生じさせています:
-データベースに対して適切なSQLクエリを書き込むために、顧客はデータベーススキーマを理解する必要がありますか、それともその一部だけが必要ですか?
-顧客のコードはデータベースと密に結合され、スキーマの変更は顧客のコードに反映される必要があります。
そのため、1年目以降は、データベースの構造を抽象化するアプリケーションとAPIエンドポイントを作成する傾向があります。
同様のことは、実際には Hasura のようなプログラムでも行われます。このプログラムは、GraphQLインターフェースを介して、行レベルと列レベルの両方の権限にPostgreSQLの権限システムを使用してデータベースを公開します。クライアントはSQLクエリのすべての機能を利用できませんが、GraphQLクエリを介してサブセットを利用できます。これにより、(すべての列ではなく)データのサブセットを取得するクエリ、および結合とある程度のフィルタリングが可能になります。 SQLのすべての機能は完全には公開されていません。つまり、サーバーに対してDOS攻撃を作成するクエリを作成することはできません。サーバーを遅くする可能性のある機能へのアクセスを制限しながら、各クエリは1つのSQLクエリに変換されます。
移行に関する懸念事項に従って、データベースを移行するだけでAPIを更新できます。それが望ましくない場合、Hasuraでは、実際のテーブルをパブリックなテーブルに変換するカスタムSQLビューを使用できるため、APIに影響を与えることなく内部表現を変更できます。さらに、Hasuraを常に同じAPIを公開する他のサーバーと交換することができるため、ロックされません。
ただし、依然としてHTTPのオーバーヘッドがありますが、WebSocketsインターフェイスを使用して毎回再接続することを回避することもできます。
質問する
顧客が私のデータベースに直接接続できるようにできないのはなぜですか?
そして、答えは本当にあなたがこの文脈でcustomersによって誰を意味するかにかかっています。インターネット上のランダムな人?他のほとんどの返信が言ったように、これは悪い考えであり、多くの正当な理由を与えています。ただし、顧客が信頼できるビジネスパートナーである場合は、 B2B、そしてあなたのサイトとおそらくフェデレーテッドSSOソリューションの間にVPN接続があれば、これは自動的に悪い考えではありません。それはサポートの悪夢になりますが、それが信じられないほど十分に文書化されていない限り、各テーブルのデータについての質問に答えるために一日中費やすことになります。
誰もこれをしないようです
びっくりするかもしれません。
私が見た中で最も進んだRDBMSでさえ、箱から出して十分なセキュリティを得ることができません。最も些細なアプリケーションを除くすべてのビジネスルールは複雑すぎます。悪意のあるハッカーに大混乱を与えたくない場合は、特定の方法で実行できることを制限するカスタムコードを作成する必要があります。さて、あなたはmightすべてをストアドプロシージャに入れて、クライアントがそれらを呼び出すことだけを許可します...しかし、その後、開始したところに戻ります-基本的なデータベースの上にカスタムアプリがあります。また、ストアドプロシージャ言語は通常、一般的なプログラミング言語(PHP/C#/ Java/Javascript/Ruby/Python/etc)よりもはるかに扱いにくく、使用が困難です。
Elasticsearch APIがどのように実行されるかを見てみると、おそらくあなたのアイデアに類似していることがわかります。 Elasticsearchのみを使用することで、カスタムバックエンドコードを開発して独自のREST APIを作成する必要がなく、ケースがシンプルな場合。クライアントをElasticsearchに直接接続するREST = APIとそれだけです(Elasticsearchを推奨しているわけではありません。これは、あなたのアイデアに適した実例であることがわかります)
3番目の箇条書きは、直接アクセスを許可しない最も重要な理由であるため、本当に最初にする必要があります。
- (My-)SQLアクセス許可はかなり細かいので、明らかなセキュリティ問題はないはずです。
これが行われない主な理由は、行レベルのセキュリティが長い間それほど重要ではなかったためであり、行レベルのセキュリティなしでは、シナリオにセキュリティがありません。 MySQLは今でも行レベルのセキュリティを備えていません。
また、行レベルのセキュリティは、セキュリティと設計の問題を終わらせるものではなく、必要な最初のステップにすぎません。基本的に、セキュリティの問題を上回るメリットはありません。
これは予想されることです。 50から500のテーブルを持つデータベースは、やや複雑であると説明します。 100%正直だったとしても、直接対話でデータベースを使用したくありません。
ほとんどの組織では、ユーザーがデータベースを介して実行する能力と知識を持っている場合でも、アプリケーションを介して何かを実行できる場合は、データベースへの直接アクセスよりもその方法で実行する方が良いと考えられます。
ユーザーをデータベースから除外し、定義された方法で変更を行うよう要求する機能は、AccessやExcelから移行する理由の1つです。すべてのユーザーが同等に熟練していなくても信頼できると少なくとも想定できる組織から、ランダムなユーザーが悪意のある人物であると本当に想定する必要があるより広いインターネットにそれを拡張します...
どのクライアントがどのデータ行を表示するのか、またはクライアントがクエリテーブルだけでなく更新する必要があるのかについてあまり心配していないようです。
ユースケースに適合する代替案の1つは、データベースのコピーを直接または間接的に顧客に提供することです。洗練度に応じて、SQLiteクローンをファイルとして、アプリケーション内で、または直接送信することを想像してみてください。これにより、少なくともサーバーでは、不正なクエリの場合のパフォーマンスの問題が回避されます。
ギガバイトサイズのYouTube動画を見ているこの現代の時代では、回線全体にかなり大きなデータベースを送信する余裕があります。
これは、適切なデータベースサービスを選択した場合にのみ可能です。現実には、アクセス許可の細分性とアクセスモデルを組み合わせたものがほとんどありません。製品を宣伝しようとすることなく、今日の例として、次のような「エンタープライズ規模」のデータベースシステムで同様のことができます。
そしておそらく他の人。
問題は、これらのシステムの管理がかなり複雑であることです。もし、あんたが
それなら誰があなたを止めるの?
それらを通常止めるのは
軽く踏む。革新。よく計画してください。
長所と短所はありますが、データベースをクライアントに公開する場合は、特定のスキーマへのアクセスのみを許可することにより、データベースを小さな攻撃対象にします。このスキーマには、実行を許可するストアドプロシージャのみが含まれます。これにより、SQLインジェクション攻撃が緩和され、ユーザーが持つ権限はSQL権限に依存します。
異なる顧客が自分のレコードにのみアクセスできるようにして、同じ顧客組織内の異なる人々に対して異なる権限を持たせたい場合は、そのすべてをますます大きなストアドプロシージャ内で実行できます。基本的に、ストアドプロシージャ内に独自のAPIを構築します。これを行う場合は、中間層に独自のAPIレイヤーを配置することで、保守性を向上させることができます。パフォーマンスとメンテナンスの両方に複雑なビジネスロジックがある場合は、ストアドプロシージャよりも中間層のほうが適しています。
つまり、必要に応じて、すべてをSQLデータベースとストアドプロシージャに配置できます。機能面でもセキュリティ面でも、小さな攻撃対象領域で機能させることができます。しかし、複雑なシステムがあり、何が関係しているかを理解している場合は、たいていの場合、それを望んでいません。
顧客がデータベースに直接接続できるようにできないのはなぜですか? SQLポートを公開し、HTTP APIを完全にスキップして、顧客がデータベースにアクセスできるようにしてはどうでしょうか。
できない/できません理由データベースエンジンによって提供されるアクセス制御は、クライアントのアクセスを適切に制御するために必要な粒度に欠けている可能性があります。
ほとんどのデータベースは正規化されており、その結果、同じタイプのすべてのオブジェクトが同じテーブルに格納されます。異なる顧客に属するものでさえ。
ほとんどの(すべての)データベースエンジン許可システムは、レコード単位ではなく、テーブル全体へのアクセスを一度に許可または拒否します。そして、おそらく、1人の顧客が他のすべての顧客のデータを表示することを望まないでしょう。
そのため、顧客に代わってデータベースクエリを実行し、特定のクライアントが受信を許可された結果のみを返すAPIハンドラを作成する価値があるのはこのためです。 APIは、課金、レートスロットリング、ロギング、およびデータベースエンジンでは実行できないその他の便利なビジネス機能も実装できます。
つまり、はい、できます直接DBアクセスを許可し、顧客が必要とするすべてのデータをいくつかのテーブルにダンプし、そのテーブルへのアクセスのみを許可する夜間ストアドプロシージャをセットアップします。しかし顧客ごとにテーブルを作成することは慣例ではありませんであり、正規化に反しています。新しいデータを見る顧客に遅れをもたらし、顧客が表示できるテーブルを再生成するためにIOスパイクが繰り返し発生し、非常に多くのディスク領域を使用します。
顧客に直接データベースSQLアクセスを与えないでください。
セキュリティ
アプリケーションサーバー(Webサーバー、コンテナーなど)は、顧客/信頼できない外部の攻撃者に直接公開され、この目的のためにはるかに強力なセキュリティテストを受けることが期待されています。比較すると、データベースサーバーには脆弱性が頻繁に見られ、直接公開されている場合はかなり悪用される可能性があります。
多くの場合、アプリケーションのロジックと許可は簡単ではありません。データベースシステムはいくつかの制限された機能を提供しますが、通常は、これらをより能力のあるシステム(アプリケーションロジック)に集中させるほうがまとまりがあります。
デカップリング
顧客が物理データモデルに直接結合できるようにすると、契約上/商業上、まったく同じデータモデルを維持する義務が生じるという問題が発生します。これは非常に望ましくありません。データモデルを変更すると顧客を壊すため、データモデルを維持/改善/リファクタリングすることが不可能になるからです。 (経営陣はそうしないように指示します。)
これは、顧客がそれをどのように使用しているかを確認できない場合、特に悪いことです。あなたが彼らに生のDB接続を与え、あなた自身が彼らがしていることを解析/書き直すことさえできないなら。
バックエンド間の移植性も問題です。 DBが提供するセキュリティとストアドプロシージャ/スクリプティングファシリティには、ジョブのための限られた不十分なツールがありますが、さらに悪いのはベンダー固有のものです。パフォーマンス/スケーラビリティ/コストの理由で別のデータベースに移行したい場合、行き詰まってしまいます。
推奨される解決策は、「論理モデル」に契約することです。これは、物理的な実装からある程度切り離されています。これには、一般的に、外部の関係者に、より単純で明確でより有用なモデルを提供するという利点もあります。
より良いAPI構造
いくつかの潜在的な改善:
開発の有効性
ソフトウェアエンジニアリングツール(IDE、デバッガ、フレームワーク、ライブラリ、エラー処理、ロギング、パフォーマンス、プロファイリング)は、おそらくアプリケーション言語(Java、C#など)の2桁優れています。Node JS、Rust、Go)ストアドプロシージャと埋め込みデータベースコードよりも。
ライフタイムメンテナンスコストが初期開発の4〜10倍であることを考えると、たとえば顧客にデータを公開する7日間の「非常に小さな」初期プロジェクトでも、大きなライフタイムコストの差が発生する可能性があります。
開発側では、合理的なアプリケーション言語ツールと最新のフレームワーク(Spring Boot、GraphQLなど)を使用すると、3〜4倍の生産性の違いが期待されます。お客様側では、データの消費がはるかに簡単になり、混乱がはるかに少ないことが期待されます(APIを安定させることができるため)。
SQLを公開するための開発側のコストはないと主張する人たちは、セキュリティルールの実装、データモデルの問題へのパッチの適用、および事後のセキュリティ問題の修正を試みるコストをおそらく省略しています。
データベースワイヤプロトコルを読み取り、SQLクエリを解析し、SQLクエリレベルでセキュリティ上の懸念をブロックするために、カスタムDB接続プロキシを作成するにはどれくらいの費用がかかりますか?生のSQL接続を許可し、DBルールが不十分である場合(ほとんどの場合それがわかっています)、それがセキュリティのフォールバックになります。
推奨
あなた自身とあなたの顧客に有利にしてください。 GraphQLはあなたに適しているかもしれませんが、多くの問題を回避しながらSQLの利点の多くを提供します。
最新のアプリケーション言語とフレームワークを使用します-Java(SpringBoot)またはC#を好みますが、NodeJSなどの他のオプションも利用できます(PHPは避けてください)。
私はお勧めします:
お役に立てれば!
ソフトウェアエンジニアリングではなく、セキュリティの観点では説明しません。
顧客に直接CRUDへのアクセスを許可しないのはなぜですか?
CRUD(作成、読み取り、更新、削除)プリミティブはatomicプリミティブであるためです。彼らはビジネスロジックを実装していません。また、リレーショナル許可モデルはデータの分離を考慮していません
セキュリティが明確に定義されていると仮定すると、CRUDが機能しない理由はいくつかあります
CRUDはアトミックです。ビジネスには原子的すぎる
送金は、クレジットとデビットで構成されます。 2つのクエリ。顧客がすべてのクエリを予想どおりの順序で、トランザクション内で実行することを100%確信していますか?リレーショナルデータベースは、「お金を作成したり破壊したりすることはできないが、転送するだけである」というニュートンの制約を強制しません。
A REST APIは、トランザクションで2つのクエリを実行することを保証します。
権限は制限されています
リレーショナルアクセス許可では、データセマンティクスとビジネスロジックは考慮されません。 UPDATEへのアクセス権がある場合(説明のためにDELETEへのアクセス権がない場合など)、クライアントが書き込みたい値を(簡単に)制限することはできません。
実際に会社で利用できるクーポンがそれほど多くないときに、アカウントのクーポン数を更新するとどうなりますか?
A REST APIはクエリを発行する前に入力のデータを検証します
権限は分離を許可していません
通常、テナントは列の値(TENANT_IDなど)で区別します。 READアクセスは、すべての情報へのアクセスを許可します。
SQL権限では、行ではなく特定のロールで使用できる列を制限できます。
REST APIはすべてのクエリにフィルターを追加します
監査とロギング
CRUDに直接アクセスすると、INSERT INTO AUDIT_LOG
を発行する顧客に依存します。悪意は別として、誰もがそのクエリを発行することを確信していますか?予算の制約があるため、一部のお客様はそのクエリの実装を「忘れて」、テストを忘れてしまいます。
REST APIは、すべての呼び出しで監査ログを発行します。
顧客ユーザーにCRUDアクセスを与えることはあまりにも原始的であり、同じNASフォルダーの無数のユーザーに注文されたExcelシートにアクセスすることによって付与される同じレベルのEVILを許可します。
私を信じて、私はあなたの人間が災害の回復を目撃した...
変更を許可してはならないデータへの書き込みアクセス権や、読み取りを許可してはならないデータへの読み取りアクセス権を彼らに与えない限り、これは許容できるようです。
多くのシステムは、異なる顧客に属するデータを共有テーブルに入れますが、これは明らかに不適切なアプローチです。
または、信頼できるVPN経由で接続を確立することもできます。ただし、データベースサーバーのセキュリティに関しては、データベースサーバー上のクライアントデータベーススキーマに属するユーザーに対して、より安全なアクセス許可と厳密なアクセス権を構成する必要があります。
ただし、これはパブリッククライアントにはお勧めできません。通常は内部トポロジのみです。