3

私はアカウント、プロジェクト、トランザクションのモデルを含む簡単なGAEシステムを持っています。コンテキストを維持するためにGoogle App EngineのエンティティキーをWebページに渡すことは安全ですか?

Djangoを使用して、指定されたアカウントに属するテーブルのプロジェクトのリストを持つWebページを生成しています。各プロジェクトの詳細ページへのリンクを作成したいと思います。私は、プロジェクトのキーを文字列に変換するリンクを生成しており、そのリンクにProjectオブジェクトを参照しやすくしています。これは、このように見えるのリンクを提供します:

<a href="/project?key=agxkZAB-bnVpY2VrbXRyDDsSBkNvdXBvbhgBDA">My Project Name</a> 
  1. は、このようなリンクを作成するために安全ですか?より良い方法がありますか?それは文脈を維持する悪い方法のように感じる。

  2. キーの文字列がリンク先のページに表示され、醜いです。それを表示しないようにする方法はありますか?

ありがとう。

答えて

3

もう少し調査をした後、自分の質問に答えることができると思います。 GAEキーまたはIDを使用するのが本質的に安全でないかどうかを知りたかったのです。

実際には、ユーザーが返されたWebページのURLを変更したり、手動で作成したURLにアクセスしたりする可能性があるため、いくつかの追加コードがないと安全ではありません。これにより、認証されたユーザーは、URLのキーIDを変更するだけで、別のユーザーのデータを編集できるようになります。

したがって、アクセスを許可するすべてのリソースについて、現在認証されているユーザーに、試行している方法でアクセスする権利があることを確認する必要があります。

これは、「ユーザーが所有するオブジェクトにのみアクセスできる」という組み込みの方法がないと思われるため、操作ごとに追加のクエリを記述することが含まれます。

6

GAEのドキュメントでは、同じアプローチを使用する例はほとんどありません。また、KeyはURLに含めるのに安全な文字を使用しています。だからおそらく問題はない。

私のモデルが数字を識別子として使用している場合は、数値ID(obj_key.id())を使用することをお勧めします。

+0

返信いただきありがとうございます。私が懸念しているのは、キーがURLセーフではなく、ユーザーが他のURLに基​​づいて他のURLを推測していることです。数字の数は簡単に増加する整数であり、ハックするのがさらに簡単です。 – MindJuice

+4

安全なURLが必要な場合は、所有者だけが開くことができます。少なくとも認証層を追加する必要がありますが、数値IDを使用する場合はURLを ' –

+0

+1'と推測しにくいものにしないでください。私はキーを使用していて、数値IDはもっと見栄えが良いです。 –

5

「安全な」かどうかは、それが意味するものと、アプリの実装方法によって異なります。ちょっと戻って、Keyオブジェクトに格納されているものを正確に見てみましょう。 、あなたの鍵を取るshell.appspot.comに移動し、次のように入力します。

db.Key(your_key) 

これは、次のようなものを返す:あなたが見ることができるように

datastore_types.Key.from_path(u'TestKind', 1234, _app=u'shell') 

を、キーは、App ID、種類の名前が含まれていIDまたは名前(親エンティティの種類/ IDペア - この場合はnone)を指定します。ここに何も秘匿に特に関心があるべきではないので、ここで情報漏洩の重大なリスクはないはずです。

あなたは、ユーザーが他のURLを推測できることを懸念しています。これは、キーを解読し、IDまたは名前を変更し、キーを再エンコードする可能性があるためです。お使いのセキュリティモデルは、他のURLを推測し、それらにないを依存している場合は、しかし、あなたは物事のカップルのいずれかを実行する必要があります

  1. は、アプリケーションのセキュリティモデルを再検討。あなたがそれを避けることができるなら、あなたは本当のセキュリティの程度のために「秘密のURL」に頼るべきではありません。
  2. キー名を使用して、ユーザーが推測できない長いランダムな文字列を設定します。

最後に、ユーザーが変更できるものは何ですか?キーをdb.getに渡してキーを処理する場合、ユーザーは種別名を変更して、意図したものとは異なるエンティティの種類を取得する可能性があります。そのエンティティの種類にも同様の名前のフィールドがある場合は、意図しないエンティティ(データの表示など)を行う可能性があります。代わりにYourModel.getに鍵を渡すことでこれを避けることができます。鍵を取り出す前に正しい鍵であることを確認します。

これはすべて、キーIDまたは名前を周囲に渡すより良い方法です。キーオブジェクトを使用している場合は、.id()(キー名を使用している場合はID-.name())を呼び出して、元の鍵をdb.Key.from_path('kind_name', id)で再構築するか、YourModel.get_by_idで直接エンティティを取得することができます。

1

単純に増加するわけではありません。私はDatastoreに10個のエントリしかなく、すでに7001に達しています。 ユーザーが単純に推測できないような保護がある限り、それをしない理由はありません。

2

これは古い投稿ですが、私は1つのことを明確にしたいと思います。 KEYで作業する必要があることもあります。

@Parent関係のエンティティを持つ場合は、そのIDで取得できません。データストアを元に戻すには、KEY全体を使用する必要があります。このような場合、エンティティを取得するには、KEYを使用して作業する必要があります。

関連する問題