[解決済み] データベースIDの公開 - セキュリティリスクは?
質問
データベースのIDを(URLなどで)公開するとセキュリティリスクがあると聞いたのですが、その理由がわからず困っています。
なぜリスクなのか、あるいはリスクでないのか、何か意見やリンクがあれば教えてください。
EDIT: もちろんアクセスにはスコープがあり、例えばリソース
foo?id=123
をクリックすると、エラーページが表示されます。そうでなければ、URLそのものが秘密になっているはずです。
EDIT: URLが秘密の場合、おそらく生成されたトークンが含まれ、有効期限が限られています(例:1時間有効、1回のみ使用可能)。
EDIT (months later): 私が現在好んで行っているのは、IDにUUIDSを使用し、それを公開することです。もし私がIDとして連番(通常いくつかのDBではパフォーマンスのため)を使っている場合、代替キーとして各エントリーにUUIDトークンを生成し、それを公開するのが好きです。
どのように解決するのですか?
データベースの識別子を公開することにはリスクが伴います。一方で、それらを全く公開せずにWebアプリケーションを設計するのは、非常に負担が大きいでしょう。したがって、リスクを理解し、それに対処するための配慮が重要です。
最初の危険は、OWASPが呼んだ 安全でない直接オブジェクトの参照。 もし誰かがあるエンティティのIDを発見し、それを防ぐための十分な権限制御がアプリケーションにない場合、彼らはあなたが意図しないことを行うことができます。
以下は良いルールです。
- 操作へのアクセスを制御するためにロールベースのセキュリティを使用する。この方法は、あなたが選んだプラットフォームとフレームワークに依存しますが、多くは宣言的なセキュリティモデルをサポートしており、アクションが何らかの権限を必要とする場合、ブラウザを自動的に認証ステップにリダイレクトします。
- オブジェクトへのアクセスを制御するために、プログラム的なセキュリティを使用します。これはフレームワークレベルで行うのは難しいです。より多くの場合、コードに書かなければならないことであり、したがって、よりエラーになりやすいのです。このチェックは、ユーザーが操作の権限を持っているだけでなく、変更される特定のオブジェクトに対して必要な権利を持っていることを確認することで、ロールベースのチェックを超越します。ロールベースのシステムでは、マネージャーだけが昇給できることを確認するのは簡単ですが、それ以上に、その従業員が特定のマネージャーの部署に属していることを確認する必要があります。
エンドユーザーから本当の識別子を隠す仕組み(例えば、本当の識別子とサーバー上の一時的なユーザー固有の識別子とのマッピング)もありますが、私は、これは曖昧さによるセキュリティの一形態であると主張したいと思います。私は、アプリケーションデータを隠そうとするのではなく、本当の暗号の秘密を守ることに焦点を当てたいと思います。Webの文脈では、広く使われているRESTの設計にも反しています。一般に、識別子はURLでリソースのアドレスを示し、アクセス制御の対象となります。
もう一つの課題は、識別子の予測・発見である。攻撃者が不正なオブジェクトを発見する最も簡単な方法は、番号の並びからそれを推測することです。以下のガイドラインは、それを軽減するのに役立ちます。
-
予測不可能な識別子のみを公開する。パフォーマンスのために、データベース内の外部キー関係でシーケンス番号を使用するかもしれませんが、 ウェブアプリケーションから参照したいエンティティは、予測不可能なサロゲート識別子を持つべきです。これは、クライアントに公開されるべき唯一のものです。ランダムなUUIDを使用することは、暗号的には安全ではありませんが、サロゲートキーを割り当てるための実用的な解決法です。
-
しかし、暗号的に予測不可能な識別子が必要な場所の1つは、セッションIDや他の認証トークンで、ID自体がリクエストを認証する場合です。これらは暗号化されたRNGによって生成されるべきです。
関連
-
ビューの作成 SQL: SQL Server でのビューの作成
-
sql common mistake of incorrect predicate orderConversion failed when converting varchar value 'abc' to data type int
-
mysql データが長すぎて列 xxx の解決策にならない
-
DB2におけるROW_NUMBER() OVER()関数の使用法
-
[解決済み] ATTACHで開いたSQLiteデータベースファイルのテーブルを一覧表示するにはどうすればよいですか?
-
[解決済み] MySQLデータベースの名前を素早く変更する(スキーマ名を変更する)方法は?
-
[解決済み] アプリケーション開発者が陥りやすいデータベース開発の失敗例【終了しました
-
[解決済み] PHPでデータベースのパスワードを保護するには?
-
Oracle インポートエラー: データファイルのフィールドが最大長を超えています。
-
[解決済み】Integrated Security = True と Integrated Security = SSPI の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
親行が削除または更新できない: 外部キー制約に失敗 解決策
-
Hibernateでhibernate.propertiesが見つからない問題とデータベース方言の更新の問題
-
SSISエラーコード DTS_E_OLEDBERROR.an OLE DBエラーが発生しました。エラーコード 0x80040E21 備考
-
db2 エラー sqlcode=-420 自動型変換問題
-
2021年版Redisインタビューの質問(継続更新中)
-
MySql への JDBC 接続エラー com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException.MySQLSyntaxErrorException: 不明なデータベース 'test'
-
node.jsサーバーのmysqlデータベース接続タイムアウト問題(Error: connect ETIMEDOUT)
-
[解決済み] ファイル拡張子.DB - 正確にはどのようなデータベースなのですか?
-
[解決済み] データベース駆動型アプリケーションのユニットテストに最適な戦略とは?
-
[解決済み] サロゲートキーとナチュラルキー/ビジネスキーの比較【終了しました